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