checked) || !is_array($transient->checked)) { return $transient; } $managed_plugins = Ansico_Plugins::get_managed_plugins(); if (empty($managed_plugins)) { return $transient; } if (!isset($transient->response) || !is_array($transient->response)) { $transient->response = array(); } if (!isset($transient->no_update) || !is_array($transient->no_update)) { $transient->no_update = array(); } $client = new Ansico_Plugins_Client(); foreach ($managed_plugins as $plugin_file => $meta) { if (empty($transient->checked[$plugin_file])) { continue; } $owner = !empty($meta['owner']) ? $meta['owner'] : ''; $repo = !empty($meta['repo']) ? $meta['repo'] : ''; if ('' === $owner || '' === $repo) { continue; } $release = $client->get_latest_release($owner, $repo); if (is_wp_error($release)) { continue; } $zip_asset = $client->find_zip_asset($release); if (!$zip_asset || empty($zip_asset['browser_download_url'])) { continue; } $remote_version = $this->normalize_version($release); $current_version = (string) $transient->checked[$plugin_file]; $plugin_data = $this->get_plugin_header($plugin_file); $slug = !empty($meta['slug']) ? $meta['slug'] : dirname($plugin_file); $item = (object) array( 'id' => $plugin_file, 'slug' => $slug, 'plugin' => $plugin_file, 'new_version' => $remote_version, 'url' => !empty($meta['repo_html_url']) ? $meta['repo_html_url'] : '', 'package' => $zip_asset['browser_download_url'], 'icons' => array(), 'banners' => array(), 'banners_rtl' => array(), 'tested' => !empty($plugin_data['RequiresWP']) ? $plugin_data['RequiresWP'] : '', 'requires_php' => !empty($plugin_data['RequiresPHP']) ? $plugin_data['RequiresPHP'] : '', 'compatibility' => new stdClass(), ); if (version_compare($remote_version, $current_version, '>')) { $transient->response[$plugin_file] = $item; unset($transient->no_update[$plugin_file]); } else { $transient->no_update[$plugin_file] = $item; unset($transient->response[$plugin_file]); } } $transient = $this->inject_self_update_data($transient, $client); return $transient; } public function plugins_api($result, $action, $args) { if ('plugin_information' !== $action || empty($args->slug)) { return $result; } $client = new Ansico_Plugins_Client(); if ($this->is_self_plugin_slug($args->slug)) { $self_info = $this->get_self_update_info($client); if (!$self_info) { return $result; } $sections = array( 'description' => !empty($self_info['repo_meta']['plugin_headers']['Description']) ? wp_kses_post(wpautop($self_info['repo_meta']['plugin_headers']['Description'])) : wp_kses_post(wpautop(__('Ansico Plugins forbinder WordPress med private Forgejo-hostede plugins.', 'ansico-plugins'))), 'installation' => wp_kses_post(wpautop(__('Installeres manuelt første gang. Derefter kan pluginet opdatere sig selv via Forgejo releases.', 'ansico-plugins'))), 'changelog' => !empty($self_info['release']['body']) ? wp_kses_post(wpautop($self_info['release']['body'])) : wp_kses_post(wpautop(__('Ingen changelog tilgængelig.', 'ansico-plugins'))), ); return (object) array( 'name' => !empty($self_info['repo_meta']['readme_title']) ? $self_info['repo_meta']['readme_title'] : 'Ansico Plugins', 'slug' => dirname(plugin_basename(ANSICO_PLUGINS_FILE)), 'version' => $this->normalize_version($self_info['release']), 'author' => !empty($self_info['repo_meta']['author_name']) ? '' . esc_html($self_info['repo_meta']['author_name']) . '' : 'Andreas Andersen (Ansico)', 'author_profile' => !empty($self_info['repo_meta']['author_url']) ? $self_info['repo_meta']['author_url'] : 'https://ansico.dk', 'homepage' => !empty($self_info['repo']['html_url']) ? $self_info['repo']['html_url'] : '', 'requires' => !empty($self_info['plugin_data']['RequiresWP']) ? $self_info['plugin_data']['RequiresWP'] : '', 'requires_php' => !empty($self_info['plugin_data']['RequiresPHP']) ? $self_info['plugin_data']['RequiresPHP'] : '', 'tested' => get_bloginfo('version'), 'last_updated' => !empty($self_info['release']['published_at']) ? gmdate('Y-m-d', strtotime($self_info['release']['published_at'])) : '', 'download_link' => (!empty($self_info['zip_asset']['browser_download_url'])) ? $self_info['zip_asset']['browser_download_url'] : '', 'sections' => $sections, 'banners' => array(), 'icons' => !empty($self_info['repo_meta']['screenshot_url']) ? array('default' => $self_info['repo_meta']['screenshot_url']) : array(), 'external' => true, ); } $managed_plugins = Ansico_Plugins::get_managed_plugins(); if (empty($managed_plugins)) { return $result; } $matched = null; foreach ($managed_plugins as $plugin_file => $meta) { if (!empty($meta['slug']) && $meta['slug'] === $args->slug) { $matched = array('plugin_file' => $plugin_file, 'meta' => $meta); break; } } if (!$matched) { return $result; } $release = $client->get_latest_release($matched['meta']['owner'], $matched['meta']['repo']); if (is_wp_error($release)) { return $result; } $zip_asset = $client->find_zip_asset($release); $plugin_data = $this->get_plugin_header($matched['plugin_file']); $repo_meta = $client->get_repository_plugin_metadata($matched['meta']['owner'], $matched['meta']['repo']); $repo_meta = is_wp_error($repo_meta) ? array() : $repo_meta; $sections = array( 'description' => !empty($matched['meta']['description']) ? wp_kses_post(wpautop($matched['meta']['description'])) : wp_kses_post(wpautop(__('Privat plugin distribueret via Forgejo.', 'ansico-plugins'))), 'installation' => wp_kses_post(wpautop(__('Installeres og opdateres via Ansico Plugins og Forgejo releases.', 'ansico-plugins'))), 'changelog' => !empty($release['body']) ? wp_kses_post(wpautop($release['body'])) : wp_kses_post(wpautop(__('Ingen changelog tilgængelig.', 'ansico-plugins'))), ); return (object) array( 'name' => !empty($plugin_data['Name']) ? $plugin_data['Name'] : $matched['meta']['repo'], 'slug' => $matched['meta']['slug'], 'version' => $this->normalize_version($release), 'author' => !empty($repo_meta['author_name']) ? '' . esc_html($repo_meta['author_name']) . '' : 'Andreas Andersen (Ansico)', 'author_profile' => !empty($repo_meta['author_url']) ? $repo_meta['author_url'] : 'https://ansico.dk', 'homepage' => !empty($matched['meta']['repo_html_url']) ? $matched['meta']['repo_html_url'] : '', 'requires' => !empty($plugin_data['RequiresWP']) ? $plugin_data['RequiresWP'] : '', 'requires_php' => !empty($plugin_data['RequiresPHP']) ? $plugin_data['RequiresPHP'] : '', 'tested' => get_bloginfo('version'), 'last_updated' => !empty($release['published_at']) ? gmdate('Y-m-d', strtotime($release['published_at'])) : '', 'download_link' => $zip_asset ? $zip_asset['browser_download_url'] : '', 'sections' => $sections, 'banners' => array(), 'icons' => !empty($repo_meta['screenshot_url']) ? array('default' => $repo_meta['screenshot_url']) : array(), 'external' => true, ); } private function inject_self_update_data($transient, $client) { $settings = Ansico_Plugins::get_settings(); if (empty($settings['self_update_enabled']) || empty($settings['self_update_owner']) || empty($settings['self_update_repo'])) { return $transient; } $plugin_file = plugin_basename(ANSICO_PLUGINS_FILE); if (empty($transient->checked[$plugin_file])) { return $transient; } $release = $client->get_latest_release($settings['self_update_owner'], $settings['self_update_repo']); if (is_wp_error($release)) { return $transient; } $zip_asset = $client->find_zip_asset($release); if (!$zip_asset || empty($zip_asset['browser_download_url'])) { return $transient; } $remote_version = $this->normalize_version($release); $current_version = (string) $transient->checked[$plugin_file]; $repo = $client->get_repository($settings['self_update_owner'], $settings['self_update_repo']); $repo_url = (!is_wp_error($repo) && !empty($repo['html_url'])) ? (string) $repo['html_url'] : ''; $item = (object) array( 'id' => $plugin_file, 'slug' => dirname($plugin_file), 'plugin' => $plugin_file, 'new_version' => $remote_version, 'url' => $repo_url, 'package' => $zip_asset['browser_download_url'], 'icons' => array(), 'banners' => array(), 'banners_rtl' => array(), 'tested' => '', 'requires_php' => '', 'compatibility' => new stdClass(), ); if (version_compare($remote_version, $current_version, '>')) { $transient->response[$plugin_file] = $item; unset($transient->no_update[$plugin_file]); } else { $transient->no_update[$plugin_file] = $item; unset($transient->response[$plugin_file]); } return $transient; } private function is_self_plugin_slug($slug) { return in_array((string) $slug, array('ansico-plugins', dirname(plugin_basename(ANSICO_PLUGINS_FILE))), true); } private function get_self_update_info($client) { $settings = Ansico_Plugins::get_settings(); if (empty($settings['self_update_enabled']) || empty($settings['self_update_owner']) || empty($settings['self_update_repo'])) { return null; } $release = $client->get_latest_release($settings['self_update_owner'], $settings['self_update_repo']); if (is_wp_error($release)) { return null; } $repo = $client->get_repository($settings['self_update_owner'], $settings['self_update_repo']); $repo_meta = $client->get_repository_plugin_metadata($settings['self_update_owner'], $settings['self_update_repo']); $zip_asset = $client->find_zip_asset($release); $plugin_data = $this->get_plugin_header(plugin_basename(ANSICO_PLUGINS_FILE)); return array( 'settings' => $settings, 'release' => $release, 'repo' => is_wp_error($repo) ? array() : $repo, 'repo_meta' => is_wp_error($repo_meta) ? array() : $repo_meta, 'zip_asset' => $zip_asset, 'plugin_data' => $plugin_data, ); } public function inject_auth_header($args, $url) { $settings = Ansico_Plugins::get_settings(); $base = trailingslashit($settings['forgejo_base_url']); if (empty($settings['access_token']) || empty($base) || strpos($url, $base) !== 0) { return $args; } if (empty($args['headers']) || !is_array($args['headers'])) { $args['headers'] = array(); } $args['headers']['Authorization'] = 'token ' . trim((string) $settings['access_token']); $args['sslverify'] = !empty($settings['verify_ssl']); return $args; } private function normalize_version($release) { $version = ''; if (!empty($release['tag_name'])) { $version = (string) $release['tag_name']; } elseif (!empty($release['name'])) { $version = (string) $release['name']; } $version = ltrim($version, 'vV'); return '' !== $version ? $version : '0.0.0'; } private function get_plugin_header($plugin_file) { if (!function_exists('get_plugin_data')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $path = WP_PLUGIN_DIR . '/' . ltrim($plugin_file, '/'); if (!file_exists($path)) { return array(); } return get_plugin_data($path, false, false); } }