[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Administration Update API 4 * 5 * @package WordPress 6 * @subpackage Administration 7 */ 8 9 /** 10 * Selects the first update version from the update_core option. 11 * 12 * @since 2.7.0 13 * 14 * @return object|array|false The response from the API on success, false on failure. 15 */ 16 function get_preferred_from_update_core() { 17 $updates = get_core_updates(); 18 if ( ! is_array( $updates ) ) { 19 return false; 20 } 21 if ( empty( $updates ) ) { 22 return (object) array( 'response' => 'latest' ); 23 } 24 return $updates[0]; 25 } 26 27 /** 28 * Gets available core updates. 29 * 30 * @since 2.7.0 31 * 32 * @param array $options Set $options['dismissed'] to true to show dismissed upgrades too, 33 * set $options['available'] to false to skip not-dismissed updates. 34 * @return array|false Array of the update objects on success, false on failure. 35 */ 36 function get_core_updates( $options = array() ) { 37 $options = array_merge( 38 array( 39 'available' => true, 40 'dismissed' => false, 41 ), 42 $options 43 ); 44 $dismissed = get_site_option( 'dismissed_update_core' ); 45 46 if ( ! is_array( $dismissed ) ) { 47 $dismissed = array(); 48 } 49 50 $from_api = get_site_transient( 'update_core' ); 51 52 if ( ! isset( $from_api->updates ) || ! is_array( $from_api->updates ) ) { 53 return false; 54 } 55 56 $updates = $from_api->updates; 57 $result = array(); 58 foreach ( $updates as $update ) { 59 if ( 'autoupdate' === $update->response ) { 60 continue; 61 } 62 63 if ( array_key_exists( $update->current . '|' . $update->locale, $dismissed ) ) { 64 if ( $options['dismissed'] ) { 65 $update->dismissed = true; 66 $result[] = $update; 67 } 68 } else { 69 if ( $options['available'] ) { 70 $update->dismissed = false; 71 $result[] = $update; 72 } 73 } 74 } 75 return $result; 76 } 77 78 /** 79 * Gets the best available (and enabled) Auto-Update for WordPress core. 80 * 81 * If there's 1.2.3 and 1.3 on offer, it'll choose 1.3 if the installation allows it, else, 1.2.3. 82 * 83 * @since 3.7.0 84 * 85 * @return object|false The core update offering on success, false on failure. 86 */ 87 function find_core_auto_update() { 88 $updates = get_site_transient( 'update_core' ); 89 if ( ! $updates || empty( $updates->updates ) ) { 90 return false; 91 } 92 93 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; 94 95 $auto_update = false; 96 $upgrader = new WP_Automatic_Updater; 97 foreach ( $updates->updates as $update ) { 98 if ( 'autoupdate' !== $update->response ) { 99 continue; 100 } 101 102 if ( ! $upgrader->should_update( 'core', $update, ABSPATH ) ) { 103 continue; 104 } 105 106 if ( ! $auto_update || version_compare( $update->current, $auto_update->current, '>' ) ) { 107 $auto_update = $update; 108 } 109 } 110 return $auto_update; 111 } 112 113 /** 114 * Gets and caches the checksums for the given version of WordPress. 115 * 116 * @since 3.7.0 117 * 118 * @param string $version Version string to query. 119 * @param string $locale Locale to query. 120 * @return array|false An array of checksums on success, false on failure. 121 */ 122 function get_core_checksums( $version, $locale ) { 123 $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), '', '&' ); 124 $url = $http_url; 125 126 $ssl = wp_http_supports( array( 'ssl' ) ); 127 if ( $ssl ) { 128 $url = set_url_scheme( $url, 'https' ); 129 } 130 131 $options = array( 132 'timeout' => wp_doing_cron() ? 30 : 3, 133 ); 134 135 $response = wp_remote_get( $url, $options ); 136 if ( $ssl && is_wp_error( $response ) ) { 137 trigger_error( 138 sprintf( 139 /* translators: %s: Support forums URL. */ 140 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), 141 __( 'https://wordpress.org/support/forums/' ) 142 ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), 143 headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE 144 ); 145 $response = wp_remote_get( $http_url, $options ); 146 } 147 148 if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) { 149 return false; 150 } 151 152 $body = trim( wp_remote_retrieve_body( $response ) ); 153 $body = json_decode( $body, true ); 154 155 if ( ! is_array( $body ) || ! isset( $body['checksums'] ) || ! is_array( $body['checksums'] ) ) { 156 return false; 157 } 158 159 return $body['checksums']; 160 } 161 162 /** 163 * Dismisses core update. 164 * 165 * @since 2.7.0 166 * 167 * @param object $update 168 * @return bool 169 */ 170 function dismiss_core_update( $update ) { 171 $dismissed = get_site_option( 'dismissed_update_core' ); 172 $dismissed[ $update->current . '|' . $update->locale ] = true; 173 return update_site_option( 'dismissed_update_core', $dismissed ); 174 } 175 176 /** 177 * Undismisses core update. 178 * 179 * @since 2.7.0 180 * 181 * @param string $version 182 * @param string $locale 183 * @return bool 184 */ 185 function undismiss_core_update( $version, $locale ) { 186 $dismissed = get_site_option( 'dismissed_update_core' ); 187 $key = $version . '|' . $locale; 188 189 if ( ! isset( $dismissed[ $key ] ) ) { 190 return false; 191 } 192 193 unset( $dismissed[ $key ] ); 194 return update_site_option( 'dismissed_update_core', $dismissed ); 195 } 196 197 /** 198 * Finds the available update for WordPress core. 199 * 200 * @since 2.7.0 201 * 202 * @param string $version Version string to find the update for. 203 * @param string $locale Locale to find the update for. 204 * @return object|false The core update offering on success, false on failure. 205 */ 206 function find_core_update( $version, $locale ) { 207 $from_api = get_site_transient( 'update_core' ); 208 209 if ( ! isset( $from_api->updates ) || ! is_array( $from_api->updates ) ) { 210 return false; 211 } 212 213 $updates = $from_api->updates; 214 foreach ( $updates as $update ) { 215 if ( $update->current == $version && $update->locale == $locale ) { 216 return $update; 217 } 218 } 219 return false; 220 } 221 222 /** 223 * @since 2.3.0 224 * 225 * @param string $msg 226 * @return string 227 */ 228 function core_update_footer( $msg = '' ) { 229 if ( ! current_user_can( 'update_core' ) ) { 230 /* translators: %s: WordPress version. */ 231 return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) ); 232 } 233 234 $cur = get_preferred_from_update_core(); 235 if ( ! is_object( $cur ) ) { 236 $cur = new stdClass; 237 } 238 239 if ( ! isset( $cur->current ) ) { 240 $cur->current = ''; 241 } 242 243 if ( ! isset( $cur->response ) ) { 244 $cur->response = ''; 245 } 246 247 // Include an unmodified $wp_version. 248 require ABSPATH . WPINC . '/version.php'; 249 250 $is_development_version = preg_match( '/alpha|beta|RC/', $wp_version ); 251 252 if ( $is_development_version ) { 253 return sprintf( 254 /* translators: 1: WordPress version number, 2: URL to WordPress Updates screen. */ 255 __( 'You are using a development version (%1$s). Cool! Please <a href="%2$s">stay updated</a>.' ), 256 get_bloginfo( 'version', 'display' ), 257 network_admin_url( 'update-core.php' ) 258 ); 259 } 260 261 switch ( $cur->response ) { 262 case 'upgrade': 263 return sprintf( 264 '<strong><a href="%s">%s</a></strong>', 265 network_admin_url( 'update-core.php' ), 266 /* translators: %s: WordPress version. */ 267 sprintf( __( 'Get Version %s' ), $cur->current ) 268 ); 269 270 case 'latest': 271 default: 272 /* translators: %s: WordPress version. */ 273 return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) ); 274 } 275 } 276 277 /** 278 * @since 2.3.0 279 * 280 * @global string $pagenow The filename of the current screen. 281 * @return void|false 282 */ 283 function update_nag() { 284 global $pagenow; 285 286 if ( is_multisite() && ! current_user_can( 'update_core' ) ) { 287 return false; 288 } 289 290 if ( 'update-core.php' === $pagenow ) { 291 return; 292 } 293 294 $cur = get_preferred_from_update_core(); 295 296 if ( ! isset( $cur->response ) || 'upgrade' !== $cur->response ) { 297 return false; 298 } 299 300 $version_url = sprintf( 301 /* translators: %s: WordPress version. */ 302 esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ), 303 sanitize_title( $cur->current ) 304 ); 305 306 if ( current_user_can( 'update_core' ) ) { 307 $msg = sprintf( 308 /* translators: 1: URL to WordPress release notes, 2: New WordPress version, 3: URL to network admin, 4: Accessibility text. */ 309 __( '<a href="%1$s">WordPress %2$s</a> is available! <a href="%3$s" aria-label="%4$s">Please update now</a>.' ), 310 $version_url, 311 $cur->current, 312 network_admin_url( 'update-core.php' ), 313 esc_attr__( 'Please update WordPress now' ) 314 ); 315 } else { 316 $msg = sprintf( 317 /* translators: 1: URL to WordPress release notes, 2: New WordPress version. */ 318 __( '<a href="%1$s">WordPress %2$s</a> is available! Please notify the site administrator.' ), 319 $version_url, 320 $cur->current 321 ); 322 } 323 324 echo "<div class='update-nag notice notice-warning inline'>$msg</div>"; 325 } 326 327 /** 328 * Displays WordPress version and active theme in the 'At a Glance' dashboard widget. 329 * 330 * @since 2.5.0 331 */ 332 function update_right_now_message() { 333 $theme_name = wp_get_theme(); 334 if ( current_user_can( 'switch_themes' ) ) { 335 $theme_name = sprintf( '<a href="themes.php">%1$s</a>', $theme_name ); 336 } 337 338 $msg = ''; 339 340 if ( current_user_can( 'update_core' ) ) { 341 $cur = get_preferred_from_update_core(); 342 343 if ( isset( $cur->response ) && 'upgrade' === $cur->response ) { 344 $msg .= sprintf( 345 '<a href="%s" class="button" aria-describedby="wp-version">%s</a> ', 346 network_admin_url( 'update-core.php' ), 347 /* translators: %s: WordPress version number, or 'Latest' string. */ 348 sprintf( __( 'Update to %s' ), $cur->current ? $cur->current : __( 'Latest' ) ) 349 ); 350 } 351 } 352 353 /* translators: 1: Version number, 2: Theme name. */ 354 $content = __( 'WordPress %1$s running %2$s theme.' ); 355 356 /** 357 * Filters the text displayed in the 'At a Glance' dashboard widget. 358 * 359 * Prior to 3.8.0, the widget was named 'Right Now'. 360 * 361 * @since 4.4.0 362 * 363 * @param string $content Default text. 364 */ 365 $content = apply_filters( 'update_right_now_text', $content ); 366 367 $msg .= sprintf( '<span id="wp-version">' . $content . '</span>', get_bloginfo( 'version', 'display' ), $theme_name ); 368 369 echo "<p id='wp-version-message'>$msg</p>"; 370 } 371 372 /** 373 * @since 2.9.0 374 * 375 * @return array 376 */ 377 function get_plugin_updates() { 378 $all_plugins = get_plugins(); 379 $upgrade_plugins = array(); 380 $current = get_site_transient( 'update_plugins' ); 381 foreach ( (array) $all_plugins as $plugin_file => $plugin_data ) { 382 if ( isset( $current->response[ $plugin_file ] ) ) { 383 $upgrade_plugins[ $plugin_file ] = (object) $plugin_data; 384 $upgrade_plugins[ $plugin_file ]->update = $current->response[ $plugin_file ]; 385 } 386 } 387 388 return $upgrade_plugins; 389 } 390 391 /** 392 * @since 2.9.0 393 */ 394 function wp_plugin_update_rows() { 395 if ( ! current_user_can( 'update_plugins' ) ) { 396 return; 397 } 398 399 $plugins = get_site_transient( 'update_plugins' ); 400 if ( isset( $plugins->response ) && is_array( $plugins->response ) ) { 401 $plugins = array_keys( $plugins->response ); 402 foreach ( $plugins as $plugin_file ) { 403 add_action( "after_plugin_row_{$plugin_file}", 'wp_plugin_update_row', 10, 2 ); 404 } 405 } 406 } 407 408 /** 409 * Displays update information for a plugin. 410 * 411 * @since 2.3.0 412 * 413 * @param string $file Plugin basename. 414 * @param array $plugin_data Plugin information. 415 * @return void|false 416 */ 417 function wp_plugin_update_row( $file, $plugin_data ) { 418 $current = get_site_transient( 'update_plugins' ); 419 if ( ! isset( $current->response[ $file ] ) ) { 420 return false; 421 } 422 423 $response = $current->response[ $file ]; 424 425 $plugins_allowedtags = array( 426 'a' => array( 427 'href' => array(), 428 'title' => array(), 429 ), 430 'abbr' => array( 'title' => array() ), 431 'acronym' => array( 'title' => array() ), 432 'code' => array(), 433 'em' => array(), 434 'strong' => array(), 435 ); 436 437 $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags ); 438 $plugin_slug = isset( $response->slug ) ? $response->slug : $response->id; 439 440 if ( isset( $response->slug ) ) { 441 $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin_slug . '§ion=changelog' ); 442 } elseif ( isset( $response->url ) ) { 443 $details_url = $response->url; 444 } else { 445 $details_url = $plugin_data['PluginURI']; 446 } 447 448 $details_url = add_query_arg( 449 array( 450 'TB_iframe' => 'true', 451 'width' => 600, 452 'height' => 800, 453 ), 454 $details_url 455 ); 456 457 /** @var WP_Plugins_List_Table $wp_list_table */ 458 $wp_list_table = _get_list_table( 459 'WP_Plugins_List_Table', 460 array( 461 'screen' => get_current_screen(), 462 ) 463 ); 464 465 if ( is_network_admin() || ! is_multisite() ) { 466 if ( is_network_admin() ) { 467 $active_class = is_plugin_active_for_network( $file ) ? ' active' : ''; 468 } else { 469 $active_class = is_plugin_active( $file ) ? ' active' : ''; 470 } 471 472 $requires_php = isset( $response->requires_php ) ? $response->requires_php : null; 473 $compatible_php = is_php_version_compatible( $requires_php ); 474 $notice_type = $compatible_php ? 'notice-warning' : 'notice-error'; 475 476 printf( 477 '<tr class="plugin-update-tr%s" id="%s" data-slug="%s" data-plugin="%s">' . 478 '<td colspan="%s" class="plugin-update colspanchange">' . 479 '<div class="update-message notice inline %s notice-alt"><p>', 480 $active_class, 481 esc_attr( $plugin_slug . '-update' ), 482 esc_attr( $plugin_slug ), 483 esc_attr( $file ), 484 esc_attr( $wp_list_table->get_column_count() ), 485 $notice_type 486 ); 487 488 if ( ! current_user_can( 'update_plugins' ) ) { 489 printf( 490 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 491 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ), 492 $plugin_name, 493 esc_url( $details_url ), 494 sprintf( 495 'class="thickbox open-plugin-details-modal" aria-label="%s"', 496 /* translators: 1: Plugin name, 2: Version number. */ 497 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 498 ), 499 esc_attr( $response->new_version ) 500 ); 501 } elseif ( empty( $response->package ) ) { 502 printf( 503 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 504 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this plugin.</em>' ), 505 $plugin_name, 506 esc_url( $details_url ), 507 sprintf( 508 'class="thickbox open-plugin-details-modal" aria-label="%s"', 509 /* translators: 1: Plugin name, 2: Version number. */ 510 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 511 ), 512 esc_attr( $response->new_version ) 513 ); 514 } else { 515 if ( $compatible_php ) { 516 printf( 517 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ 518 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ), 519 $plugin_name, 520 esc_url( $details_url ), 521 sprintf( 522 'class="thickbox open-plugin-details-modal" aria-label="%s"', 523 /* translators: 1: Plugin name, 2: Version number. */ 524 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 525 ), 526 esc_attr( $response->new_version ), 527 wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ), 528 sprintf( 529 'class="update-link" aria-label="%s"', 530 /* translators: %s: Plugin name. */ 531 esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $plugin_name ) ) 532 ) 533 ); 534 } else { 535 printf( 536 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number 5: URL to Update PHP page. */ 537 __( 'There is a new version of %1$s available, but it does not work with your version of PHP. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s">learn more about updating PHP</a>.' ), 538 $plugin_name, 539 esc_url( $details_url ), 540 sprintf( 541 'class="thickbox open-plugin-details-modal" aria-label="%s"', 542 /* translators: 1: Plugin name, 2: Version number. */ 543 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 544 ), 545 esc_attr( $response->new_version ), 546 esc_url( wp_get_update_php_url() ) 547 ); 548 wp_update_php_annotation( '<br><em>', '</em>' ); 549 } 550 } 551 552 /** 553 * Fires at the end of the update message container in each 554 * row of the plugins list table. 555 * 556 * The dynamic portion of the hook name, `$file`, refers to the path 557 * of the plugin's primary file relative to the plugins directory. 558 * 559 * @since 2.8.0 560 * 561 * @param array $plugin_data An array of plugin metadata. See get_plugin_data() 562 * and the {@see 'plugin_row_meta'} filter for the list 563 * of possible values. 564 * @param object $response { 565 * An object of metadata about the available plugin update. 566 * 567 * @type string $id Plugin ID, e.g. `w.org/plugins/[plugin-name]`. 568 * @type string $slug Plugin slug. 569 * @type string $plugin Plugin basename. 570 * @type string $new_version New plugin version. 571 * @type string $url Plugin URL. 572 * @type string $package Plugin update package URL. 573 * @type string[] $icons An array of plugin icon URLs. 574 * @type string[] $banners An array of plugin banner URLs. 575 * @type string[] $banners_rtl An array of plugin RTL banner URLs. 576 * @type string $requires The version of WordPress which the plugin requires. 577 * @type string $tested The version of WordPress the plugin is tested against. 578 * @type string $requires_php The version of PHP which the plugin requires. 579 * } 580 */ 581 do_action( "in_plugin_update_message-{$file}", $plugin_data, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 582 583 echo '</p></div></td></tr>'; 584 } 585 } 586 587 /** 588 * @since 2.9.0 589 * 590 * @return array 591 */ 592 function get_theme_updates() { 593 $current = get_site_transient( 'update_themes' ); 594 595 if ( ! isset( $current->response ) ) { 596 return array(); 597 } 598 599 $update_themes = array(); 600 foreach ( $current->response as $stylesheet => $data ) { 601 $update_themes[ $stylesheet ] = wp_get_theme( $stylesheet ); 602 $update_themes[ $stylesheet ]->update = $data; 603 } 604 605 return $update_themes; 606 } 607 608 /** 609 * @since 3.1.0 610 */ 611 function wp_theme_update_rows() { 612 if ( ! current_user_can( 'update_themes' ) ) { 613 return; 614 } 615 616 $themes = get_site_transient( 'update_themes' ); 617 if ( isset( $themes->response ) && is_array( $themes->response ) ) { 618 $themes = array_keys( $themes->response ); 619 620 foreach ( $themes as $theme ) { 621 add_action( "after_theme_row_{$theme}", 'wp_theme_update_row', 10, 2 ); 622 } 623 } 624 } 625 626 /** 627 * Displays update information for a theme. 628 * 629 * @since 3.1.0 630 * 631 * @param string $theme_key Theme stylesheet. 632 * @param WP_Theme $theme Theme object. 633 * @return void|false 634 */ 635 function wp_theme_update_row( $theme_key, $theme ) { 636 $current = get_site_transient( 'update_themes' ); 637 638 if ( ! isset( $current->response[ $theme_key ] ) ) { 639 return false; 640 } 641 642 $response = $current->response[ $theme_key ]; 643 644 $details_url = add_query_arg( 645 array( 646 'TB_iframe' => 'true', 647 'width' => 1024, 648 'height' => 800, 649 ), 650 $current->response[ $theme_key ]['url'] 651 ); 652 653 /** @var WP_MS_Themes_List_Table $wp_list_table */ 654 $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' ); 655 656 $active = $theme->is_allowed( 'network' ) ? ' active' : ''; 657 658 $requires_wp = isset( $response['requires'] ) ? $response['requires'] : null; 659 $requires_php = isset( $response['requires_php'] ) ? $response['requires_php'] : null; 660 661 $compatible_wp = is_wp_version_compatible( $requires_wp ); 662 $compatible_php = is_php_version_compatible( $requires_php ); 663 664 printf( 665 '<tr class="plugin-update-tr%s" id="%s" data-slug="%s">' . 666 '<td colspan="%s" class="plugin-update colspanchange">' . 667 '<div class="update-message notice inline notice-warning notice-alt"><p>', 668 $active, 669 esc_attr( $theme->get_stylesheet() . '-update' ), 670 esc_attr( $theme->get_stylesheet() ), 671 $wp_list_table->get_column_count() 672 ); 673 674 if ( $compatible_wp && $compatible_php ) { 675 if ( ! current_user_can( 'update_themes' ) ) { 676 printf( 677 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 678 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ), 679 $theme['Name'], 680 esc_url( $details_url ), 681 sprintf( 682 'class="thickbox open-plugin-details-modal" aria-label="%s"', 683 /* translators: 1: Theme name, 2: Version number. */ 684 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 685 ), 686 $response['new_version'] 687 ); 688 } elseif ( empty( $response['package'] ) ) { 689 printf( 690 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 691 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ), 692 $theme['Name'], 693 esc_url( $details_url ), 694 sprintf( 695 'class="thickbox open-plugin-details-modal" aria-label="%s"', 696 /* translators: 1: Theme name, 2: Version number. */ 697 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 698 ), 699 $response['new_version'] 700 ); 701 } else { 702 printf( 703 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ 704 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ), 705 $theme['Name'], 706 esc_url( $details_url ), 707 sprintf( 708 'class="thickbox open-plugin-details-modal" aria-label="%s"', 709 /* translators: 1: Theme name, 2: Version number. */ 710 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 711 ), 712 $response['new_version'], 713 wp_nonce_url( self_admin_url( 'update.php?action=upgrade-theme&theme=' ) . $theme_key, 'upgrade-theme_' . $theme_key ), 714 sprintf( 715 'class="update-link" aria-label="%s"', 716 /* translators: %s: Theme name. */ 717 esc_attr( sprintf( _x( 'Update %s now', 'theme' ), $theme['Name'] ) ) 718 ) 719 ); 720 } 721 } else { 722 if ( ! $compatible_wp && ! $compatible_php ) { 723 printf( 724 /* translators: %s: Theme name. */ 725 __( 'There is a new version of %s available, but it does not work with your versions of WordPress and PHP.' ), 726 $theme['Name'] 727 ); 728 if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { 729 printf( 730 /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ 731 ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), 732 self_admin_url( 'update-core.php' ), 733 esc_url( wp_get_update_php_url() ) 734 ); 735 wp_update_php_annotation( '</p><p><em>', '</em>' ); 736 } elseif ( current_user_can( 'update_core' ) ) { 737 printf( 738 /* translators: %s: URL to WordPress Updates screen. */ 739 ' ' . __( '<a href="%s">Please update WordPress</a>.' ), 740 self_admin_url( 'update-core.php' ) 741 ); 742 } elseif ( current_user_can( 'update_php' ) ) { 743 printf( 744 /* translators: %s: URL to Update PHP page. */ 745 ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), 746 esc_url( wp_get_update_php_url() ) 747 ); 748 wp_update_php_annotation( '</p><p><em>', '</em>' ); 749 } 750 } elseif ( ! $compatible_wp ) { 751 printf( 752 /* translators: %s: Theme name. */ 753 __( 'There is a new version of %s available, but it does not work with your version of WordPress.' ), 754 $theme['Name'] 755 ); 756 if ( current_user_can( 'update_core' ) ) { 757 printf( 758 /* translators: %s: URL to WordPress Updates screen. */ 759 ' ' . __( '<a href="%s">Please update WordPress</a>.' ), 760 self_admin_url( 'update-core.php' ) 761 ); 762 } 763 } elseif ( ! $compatible_php ) { 764 printf( 765 /* translators: %s: Theme name. */ 766 __( 'There is a new version of %s available, but it does not work with your version of PHP.' ), 767 $theme['Name'] 768 ); 769 if ( current_user_can( 'update_php' ) ) { 770 printf( 771 /* translators: %s: URL to Update PHP page. */ 772 ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), 773 esc_url( wp_get_update_php_url() ) 774 ); 775 wp_update_php_annotation( '</p><p><em>', '</em>' ); 776 } 777 } 778 } 779 780 /** 781 * Fires at the end of the update message container in each 782 * row of the themes list table. 783 * 784 * The dynamic portion of the hook name, `$theme_key`, refers to 785 * the theme slug as found in the WordPress.org themes repository. 786 * 787 * @since 3.1.0 788 * 789 * @param WP_Theme $theme The WP_Theme object. 790 * @param array $response { 791 * An array of metadata about the available theme update. 792 * 793 * @type string $new_version New theme version. 794 * @type string $url Theme URL. 795 * @type string $package Theme update package URL. 796 * } 797 */ 798 do_action( "in_theme_update_message-{$theme_key}", $theme, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 799 800 echo '</p></div></td></tr>'; 801 } 802 803 /** 804 * @since 2.7.0 805 * 806 * @global int $upgrading 807 * @return void|false 808 */ 809 function maintenance_nag() { 810 // Include an unmodified $wp_version. 811 require ABSPATH . WPINC . '/version.php'; 812 global $upgrading; 813 $nag = isset( $upgrading ); 814 if ( ! $nag ) { 815 $failed = get_site_option( 'auto_core_update_failed' ); 816 /* 817 * If an update failed critically, we may have copied over version.php but not other files. 818 * In that case, if the installation claims we're running the version we attempted, nag. 819 * This is serious enough to err on the side of nagging. 820 * 821 * If we simply failed to update before we tried to copy any files, then assume things are 822 * OK if they are now running the latest. 823 * 824 * This flag is cleared whenever a successful update occurs using Core_Upgrader. 825 */ 826 $comparison = ! empty( $failed['critical'] ) ? '>=' : '>'; 827 if ( isset( $failed['attempted'] ) && version_compare( $failed['attempted'], $wp_version, $comparison ) ) { 828 $nag = true; 829 } 830 } 831 832 if ( ! $nag ) { 833 return false; 834 } 835 836 if ( current_user_can( 'update_core' ) ) { 837 $msg = sprintf( 838 /* translators: %s: URL to WordPress Updates screen. */ 839 __( 'An automated WordPress update has failed to complete - <a href="%s">please attempt the update again now</a>.' ), 840 'update-core.php' 841 ); 842 } else { 843 $msg = __( 'An automated WordPress update has failed to complete! Please notify the site administrator.' ); 844 } 845 846 echo "<div class='update-nag notice notice-warning inline'>$msg</div>"; 847 } 848 849 /** 850 * Prints the JavaScript templates for update admin notices. 851 * 852 * Template takes one argument with four values: 853 * 854 * param {object} data { 855 * Arguments for admin notice. 856 * 857 * @type string id ID of the notice. 858 * @type string className Class names for the notice. 859 * @type string message The notice's message. 860 * @type string type The type of update the notice is for. Either 'plugin' or 'theme'. 861 * } 862 * 863 * @since 4.6.0 864 */ 865 function wp_print_admin_notice_templates() { 866 ?> 867 <script id="tmpl-wp-updates-admin-notice" type="text/html"> 868 <div <# if ( data.id ) { #>id="{{ data.id }}"<# } #> class="notice {{ data.className }}"><p>{{{ data.message }}}</p></div> 869 </script> 870 <script id="tmpl-wp-bulk-updates-admin-notice" type="text/html"> 871 <div id="{{ data.id }}" class="{{ data.className }} notice <# if ( data.errors ) { #>notice-error<# } else { #>notice-success<# } #>"> 872 <p> 873 <# if ( data.successes ) { #> 874 <# if ( 1 === data.successes ) { #> 875 <# if ( 'plugin' === data.type ) { #> 876 <?php 877 /* translators: %s: Number of plugins. */ 878 printf( __( '%s plugin successfully updated.' ), '{{ data.successes }}' ); 879 ?> 880 <# } else { #> 881 <?php 882 /* translators: %s: Number of themes. */ 883 printf( __( '%s theme successfully updated.' ), '{{ data.successes }}' ); 884 ?> 885 <# } #> 886 <# } else { #> 887 <# if ( 'plugin' === data.type ) { #> 888 <?php 889 /* translators: %s: Number of plugins. */ 890 printf( __( '%s plugins successfully updated.' ), '{{ data.successes }}' ); 891 ?> 892 <# } else { #> 893 <?php 894 /* translators: %s: Number of themes. */ 895 printf( __( '%s themes successfully updated.' ), '{{ data.successes }}' ); 896 ?> 897 <# } #> 898 <# } #> 899 <# } #> 900 <# if ( data.errors ) { #> 901 <button class="button-link bulk-action-errors-collapsed" aria-expanded="false"> 902 <# if ( 1 === data.errors ) { #> 903 <?php 904 /* translators: %s: Number of failed updates. */ 905 printf( __( '%s update failed.' ), '{{ data.errors }}' ); 906 ?> 907 <# } else { #> 908 <?php 909 /* translators: %s: Number of failed updates. */ 910 printf( __( '%s updates failed.' ), '{{ data.errors }}' ); 911 ?> 912 <# } #> 913 <span class="screen-reader-text"><?php _e( 'Show more details' ); ?></span> 914 <span class="toggle-indicator" aria-hidden="true"></span> 915 </button> 916 <# } #> 917 </p> 918 <# if ( data.errors ) { #> 919 <ul class="bulk-action-errors hidden"> 920 <# _.each( data.errorMessages, function( errorMessage ) { #> 921 <li>{{ errorMessage }}</li> 922 <# } ); #> 923 </ul> 924 <# } #> 925 </div> 926 </script> 927 <?php 928 } 929 930 /** 931 * Prints the JavaScript templates for update and deletion rows in list tables. 932 * 933 * The update template takes one argument with four values: 934 * 935 * param {object} data { 936 * Arguments for the update row 937 * 938 * @type string slug Plugin slug. 939 * @type string plugin Plugin base name. 940 * @type string colspan The number of table columns this row spans. 941 * @type string content The row content. 942 * } 943 * 944 * The delete template takes one argument with four values: 945 * 946 * param {object} data { 947 * Arguments for the update row 948 * 949 * @type string slug Plugin slug. 950 * @type string plugin Plugin base name. 951 * @type string name Plugin name. 952 * @type string colspan The number of table columns this row spans. 953 * } 954 * 955 * @since 4.6.0 956 */ 957 function wp_print_update_row_templates() { 958 ?> 959 <script id="tmpl-item-update-row" type="text/template"> 960 <tr class="plugin-update-tr update" id="{{ data.slug }}-update" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>> 961 <td colspan="{{ data.colspan }}" class="plugin-update colspanchange"> 962 {{{ data.content }}} 963 </td> 964 </tr> 965 </script> 966 <script id="tmpl-item-deleted-row" type="text/template"> 967 <tr class="plugin-deleted-tr inactive deleted" id="{{ data.slug }}-deleted" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>> 968 <td colspan="{{ data.colspan }}" class="plugin-update colspanchange"> 969 <# if ( data.plugin ) { #> 970 <?php 971 printf( 972 /* translators: %s: Plugin name. */ 973 _x( '%s was successfully deleted.', 'plugin' ), 974 '<strong>{{{ data.name }}}</strong>' 975 ); 976 ?> 977 <# } else { #> 978 <?php 979 printf( 980 /* translators: %s: Theme name. */ 981 _x( '%s was successfully deleted.', 'theme' ), 982 '<strong>{{{ data.name }}}</strong>' 983 ); 984 ?> 985 <# } #> 986 </td> 987 </tr> 988 </script> 989 <?php 990 } 991 992 /** 993 * Displays a notice when the user is in recovery mode. 994 * 995 * @since 5.2.0 996 */ 997 function wp_recovery_mode_nag() { 998 if ( ! wp_is_recovery_mode() ) { 999 return; 1000 } 1001 1002 $url = wp_login_url(); 1003 $url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url ); 1004 $url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION ); 1005 1006 ?> 1007 <div class="notice notice-info"> 1008 <p> 1009 <?php 1010 printf( 1011 /* translators: %s: Recovery Mode exit link. */ 1012 __( 'You are in recovery mode. This means there may be an error with a theme or plugin. To exit recovery mode, log out or use the Exit button. <a href="%s">Exit Recovery Mode</a>' ), 1013 esc_url( $url ) 1014 ); 1015 ?> 1016 </p> 1017 </div> 1018 <?php 1019 } 1020 1021 /** 1022 * Checks whether auto-updates are enabled. 1023 * 1024 * @since 5.5.0 1025 * 1026 * @param string $type The type of update being checked: 'theme' or 'plugin'. 1027 * @return bool True if auto-updates are enabled for `$type`, false otherwise. 1028 */ 1029 function wp_is_auto_update_enabled_for_type( $type ) { 1030 if ( ! class_exists( 'WP_Automatic_Updater' ) ) { 1031 require_once ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php'; 1032 } 1033 1034 $updater = new WP_Automatic_Updater(); 1035 $enabled = ! $updater->is_disabled(); 1036 1037 switch ( $type ) { 1038 case 'plugin': 1039 /** 1040 * Filters whether plugins auto-update is enabled. 1041 * 1042 * @since 5.5.0 1043 * 1044 * @param bool $enabled True if plugins auto-update is enabled, false otherwise. 1045 */ 1046 return apply_filters( 'plugins_auto_update_enabled', $enabled ); 1047 case 'theme': 1048 /** 1049 * Filters whether themes auto-update is enabled. 1050 * 1051 * @since 5.5.0 1052 * 1053 * @param bool $enabled True if themes auto-update is enabled, false otherwise. 1054 */ 1055 return apply_filters( 'themes_auto_update_enabled', $enabled ); 1056 } 1057 1058 return false; 1059 } 1060 1061 /** 1062 * Checks whether auto-updates are forced for an item. 1063 * 1064 * @since 5.6.0 1065 * 1066 * @param string $type The type of update being checked: 'theme' or 'plugin'. 1067 * @param bool|null $update Whether to update. The value of null is internally used 1068 * to detect whether nothing has hooked into this filter. 1069 * @param object $item The update offer. 1070 * @return bool True if auto-updates are forced for `$item`, false otherwise. 1071 */ 1072 function wp_is_auto_update_forced_for_item( $type, $update, $item ) { 1073 /** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */ 1074 return apply_filters( "auto_update_{$type}", $update, $item ); 1075 } 1076 1077 /** 1078 * Determines the appropriate auto-update message to be displayed. 1079 * 1080 * @since 5.5.0 1081 * 1082 * @return string The update message to be shown. 1083 */ 1084 function wp_get_auto_update_message() { 1085 $next_update_time = wp_next_scheduled( 'wp_version_check' ); 1086 1087 // Check if the event exists. 1088 if ( false === $next_update_time ) { 1089 $message = __( 'Automatic update not scheduled. There may be a problem with WP-Cron.' ); 1090 } else { 1091 $time_to_next_update = human_time_diff( (int) $next_update_time ); 1092 1093 // See if cron is overdue. 1094 $overdue = ( time() - $next_update_time ) > 0; 1095 1096 if ( $overdue ) { 1097 $message = sprintf( 1098 /* translators: %s: Duration that WP-Cron has been overdue. */ 1099 __( 'Automatic update overdue by %s. There may be a problem with WP-Cron.' ), 1100 $time_to_next_update 1101 ); 1102 } else { 1103 $message = sprintf( 1104 /* translators: %s: Time until the next update. */ 1105 __( 'Automatic update scheduled in %s.' ), 1106 $time_to_next_update 1107 ); 1108 } 1109 } 1110 1111 return $message; 1112 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Dec 7 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |