| 1 |
<?php |
| 2 |
/* |
| 3 |
* License: GPLv3 |
| 4 |
* License URI: https://www.gnu.org/licenses/gpl.txt |
| 5 |
* Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/) |
| 6 |
*/ |
| 7 |
|
| 8 |
if ( ! defined( 'ABSPATH' ) ) { |
| 9 |
|
| 10 |
die( 'These aren\'t the droids you\'re looking for.' ); |
| 11 |
} |
| 12 |
|
| 13 |
if ( ! class_exists( 'WpssoAdminDashboard' ) ) { |
| 14 |
|
| 15 |
class WpssoAdminDashboard { |
| 16 |
|
| 17 |
private $p; // Wpsso class object. |
| 18 |
|
| 19 |
/* |
| 20 |
* Instantiated by WpssoAdmin->__construct(). |
| 21 |
*/ |
| 22 |
public function __construct( &$plugin ) { |
| 23 |
|
| 24 |
$this->p =& $plugin; |
| 25 |
|
| 26 |
if ( $this->p->debug->enabled ) { |
| 27 |
|
| 28 |
$this->p->debug->mark(); |
| 29 |
} |
| 30 |
|
| 31 |
add_action( 'wp_dashboard_setup', array( $this, 'wp_dashboard_setup' ) ); |
| 32 |
} |
| 33 |
|
| 34 |
public function wp_dashboard_setup() { |
| 35 |
|
| 36 |
wp_add_dashboard_widget( $widget_id = 'wpsso-help-support', $widget_name = __( 'WPSSO Help and Support', 'wpsso' ), |
| 37 |
$callback = array( $this, 'show_metabox_help_support' ), $control_callback = null, $callback_args = array( |
| 38 |
'metabox_id' => $widget_id, 'metabox_title' => $widget_name ), $context = 'normal', $priority = 'high' ); |
| 39 |
|
| 40 |
wp_add_dashboard_widget( $widget_id = 'wpsso-version-info', $widget_name = __( 'WPSSO Version Information', 'wpsso' ), |
| 41 |
$callback = array( $this, 'show_metabox_version_info' ), $control_callback = null, $callback_args = array( |
| 42 |
'metabox_id' => $widget_id, 'metabox_title' => $widget_name ), $context = 'normal', $priority = 'high' ); |
| 43 |
|
| 44 |
wp_add_dashboard_widget( $widget_id = 'wpsso-cache-status', $widget_name = __( 'WPSSO Cache Status', 'wpsso' ), |
| 45 |
$callback = array( $this, 'show_metabox_cache_status' ), $control_callback = null, $callback_args = array( |
| 46 |
'metabox_id' => $widget_id, 'metabox_title' => $widget_name ), $context = 'normal', $priority = 'high' ); |
| 47 |
|
| 48 |
} |
| 49 |
|
| 50 |
/* |
| 51 |
* WPSSO Cache Status. |
| 52 |
*/ |
| 53 |
public function show_metabox_cache_status( $obj, $mb ) { |
| 54 |
|
| 55 |
if ( WpssoUtilMetabox::show_is_hidden_content( $mb ) ) return; |
| 56 |
|
| 57 |
$decimals = 1; |
| 58 |
$table_cols = 4; |
| 59 |
$all_keys_prefix = 'wpsso_'; |
| 60 |
$db_transient_keys = $this->p->util->cache->get_db_transients_keys( $all_keys_prefix, $only_expired = false ); |
| 61 |
|
| 62 |
echo '<table class="wpsso-dashboard-widget">'; |
| 63 |
|
| 64 |
echo '<tr><td colspan="' . $table_cols . '"><h4>'; |
| 65 |
echo __( 'Database Transients', 'wpsso' ); |
| 66 |
echo '</h4></td></tr>'; |
| 67 |
|
| 68 |
echo '<tr>'; |
| 69 |
echo '<th class="cache-label"></th>'; |
| 70 |
echo '<th class="cache-count">' . __( 'Count', 'wpsso' ) . '</th>'; |
| 71 |
echo '<th class="cache-size">' . __( 'MB', 'wpsso' ) . '</th>'; |
| 72 |
echo '<th class="cache-expiration">' . __( 'Expiration', 'wpsso' ) . '</th>'; |
| 73 |
echo '</tr>'; |
| 74 |
|
| 75 |
/* |
| 76 |
* Sort the transient array and make sure the "All Transients" count is last. |
| 77 |
*/ |
| 78 |
$transients_info = $this->p->cf[ 'wp' ][ 'cache' ][ 'transient' ]; |
| 79 |
|
| 80 |
uasort( $transients_info, array( __CLASS__, 'sort_by_label_key' ) ); |
| 81 |
|
| 82 |
if ( isset( $transients_info[ $all_keys_prefix ] ) ) { // Just in case. |
| 83 |
|
| 84 |
SucomUtil::move_to_end( $transients_info, $all_keys_prefix ); |
| 85 |
} |
| 86 |
|
| 87 |
foreach ( $transients_info as $cache_key => $cache_info ) { |
| 88 |
|
| 89 |
if ( empty( $cache_info ) ) { |
| 90 |
|
| 91 |
continue; |
| 92 |
|
| 93 |
} elseif ( empty( $cache_info[ 'label' ] ) ) { // Skip cache info without labels. |
| 94 |
|
| 95 |
continue; |
| 96 |
} |
| 97 |
|
| 98 |
$cache_text_dom = empty( $cache_info[ 'text_domain' ] ) ? $this->p->id : $cache_info[ 'text_domain' ]; |
| 99 |
$cache_label_transl = _x( $cache_info[ 'label' ], 'option label', $cache_text_dom ); |
| 100 |
$cache_count = count( preg_grep( '/^' . $cache_key . '/', $db_transient_keys ) ); |
| 101 |
$cache_size = $this->p->util->cache->get_db_transients_size_mb( $cache_key ); |
| 102 |
$cache_exp_secs = $this->p->util->get_cache_exp_secs( $cache_key, $cache_type = 'transient' ); |
| 103 |
$human_cache_exp = $cache_exp_secs > 0 ? human_time_diff( 0, $cache_exp_secs ) : __( 'disabled', 'wpsso' ); |
| 104 |
|
| 105 |
echo '<tr>'; |
| 106 |
echo '<td class="cache-label">' . $cache_label_transl . '</td>'; |
| 107 |
echo '<td class="cache-count">' . number_format_i18n( $cache_count ) . '</td>'; |
| 108 |
echo '<td class="cache-size">' . number_format_i18n( $cache_size, $decimals ) . '</td>'; |
| 109 |
|
| 110 |
if ( $cache_key !== $all_keys_prefix ) echo '<td class="cache-expiration">' . $human_cache_exp . '</td>'; |
| 111 |
|
| 112 |
echo '</tr>' . "\n"; |
| 113 |
} |
| 114 |
|
| 115 |
if ( wp_using_ext_object_cache() ) { |
| 116 |
|
| 117 |
echo '<tr><td colspan="' . $table_cols . '">'; |
| 118 |
echo '<p class="status-msg">'; |
| 119 |
echo sprintf( __( '<a href="%1$s">Using an external object cache</a> for WordPress transients is <code>%2$s</code>.', 'wpsso' ), |
| 120 |
__( 'https://developer.wordpress.org/reference/functions/wp_using_ext_object_cache/', 'wpsso' ), |
| 121 |
wp_using_ext_object_cache() ? 'true' : 'false' ) . ' '; |
| 122 |
echo '</p><p class="status-msg">'; |
| 123 |
echo __( 'All database transient counts should be 0.', 'wpsso' ) . ' '; |
| 124 |
echo '</p>' . "\n"; |
| 125 |
echo '</td></tr>'; |
| 126 |
} |
| 127 |
|
| 128 |
if ( $cache_files = $this->p->cache->get_cache_files_size_mb() ) { |
| 129 |
|
| 130 |
echo '<tr><td colspan="' . $table_cols . '"><h4>'; |
| 131 |
echo __( 'Cache Folder', 'wpsso' ); |
| 132 |
echo '</h4></td></tr>'; |
| 133 |
|
| 134 |
echo '<tr>'; |
| 135 |
echo '<th class="cache-label"></th>'; |
| 136 |
echo '<th class="cache-count">' . __( 'Count', 'wpsso' ) . '</th>'; |
| 137 |
echo '<th class="cache-size">' . __( 'MB', 'wpsso' ) . '</th>'; |
| 138 |
echo '</tr>'; |
| 139 |
|
| 140 |
$all_count = 0; |
| 141 |
$all_size = 0; |
| 142 |
|
| 143 |
foreach ( $cache_files as $ext => $info ) { |
| 144 |
|
| 145 |
$all_count += $info[ 'count' ]; |
| 146 |
$all_size += $info[ 'size' ]; |
| 147 |
|
| 148 |
echo '<tr>'; |
| 149 |
echo '<td class="cache-label">' . sprintf( __( 'Cached %s Files', 'wpsso' ), $ext ) . '</td>'; |
| 150 |
echo '<td class="cache-count">' . number_format_i18n( $info[ 'count' ] ) . '</td>'; |
| 151 |
echo '<td class="cache-size">' . number_format_i18n( $info[ 'size' ], $decimals ) . '</td>'; |
| 152 |
echo '</tr>'; |
| 153 |
} |
| 154 |
|
| 155 |
echo '<tr>'; |
| 156 |
echo '<td class="cache-label">' . __( 'All Cached Files', 'wpsso' ) . '</td>'; |
| 157 |
echo '<td class="cache-count">' . number_format_i18n( $all_count ) . '</td>'; |
| 158 |
echo '<td class="cache-size">' . number_format_i18n( $all_size, $decimals ) . '</td>'; |
| 159 |
echo '</tr>'; |
| 160 |
} |
| 161 |
|
| 162 |
echo '</table>'; |
| 163 |
} |
| 164 |
|
| 165 |
/* |
| 166 |
* WPSSO Help and Support. |
| 167 |
*/ |
| 168 |
public function show_metabox_help_support( $obj, $mb ) { |
| 169 |
|
| 170 |
if ( WpssoUtilMetabox::show_is_hidden_content( $mb ) ) return; |
| 171 |
|
| 172 |
$pkg_info = $this->p->util->get_pkg_info(); // Uses a local cache. |
| 173 |
|
| 174 |
echo '<table class="wpsso-dashboard-widget">'; |
| 175 |
echo '<tr><td>'; |
| 176 |
|
| 177 |
foreach ( $this->p->cf[ 'plugin' ] as $ext => $info ) { |
| 178 |
|
| 179 |
if ( empty( $info[ 'version' ] ) ) { // Exclude add-ons that are not active. |
| 180 |
|
| 181 |
continue; |
| 182 |
} |
| 183 |
|
| 184 |
$action_links = array(); |
| 185 |
|
| 186 |
if ( ! empty( $info[ 'url' ][ 'faqs' ] ) ) { |
| 187 |
|
| 188 |
$action_links[] = sprintf( __( '<a href="%s">Frequently Asked Questions</a>', 'wpsso' ), $info[ 'url' ][ 'faqs' ] ); |
| 189 |
} |
| 190 |
|
| 191 |
if ( ! empty( $info[ 'url' ][ 'notes' ] ) ) { |
| 192 |
|
| 193 |
$action_links[] = sprintf( __( '<a href="%s">Notes and Documentation</a>', 'wpsso' ), $info[ 'url' ][ 'notes' ] ); |
| 194 |
} |
| 195 |
|
| 196 |
if ( ! empty( $info[ 'url' ][ 'support' ] ) && $pkg_info[ $ext ][ 'pp' ] ) { |
| 197 |
|
| 198 |
$action_links[] = sprintf( __( '<a href="%s">Priority Support Ticket</a>', 'wpsso' ), $info[ 'url' ][ 'support' ] ) . |
| 199 |
' (' . __( 'Premium edition', 'wpsso' ) . ')'; |
| 200 |
|
| 201 |
} elseif ( ! empty( $info[ 'url' ][ 'forum' ] ) ) { |
| 202 |
|
| 203 |
$action_links[] = sprintf( __( '<a href="%s">Community Support Forum</a>', 'wpsso' ), $info[ 'url' ][ 'forum' ] ); |
| 204 |
} |
| 205 |
|
| 206 |
if ( ! empty( $action_links ) ) { |
| 207 |
|
| 208 |
echo '<h4>' . $info[ 'name' ] . '</h4>' . "\n"; |
| 209 |
|
| 210 |
echo SucomUtil::array_to_list_html( $action_links ); |
| 211 |
} |
| 212 |
} |
| 213 |
|
| 214 |
echo '</td></tr>'; |
| 215 |
echo '</table>'; |
| 216 |
} |
| 217 |
|
| 218 |
/* |
| 219 |
* WPSSO Version Information. |
| 220 |
*/ |
| 221 |
public function show_metabox_version_info( $obj, $mb ) { |
| 222 |
|
| 223 |
if ( WpssoUtilMetabox::show_is_hidden_content( $mb ) ) return; |
| 224 |
|
| 225 |
$table_cols = 2; |
| 226 |
$label_width = '30%'; |
| 227 |
|
| 228 |
echo '<table class="wpsso-dashboard-widget">'; |
| 229 |
|
| 230 |
/* |
| 231 |
* Required for chrome to display a fixed table layout. |
| 232 |
*/ |
| 233 |
echo '<colgroup>'; |
| 234 |
echo '<col style="width:' . $label_width . ';"/>'; |
| 235 |
echo '<col/>'; |
| 236 |
echo '</colgroup>'; |
| 237 |
|
| 238 |
foreach ( $this->p->cf[ 'plugin' ] as $ext => $info ) { |
| 239 |
|
| 240 |
if ( empty( $info[ 'version' ] ) ) { // Filter out add-ons that are not installed. |
| 241 |
|
| 242 |
continue; |
| 243 |
} |
| 244 |
|
| 245 |
$plugin_version = isset( $info[ 'version' ] ) ? $info[ 'version' ] : ''; // Static value from config. |
| 246 |
$stable_version = __( 'Not Available', 'wpsso' ); // Default value. |
| 247 |
$latest_version = __( 'Not Available', 'wpsso' ); // Default value. |
| 248 |
$latest_notice = ''; |
| 249 |
$changelog_url = isset( $info[ 'url' ][ 'changelog' ] ) ? $info[ 'url' ][ 'changelog' ] : ''; |
| 250 |
$readme_info = $this->p->admin->get_readme_info( $ext, $read_cache = true ); |
| 251 |
$td_addl_class = ''; |
| 252 |
|
| 253 |
if ( ! empty( $readme_info[ 'stable_tag' ] ) ) { |
| 254 |
|
| 255 |
$stable_version = $readme_info[ 'stable_tag' ]; |
| 256 |
$is_newer_avail = version_compare( $plugin_version, $stable_version, '<' ); |
| 257 |
|
| 258 |
if ( is_array( $readme_info[ 'upgrade_notice' ] ) ) { |
| 259 |
|
| 260 |
/* |
| 261 |
* Hooked by the update manager to apply the version filter. |
| 262 |
* |
| 263 |
* See WpssoUmFilters->filter_readme_upgrade_notices(). |
| 264 |
*/ |
| 265 |
$upgrade_notice = apply_filters( 'wpsso_readme_upgrade_notices', $readme_info[ 'upgrade_notice' ], $ext ); |
| 266 |
|
| 267 |
if ( ! empty( $upgrade_notice ) ) { |
| 268 |
|
| 269 |
reset( $upgrade_notice ); |
| 270 |
|
| 271 |
$latest_version = key( $upgrade_notice ); |
| 272 |
|
| 273 |
$latest_notice = $upgrade_notice[ $latest_version ]; |
| 274 |
} |
| 275 |
} |
| 276 |
|
| 277 |
/* |
| 278 |
* Hooked by the update manager to check installed version against the latest version, in |
| 279 |
* case a non-stable filter is selected for that plugin / add-on. |
| 280 |
* |
| 281 |
* See WpssoUmFilters->filter_newer_version_available(). |
| 282 |
*/ |
| 283 |
if ( apply_filters( 'wpsso_newer_version_available', $is_newer_avail, $ext, $plugin_version, $stable_version, $latest_version ) ) { |
| 284 |
|
| 285 |
$td_addl_class = ' newer-version-available'; |
| 286 |
|
| 287 |
} elseif ( preg_match( '/[a-z]/', $plugin_version ) ) { // Current but not stable (alpha chars in version). |
| 288 |
|
| 289 |
$td_addl_class = ' current-version-not-stable'; |
| 290 |
|
| 291 |
} else $td_addl_class = ' current-version'; |
| 292 |
} |
| 293 |
|
| 294 |
echo '<tr><td colspan="' . $table_cols . '"><h4>' . $info[ 'name' ] . '</h4></td></tr>'; |
| 295 |
|
| 296 |
/* |
| 297 |
* Show the stable version if the latest version is different (ie. latest is a non-stable version). |
| 298 |
*/ |
| 299 |
if ( $latest_version !== $stable_version ) { |
| 300 |
|
| 301 |
echo '<tr><th class="version-label">' . _x( 'Stable Version', 'version label', 'wpsso' ) . '</th>'; |
| 302 |
echo '<td class="version-number">' . $stable_version . '</td></tr>'; |
| 303 |
} |
| 304 |
|
| 305 |
echo '<tr><th class="version-label">' . _x( 'Installed Version', 'version label', 'wpsso' ) . '</th>'; |
| 306 |
echo '<td class="version-number' . $td_addl_class . '">' . $plugin_version . '</td></tr>'; |
| 307 |
|
| 308 |
echo '<tr><th class="version-label">' . _x( 'Latest Version', 'version label', 'wpsso' ) . '</th>'; |
| 309 |
echo '<td class="version-number">' . $latest_version . '</td></tr>'; |
| 310 |
|
| 311 |
/* |
| 312 |
* Show the latest version notice message if there's a newer / non-matching version. |
| 313 |
*/ |
| 314 |
if ( $plugin_version !== $stable_version || $plugin_version !== $latest_version ) { |
| 315 |
|
| 316 |
echo '<tr><th class="version-label">' . _x( 'Update Notice', 'version label', 'wpsso' ) . '</th>'; |
| 317 |
echo '<td class="latest-notice">'; |
| 318 |
|
| 319 |
if ( ! empty( $latest_notice ) ) { |
| 320 |
|
| 321 |
echo $latest_notice . ' '; |
| 322 |
} |
| 323 |
|
| 324 |
echo '<a href="' . $changelog_url . '">' . sprintf( __( 'View %s changelog...', 'wpsso'), $info[ 'short' ] ) . '</a>'; |
| 325 |
echo '</td></tr>'; |
| 326 |
} |
| 327 |
} |
| 328 |
|
| 329 |
echo '</table>'; |
| 330 |
} |
| 331 |
|
| 332 |
/* |
| 333 |
* See WpssoSubmenuDashboard->show_metabox_cache_status(). |
| 334 |
*/ |
| 335 |
private static function sort_by_label_key( $a, $b ) { |
| 336 |
|
| 337 |
if ( isset( $a[ 'label' ] ) && isset( $b[ 'label' ] ) ) { |
| 338 |
|
| 339 |
return strcmp( $a[ 'label' ], $b[ 'label' ] ); |
| 340 |
} |
| 341 |
|
| 342 |
return 0; // No change. |
| 343 |
} |
| 344 |
} |
| 345 |
} |
| 346 |
|