| Total Complexity | 42 |
| Total Lines | 284 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like Ui often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Ui, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 8 | class Ui { |
||
| 9 | private $updateChecker; |
||
| 10 | private $manualCheckErrorTransient = ''; |
||
| 11 | |||
| 12 | /** |
||
| 13 | * @param UpdateChecker $updateChecker |
||
| 14 | */ |
||
| 15 | public function __construct($updateChecker) { |
||
| 20 | } |
||
| 21 | |||
| 22 | public function onAdminInit() { |
||
| 23 | if ( $this->updateChecker->userCanInstallUpdates() ) { |
||
| 24 | $this->handleManualCheck(); |
||
| 25 | |||
| 26 | add_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10, 3); |
||
| 27 | add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2); |
||
| 28 | add_action('all_admin_notices', array($this, 'displayManualCheckResult')); |
||
| 29 | } |
||
| 30 | } |
||
| 31 | |||
| 32 | /** |
||
| 33 | * Add a "View Details" link to the plugin row in the "Plugins" page. By default, |
||
| 34 | * the new link will appear before the "Visit plugin site" link (if present). |
||
| 35 | * |
||
| 36 | * You can change the link text by using the "puc_view_details_link-$slug" filter. |
||
| 37 | * Returning an empty string from the filter will disable the link. |
||
| 38 | * |
||
| 39 | * You can change the position of the link using the |
||
| 40 | * "puc_view_details_link_position-$slug" filter. |
||
| 41 | * Returning 'before' or 'after' will place the link immediately before/after |
||
| 42 | * the "Visit plugin site" link. |
||
| 43 | * Returning 'append' places the link after any existing links at the time of the hook. |
||
| 44 | * Returning 'replace' replaces the "Visit plugin site" link. |
||
| 45 | * Returning anything else disables the link when there is a "Visit plugin site" link. |
||
| 46 | * |
||
| 47 | * If there is no "Visit plugin site" link 'append' is always used! |
||
| 48 | * |
||
| 49 | * @param array $pluginMeta Array of meta links. |
||
| 50 | * @param string $pluginFile |
||
| 51 | * @param array $pluginData Array of plugin header data. |
||
| 52 | * @return array |
||
| 53 | */ |
||
| 54 | public function addViewDetailsLink($pluginMeta, $pluginFile, $pluginData = array()) { |
||
| 55 | if ( $this->isMyPluginFile($pluginFile) && !isset($pluginData['slug']) ) { |
||
| 56 | $linkText = apply_filters($this->updateChecker->getUniqueName('view_details_link'), __('View details')); |
||
| 57 | if ( !empty($linkText) ) { |
||
| 58 | $viewDetailsLinkPosition = 'append'; |
||
| 59 | |||
| 60 | //Find the "Visit plugin site" link (if present). |
||
| 61 | $visitPluginSiteLinkIndex = count($pluginMeta) - 1; |
||
| 62 | if ( $pluginData['PluginURI'] ) { |
||
| 63 | $escapedPluginUri = esc_url($pluginData['PluginURI']); |
||
| 64 | foreach ($pluginMeta as $linkIndex => $existingLink) { |
||
| 65 | if ( strpos($existingLink, $escapedPluginUri) !== false ) { |
||
| 66 | $visitPluginSiteLinkIndex = $linkIndex; |
||
| 67 | $viewDetailsLinkPosition = apply_filters( |
||
| 68 | $this->updateChecker->getUniqueName('view_details_link_position'), |
||
| 69 | 'before' |
||
| 70 | ); |
||
| 71 | break; |
||
| 72 | } |
||
| 73 | } |
||
| 74 | } |
||
| 75 | |||
| 76 | $viewDetailsLink = sprintf('<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>', |
||
| 77 | esc_url(network_admin_url('plugin-install.php?tab=plugin-information&plugin=' . urlencode($this->updateChecker->slug) . |
||
| 78 | '&TB_iframe=true&width=600&height=550')), |
||
| 79 | esc_attr(sprintf(__('More information about %s'), $pluginData['Name'])), |
||
| 80 | esc_attr($pluginData['Name']), |
||
| 81 | $linkText |
||
| 82 | ); |
||
| 83 | switch ($viewDetailsLinkPosition) { |
||
| 84 | case 'before': |
||
| 85 | array_splice($pluginMeta, $visitPluginSiteLinkIndex, 0, $viewDetailsLink); |
||
| 86 | break; |
||
| 87 | case 'after': |
||
| 88 | array_splice($pluginMeta, $visitPluginSiteLinkIndex + 1, 0, $viewDetailsLink); |
||
| 89 | break; |
||
| 90 | case 'replace': |
||
| 91 | $pluginMeta[$visitPluginSiteLinkIndex] = $viewDetailsLink; |
||
| 92 | break; |
||
| 93 | case 'append': |
||
| 94 | default: |
||
| 95 | $pluginMeta[] = $viewDetailsLink; |
||
| 96 | break; |
||
| 97 | } |
||
| 98 | } |
||
| 99 | } |
||
| 100 | return $pluginMeta; |
||
| 101 | } |
||
| 102 | |||
| 103 | /** |
||
| 104 | * Add a "Check for updates" link to the plugin row in the "Plugins" page. By default, |
||
| 105 | * the new link will appear after the "Visit plugin site" link if present, otherwise |
||
| 106 | * after the "View plugin details" link. |
||
| 107 | * |
||
| 108 | * You can change the link text by using the "puc_manual_check_link-$slug" filter. |
||
| 109 | * Returning an empty string from the filter will disable the link. |
||
| 110 | * |
||
| 111 | * @param array $pluginMeta Array of meta links. |
||
| 112 | * @param string $pluginFile |
||
| 113 | * @return array |
||
| 114 | */ |
||
| 115 | public function addCheckForUpdatesLink($pluginMeta, $pluginFile) { |
||
| 138 | } |
||
| 139 | |||
| 140 | protected function isMyPluginFile($pluginFile) { |
||
| 141 | return ($pluginFile == $this->updateChecker->pluginFile) |
||
| 142 | || (!empty($this->updateChecker->muPluginFile) && ($pluginFile == $this->updateChecker->muPluginFile)); |
||
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * Check for updates when the user clicks the "Check for updates" link. |
||
| 147 | * |
||
| 148 | * @see self::addCheckForUpdatesLink() |
||
| 149 | * |
||
| 150 | * @return void |
||
| 151 | */ |
||
| 152 | public function handleManualCheck() { |
||
| 198 | } |
||
| 199 | } |
||
| 200 | |||
| 201 | /** |
||
| 202 | * Display the results of a manual update check. |
||
| 203 | * |
||
| 204 | * @see self::handleManualCheck() |
||
| 205 | * |
||
| 206 | * You can change the result message by using the "puc_manual_check_message-$slug" filter. |
||
| 207 | */ |
||
| 208 | public function displayManualCheckResult() { |
||
| 209 | //phpcs:disable WordPress.Security.NonceVerification.Recommended -- Just displaying a message. |
||
| 210 | if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->updateChecker->slug) ) { |
||
| 211 | $status = sanitize_key($_GET['puc_update_check_result']); |
||
| 212 | $title = $this->updateChecker->getInstalledPackage()->getPluginTitle(); |
||
| 213 | $noticeClass = 'updated notice-success'; |
||
| 214 | $details = ''; |
||
| 215 | |||
| 216 | if ( $status == 'no_update' ) { |
||
| 217 | $message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title); |
||
| 218 | } else if ( $status == 'update_available' ) { |
||
| 219 | $message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title); |
||
| 220 | } else if ( $status === 'error' ) { |
||
| 221 | $message = sprintf(_x('Could not determine if updates are available for %s.', 'the plugin title', 'plugin-update-checker'), $title); |
||
| 222 | $noticeClass = 'error notice-error'; |
||
| 223 | |||
| 224 | $details = $this->formatManualCheckErrors(get_site_transient($this->manualCheckErrorTransient)); |
||
| 225 | delete_site_transient($this->manualCheckErrorTransient); |
||
| 226 | } else { |
||
| 227 | $message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), $status); |
||
| 228 | $noticeClass = 'error notice-error'; |
||
| 229 | } |
||
| 230 | |||
| 231 | $message = esc_html($message); |
||
| 232 | |||
| 233 | //Plugins can replace the message with their own, including adding HTML. |
||
| 234 | $message = apply_filters( |
||
| 235 | $this->updateChecker->getUniqueName('manual_check_message'), |
||
| 236 | $message, |
||
| 237 | $status |
||
| 238 | ); |
||
| 239 | |||
| 240 | printf( |
||
| 241 | '<div class="notice %s is-dismissible"><p>%s</p>%s</div>', |
||
| 242 | esc_attr($noticeClass), |
||
| 243 | //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Was escaped above, and plugins can add HTML. |
||
| 244 | $message, |
||
| 245 | //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains HTML. Content should already be escaped. |
||
| 246 | $details |
||
| 247 | ); |
||
| 248 | } |
||
| 249 | //phpcs:enable |
||
| 250 | } |
||
| 251 | |||
| 252 | /** |
||
| 253 | * Format the list of errors that were thrown during an update check. |
||
| 254 | * |
||
| 255 | * @param array $errors |
||
| 256 | * @return string |
||
| 257 | */ |
||
| 258 | protected function formatManualCheckErrors($errors) { |
||
| 259 | if ( empty($errors) ) { |
||
| 260 | return ''; |
||
| 261 | } |
||
| 262 | $output = ''; |
||
| 263 | |||
| 264 | $showAsList = count($errors) > 1; |
||
| 265 | if ( $showAsList ) { |
||
| 266 | $output .= '<ol>'; |
||
| 267 | $formatString = '<li>%1$s <code>%2$s</code></li>'; |
||
| 268 | } else { |
||
| 269 | $formatString = '<p>%1$s <code>%2$s</code></p>'; |
||
| 270 | } |
||
| 271 | foreach ($errors as $item) { |
||
| 272 | $wpError = $item['error']; |
||
| 273 | /** @var \WP_Error $wpError */ |
||
| 274 | $output .= sprintf( |
||
| 275 | $formatString, |
||
| 276 | esc_html($wpError->get_error_message()), |
||
| 277 | esc_html($wpError->get_error_code()) |
||
| 278 | ); |
||
| 279 | } |
||
| 280 | if ( $showAsList ) { |
||
| 281 | $output .= '</ol>'; |
||
| 282 | } |
||
| 283 | |||
| 284 | return $output; |
||
| 285 | } |
||
| 286 | |||
| 287 | public function removeHooks() { |
||
| 292 | } |
||
| 293 | } |
||
| 294 | endif; |
||
| 295 |