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