link text by using the "puc_manual_check_link-$slug" filter. * Returning an empty string from the filter will disable the link. * * @param array $pluginMeta Array of meta links. * @param string $pluginFile * @return array */ public function addCheckForUpdatesLink($pluginMeta, $pluginFile) { if ( $this->isMyPluginFile($pluginFile) ) { $linkUrl = wp_nonce_url( add_query_arg( array( 'puc_check_for_updates' => 1, 'puc_slug' => $this->updateChecker->slug, ), self_admin_url('plugins.php') ), 'puc_check_for_updates' ); $linkText = apply_filters( $this->updateChecker->getUniqueName('manual_check_link'), __('Check for updates', 'plugin-update-checker') ); if ( !empty($linkText) ) { /** @noinspection HtmlUnknownTarget */ $pluginMeta[] = sprintf('%s', esc_attr($linkUrl), $linkText); } } return $pluginMeta; } protected function isMyPluginFile($pluginFile) { return ($pluginFile == $this->updateChecker->pluginFile) || (!empty($this->updateChecker->muPluginFile) && ($pluginFile == $this->updateChecker->muPluginFile)); } /** * Check for updates when the user clicks the "Check for updates" link. * * @see self::addCheckForUpdatesLink() * * @return void */ public function handleManualCheck() { $shouldCheck = isset($_GET['puc_check_for_updates'], $_GET['puc_slug']) && $_GET['puc_slug'] == $this->updateChecker->slug && check_admin_referer('puc_check_for_updates'); if ( $shouldCheck ) { $update = $this->updateChecker->checkForUpdates(); $status = ($update === null) ? 'no_update' : 'update_available'; $lastRequestApiErrors = $this->updateChecker->getLastRequestApiErrors(); if ( ($update === null) && !empty($lastRequestApiErrors) ) { //Some errors are not critical. For example, if PUC tries to retrieve the readme.txt //file from GitHub and gets a 404, that's an API error, but it doesn't prevent updates //from working. Maybe the plugin simply doesn't have a readme. //Let's only show important errors. $foundCriticalErrors = false; $questionableErrorCodes = array( 'puc-github-http-error', 'puc-gitlab-http-error', 'puc-bitbucket-http-error', ); foreach ($lastRequestApiErrors as $item) { $wpError = $item['error']; /** @var WP_Error $wpError */ if ( !in_array($wpError->get_error_code(), $questionableErrorCodes) ) { $foundCriticalErrors = true; break; } } if ( $foundCriticalErrors ) { $status = 'error'; set_site_transient($this->manualCheckErrorTransient, $lastRequestApiErrors, 60); } } wp_redirect(add_query_arg( array( 'puc_update_check_result' => $status, 'puc_slug' => $this->updateChecker->slug, ), self_admin_url('plugins.php') )); exit; } } /** * Display the results of a manual update check. * * @see self::handleManualCheck() * * You can change the result message by using the "puc_manual_check_message-$slug" filter. */ public function displayManualCheckResult() { if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->updateChecker->slug) ) { $status = strval($_GET['puc_update_check_result']); $title = $this->updateChecker->getInstalledPackage()->getPluginTitle(); $noticeClass = 'updated notice-success'; $details = ''; if ( $status == 'no_update' ) { $message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title); } else if ( $status == 'update_available' ) { $message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title); } else if ( $status === 'error' ) { $message = sprintf(_x('Could not determine if updates are available for %s.', 'the plugin title', 'plugin-update-checker'), $title); $noticeClass = 'error notice-error'; $details = $this->formatManualCheckErrors(get_site_transient($this->manualCheckErrorTransient)); delete_site_transient($this->manualCheckErrorTransient); } else { $message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status)); $noticeClass = 'error notice-error'; } printf( '

%s

%s
', $noticeClass, apply_filters($this->updateChecker->getUniqueName('manual_check_message'), $message, $status), $details ); } } /** * Format the list of errors that were thrown during an update check. * * @param array $errors * @return string */ protected function formatManualCheckErrors($errors) { if ( empty($errors) ) { return ''; } $output = ''; $showAsList = count($errors) > 1; if ( $showAsList ) { $output .= '
    '; $formatString = '
  1. %1$s %2$s
  2. '; } else { $formatString = '

    %1$s %2$s

    '; } foreach ($errors as $item) { $wpError = $item['error']; /** @var WP_Error $wpError */ $output .= sprintf( $formatString, $wpError->get_error_message(), $wpError->get_error_code() ); } if ( $showAsList ) { $output .= '
'; } return $output; } public function removeHooks() { remove_action('admin_init', array($this, 'onAdminInit')); remove_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10); remove_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10); remove_action('all_admin_notices', array($this, 'displayManualCheckResult')); } } endif;