[ 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' ), null, '&' ); 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 281 * @return void|false 282 */ 283 function update_nag() { 284 if ( is_multisite() && ! current_user_can( 'update_core' ) ) { 285 return false; 286 } 287 288 global $pagenow; 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 $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $response->slug . '§ion=changelog&TB_iframe=true&width=600&height=800' ); 439 440 /** @var WP_Plugins_List_Table $wp_list_table */ 441 $wp_list_table = _get_list_table( 442 'WP_Plugins_List_Table', 443 array( 444 'screen' => get_current_screen(), 445 ) 446 ); 447 448 if ( is_network_admin() || ! is_multisite() ) { 449 if ( is_network_admin() ) { 450 $active_class = is_plugin_active_for_network( $file ) ? ' active' : ''; 451 } else { 452 $active_class = is_plugin_active( $file ) ? ' active' : ''; 453 } 454 455 $requires_php = isset( $response->requires_php ) ? $response->requires_php : null; 456 $compatible_php = is_php_version_compatible( $requires_php ); 457 $notice_type = $compatible_php ? 'notice-warning' : 'notice-error'; 458 459 printf( 460 '<tr class="plugin-update-tr%s" id="%s" data-slug="%s" data-plugin="%s">' . 461 '<td colspan="%s" class="plugin-update colspanchange">' . 462 '<div class="update-message notice inline %s notice-alt"><p>', 463 $active_class, 464 esc_attr( $response->slug . '-update' ), 465 esc_attr( $response->slug ), 466 esc_attr( $file ), 467 esc_attr( $wp_list_table->get_column_count() ), 468 $notice_type 469 ); 470 471 if ( ! current_user_can( 'update_plugins' ) ) { 472 printf( 473 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 474 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ), 475 $plugin_name, 476 esc_url( $details_url ), 477 sprintf( 478 'class="thickbox open-plugin-details-modal" aria-label="%s"', 479 /* translators: 1: Plugin name, 2: Version number. */ 480 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 481 ), 482 esc_attr( $response->new_version ) 483 ); 484 } elseif ( empty( $response->package ) ) { 485 printf( 486 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 487 __( '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>' ), 488 $plugin_name, 489 esc_url( $details_url ), 490 sprintf( 491 'class="thickbox open-plugin-details-modal" aria-label="%s"', 492 /* translators: 1: Plugin name, 2: Version number. */ 493 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 494 ), 495 esc_attr( $response->new_version ) 496 ); 497 } else { 498 if ( $compatible_php ) { 499 printf( 500 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ 501 __( '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>.' ), 502 $plugin_name, 503 esc_url( $details_url ), 504 sprintf( 505 'class="thickbox open-plugin-details-modal" aria-label="%s"', 506 /* translators: 1: Plugin name, 2: Version number. */ 507 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 508 ), 509 esc_attr( $response->new_version ), 510 wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ), 511 sprintf( 512 'class="update-link" aria-label="%s"', 513 /* translators: %s: Plugin name. */ 514 esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $plugin_name ) ) 515 ) 516 ); 517 } else { 518 printf( 519 /* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number 5: URL to Update PHP page. */ 520 __( 'There is a new version of %1$s available, but it doesn’t 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>.' ), 521 $plugin_name, 522 esc_url( $details_url ), 523 sprintf( 524 'class="thickbox open-plugin-details-modal" aria-label="%s"', 525 /* translators: 1: Plugin name, 2: Version number. */ 526 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) ) 527 ), 528 esc_attr( $response->new_version ), 529 esc_url( wp_get_update_php_url() ) 530 ); 531 wp_update_php_annotation( '<br><em>', '</em>' ); 532 } 533 } 534 535 /** 536 * Fires at the end of the update message container in each 537 * row of the plugins list table. 538 * 539 * The dynamic portion of the hook name, `$file`, refers to the path 540 * of the plugin's primary file relative to the plugins directory. 541 * 542 * @since 2.8.0 543 * 544 * @param array $plugin_data { 545 * An array of plugin metadata. 546 * 547 * @type string $name The human-readable name of the plugin. 548 * @type string $plugin_uri Plugin URI. 549 * @type string $version Plugin version. 550 * @type string $description Plugin description. 551 * @type string $author Plugin author. 552 * @type string $author_uri Plugin author URI. 553 * @type string $text_domain Plugin text domain. 554 * @type string $domain_path Relative path to the plugin's .mo file(s). 555 * @type bool $network Whether the plugin can only be activated network wide. 556 * @type string $title The human-readable title of the plugin. 557 * @type string $author_name Plugin author's name. 558 * @type bool $update Whether there's an available update. Default null. 559 * } 560 * @param array $response { 561 * An array of metadata about the available plugin update. 562 * 563 * @type int $id Plugin ID. 564 * @type string $slug Plugin slug. 565 * @type string $new_version New plugin version. 566 * @type string $url Plugin URL. 567 * @type string $package Plugin update package URL. 568 * } 569 */ 570 do_action( "in_plugin_update_message-{$file}", $plugin_data, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 571 572 echo '</p></div></td></tr>'; 573 } 574 } 575 576 /** 577 * @since 2.9.0 578 * 579 * @return array 580 */ 581 function get_theme_updates() { 582 $current = get_site_transient( 'update_themes' ); 583 584 if ( ! isset( $current->response ) ) { 585 return array(); 586 } 587 588 $update_themes = array(); 589 foreach ( $current->response as $stylesheet => $data ) { 590 $update_themes[ $stylesheet ] = wp_get_theme( $stylesheet ); 591 $update_themes[ $stylesheet ]->update = $data; 592 } 593 594 return $update_themes; 595 } 596 597 /** 598 * @since 3.1.0 599 */ 600 function wp_theme_update_rows() { 601 if ( ! current_user_can( 'update_themes' ) ) { 602 return; 603 } 604 605 $themes = get_site_transient( 'update_themes' ); 606 if ( isset( $themes->response ) && is_array( $themes->response ) ) { 607 $themes = array_keys( $themes->response ); 608 609 foreach ( $themes as $theme ) { 610 add_action( "after_theme_row_{$theme}", 'wp_theme_update_row', 10, 2 ); 611 } 612 } 613 } 614 615 /** 616 * Displays update information for a theme. 617 * 618 * @since 3.1.0 619 * 620 * @param string $theme_key Theme stylesheet. 621 * @param WP_Theme $theme Theme object. 622 * @return void|false 623 */ 624 function wp_theme_update_row( $theme_key, $theme ) { 625 $current = get_site_transient( 'update_themes' ); 626 627 if ( ! isset( $current->response[ $theme_key ] ) ) { 628 return false; 629 } 630 631 $response = $current->response[ $theme_key ]; 632 633 $details_url = add_query_arg( 634 array( 635 'TB_iframe' => 'true', 636 'width' => 1024, 637 'height' => 800, 638 ), 639 $current->response[ $theme_key ]['url'] 640 ); 641 642 /** @var WP_MS_Themes_List_Table $wp_list_table */ 643 $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' ); 644 645 $active = $theme->is_allowed( 'network' ) ? ' active' : ''; 646 647 $requires_wp = isset( $response['requires'] ) ? $response['requires'] : null; 648 $requires_php = isset( $response['requires_php'] ) ? $response['requires_php'] : null; 649 650 $compatible_wp = is_wp_version_compatible( $requires_wp ); 651 $compatible_php = is_php_version_compatible( $requires_php ); 652 653 printf( 654 '<tr class="plugin-update-tr%s" id="%s" data-slug="%s">' . 655 '<td colspan="%s" class="plugin-update colspanchange">' . 656 '<div class="update-message notice inline notice-warning notice-alt"><p>', 657 $active, 658 esc_attr( $theme->get_stylesheet() . '-update' ), 659 esc_attr( $theme->get_stylesheet() ), 660 $wp_list_table->get_column_count() 661 ); 662 663 if ( $compatible_wp && $compatible_php ) { 664 if ( ! current_user_can( 'update_themes' ) ) { 665 printf( 666 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 667 __( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ), 668 $theme['Name'], 669 esc_url( $details_url ), 670 sprintf( 671 'class="thickbox open-plugin-details-modal" aria-label="%s"', 672 /* translators: 1: Theme name, 2: Version number. */ 673 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 674 ), 675 $response['new_version'] 676 ); 677 } elseif ( empty( $response['package'] ) ) { 678 printf( 679 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */ 680 __( '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>' ), 681 $theme['Name'], 682 esc_url( $details_url ), 683 sprintf( 684 'class="thickbox open-plugin-details-modal" aria-label="%s"', 685 /* translators: 1: Theme name, 2: Version number. */ 686 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 687 ), 688 $response['new_version'] 689 ); 690 } else { 691 printf( 692 /* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */ 693 __( '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>.' ), 694 $theme['Name'], 695 esc_url( $details_url ), 696 sprintf( 697 'class="thickbox open-plugin-details-modal" aria-label="%s"', 698 /* translators: 1: Theme name, 2: Version number. */ 699 esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) ) 700 ), 701 $response['new_version'], 702 wp_nonce_url( self_admin_url( 'update.php?action=upgrade-theme&theme=' ) . $theme_key, 'upgrade-theme_' . $theme_key ), 703 sprintf( 704 'class="update-link" aria-label="%s"', 705 /* translators: %s: Theme name. */ 706 esc_attr( sprintf( _x( 'Update %s now', 'theme' ), $theme['Name'] ) ) 707 ) 708 ); 709 } 710 } else { 711 if ( ! $compatible_wp && ! $compatible_php ) { 712 printf( 713 /* translators: %s: Theme name. */ 714 __( 'There is a new version of %s available, but it doesn’t work with your versions of WordPress and PHP.' ), 715 $theme['Name'] 716 ); 717 if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { 718 printf( 719 /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ 720 ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), 721 self_admin_url( 'update-core.php' ), 722 esc_url( wp_get_update_php_url() ) 723 ); 724 wp_update_php_annotation( '</p><p><em>', '</em>' ); 725 } elseif ( current_user_can( 'update_core' ) ) { 726 printf( 727 /* translators: %s: URL to WordPress Updates screen. */ 728 ' ' . __( '<a href="%s">Please update WordPress</a>.' ), 729 self_admin_url( 'update-core.php' ) 730 ); 731 } elseif ( current_user_can( 'update_php' ) ) { 732 printf( 733 /* translators: %s: URL to Update PHP page. */ 734 ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), 735 esc_url( wp_get_update_php_url() ) 736 ); 737 wp_update_php_annotation( '</p><p><em>', '</em>' ); 738 } 739 } elseif ( ! $compatible_wp ) { 740 printf( 741 /* translators: %s: Theme name. */ 742 __( 'There is a new version of %s available, but it doesn’t work with your version of WordPress.' ), 743 $theme['Name'] 744 ); 745 if ( current_user_can( 'update_core' ) ) { 746 printf( 747 /* translators: %s: URL to WordPress Updates screen. */ 748 ' ' . __( '<a href="%s">Please update WordPress</a>.' ), 749 self_admin_url( 'update-core.php' ) 750 ); 751 } 752 } elseif ( ! $compatible_php ) { 753 printf( 754 /* translators: %s: Theme name. */ 755 __( 'There is a new version of %s available, but it doesn’t work with your version of PHP.' ), 756 $theme['Name'] 757 ); 758 if ( current_user_can( 'update_php' ) ) { 759 printf( 760 /* translators: %s: URL to Update PHP page. */ 761 ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), 762 esc_url( wp_get_update_php_url() ) 763 ); 764 wp_update_php_annotation( '</p><p><em>', '</em>' ); 765 } 766 } 767 } 768 769 /** 770 * Fires at the end of the update message container in each 771 * row of the themes list table. 772 * 773 * The dynamic portion of the hook name, `$theme_key`, refers to 774 * the theme slug as found in the WordPress.org themes repository. 775 * 776 * @since 3.1.0 777 * 778 * @param WP_Theme $theme The WP_Theme object. 779 * @param array $response { 780 * An array of metadata about the available theme update. 781 * 782 * @type string $new_version New theme version. 783 * @type string $url Theme URL. 784 * @type string $package Theme update package URL. 785 * } 786 */ 787 do_action( "in_theme_update_message-{$theme_key}", $theme, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 788 789 echo '</p></div></td></tr>'; 790 } 791 792 /** 793 * @since 2.7.0 794 * 795 * @global int $upgrading 796 * @return void|false 797 */ 798 function maintenance_nag() { 799 // Include an unmodified $wp_version. 800 require ABSPATH . WPINC . '/version.php'; 801 global $upgrading; 802 $nag = isset( $upgrading ); 803 if ( ! $nag ) { 804 $failed = get_site_option( 'auto_core_update_failed' ); 805 /* 806 * If an update failed critically, we may have copied over version.php but not other files. 807 * In that case, if the installation claims we're running the version we attempted, nag. 808 * This is serious enough to err on the side of nagging. 809 * 810 * If we simply failed to update before we tried to copy any files, then assume things are 811 * OK if they are now running the latest. 812 * 813 * This flag is cleared whenever a successful update occurs using Core_Upgrader. 814 */ 815 $comparison = ! empty( $failed['critical'] ) ? '>=' : '>'; 816 if ( isset( $failed['attempted'] ) && version_compare( $failed['attempted'], $wp_version, $comparison ) ) { 817 $nag = true; 818 } 819 } 820 821 if ( ! $nag ) { 822 return false; 823 } 824 825 if ( current_user_can( 'update_core' ) ) { 826 $msg = sprintf( 827 /* translators: %s: URL to WordPress Updates screen. */ 828 __( 'An automated WordPress update has failed to complete - <a href="%s">please attempt the update again now</a>.' ), 829 'update-core.php' 830 ); 831 } else { 832 $msg = __( 'An automated WordPress update has failed to complete! Please notify the site administrator.' ); 833 } 834 835 echo "<div class='update-nag notice notice-warning inline'>$msg</div>"; 836 } 837 838 /** 839 * Prints the JavaScript templates for update admin notices. 840 * 841 * Template takes one argument with four values: 842 * 843 * param {object} data { 844 * Arguments for admin notice. 845 * 846 * @type string id ID of the notice. 847 * @type string className Class names for the notice. 848 * @type string message The notice's message. 849 * @type string type The type of update the notice is for. Either 'plugin' or 'theme'. 850 * } 851 * 852 * @since 4.6.0 853 */ 854 function wp_print_admin_notice_templates() { 855 ?> 856 <script id="tmpl-wp-updates-admin-notice" type="text/html"> 857 <div <# if ( data.id ) { #>id="{{ data.id }}"<# } #> class="notice {{ data.className }}"><p>{{{ data.message }}}</p></div> 858 </script> 859 <script id="tmpl-wp-bulk-updates-admin-notice" type="text/html"> 860 <div id="{{ data.id }}" class="{{ data.className }} notice <# if ( data.errors ) { #>notice-error<# } else { #>notice-success<# } #>"> 861 <p> 862 <# if ( data.successes ) { #> 863 <# if ( 1 === data.successes ) { #> 864 <# if ( 'plugin' === data.type ) { #> 865 <?php 866 /* translators: %s: Number of plugins. */ 867 printf( __( '%s plugin successfully updated.' ), '{{ data.successes }}' ); 868 ?> 869 <# } else { #> 870 <?php 871 /* translators: %s: Number of themes. */ 872 printf( __( '%s theme successfully updated.' ), '{{ data.successes }}' ); 873 ?> 874 <# } #> 875 <# } else { #> 876 <# if ( 'plugin' === data.type ) { #> 877 <?php 878 /* translators: %s: Number of plugins. */ 879 printf( __( '%s plugins successfully updated.' ), '{{ data.successes }}' ); 880 ?> 881 <# } else { #> 882 <?php 883 /* translators: %s: Number of themes. */ 884 printf( __( '%s themes successfully updated.' ), '{{ data.successes }}' ); 885 ?> 886 <# } #> 887 <# } #> 888 <# } #> 889 <# if ( data.errors ) { #> 890 <button class="button-link bulk-action-errors-collapsed" aria-expanded="false"> 891 <# if ( 1 === data.errors ) { #> 892 <?php 893 /* translators: %s: Number of failed updates. */ 894 printf( __( '%s update failed.' ), '{{ data.errors }}' ); 895 ?> 896 <# } else { #> 897 <?php 898 /* translators: %s: Number of failed updates. */ 899 printf( __( '%s updates failed.' ), '{{ data.errors }}' ); 900 ?> 901 <# } #> 902 <span class="screen-reader-text"><?php _e( 'Show more details' ); ?></span> 903 <span class="toggle-indicator" aria-hidden="true"></span> 904 </button> 905 <# } #> 906 </p> 907 <# if ( data.errors ) { #> 908 <ul class="bulk-action-errors hidden"> 909 <# _.each( data.errorMessages, function( errorMessage ) { #> 910 <li>{{ errorMessage }}</li> 911 <# } ); #> 912 </ul> 913 <# } #> 914 </div> 915 </script> 916 <?php 917 } 918 919 /** 920 * Prints the JavaScript templates for update and deletion rows in list tables. 921 * 922 * The update template takes one argument with four values: 923 * 924 * param {object} data { 925 * Arguments for the update row 926 * 927 * @type string slug Plugin slug. 928 * @type string plugin Plugin base name. 929 * @type string colspan The number of table columns this row spans. 930 * @type string content The row content. 931 * } 932 * 933 * The delete 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 name Plugin name. 941 * @type string colspan The number of table columns this row spans. 942 * } 943 * 944 * @since 4.6.0 945 */ 946 function wp_print_update_row_templates() { 947 ?> 948 <script id="tmpl-item-update-row" type="text/template"> 949 <tr class="plugin-update-tr update" id="{{ data.slug }}-update" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>> 950 <td colspan="{{ data.colspan }}" class="plugin-update colspanchange"> 951 {{{ data.content }}} 952 </td> 953 </tr> 954 </script> 955 <script id="tmpl-item-deleted-row" type="text/template"> 956 <tr class="plugin-deleted-tr inactive deleted" id="{{ data.slug }}-deleted" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>> 957 <td colspan="{{ data.colspan }}" class="plugin-update colspanchange"> 958 <# if ( data.plugin ) { #> 959 <?php 960 printf( 961 /* translators: %s: Plugin name. */ 962 _x( '%s was successfully deleted.', 'plugin' ), 963 '<strong>{{{ data.name }}}</strong>' 964 ); 965 ?> 966 <# } else { #> 967 <?php 968 printf( 969 /* translators: %s: Theme name. */ 970 _x( '%s was successfully deleted.', 'theme' ), 971 '<strong>{{{ data.name }}}</strong>' 972 ); 973 ?> 974 <# } #> 975 </td> 976 </tr> 977 </script> 978 <?php 979 } 980 981 /** 982 * Displays a notice when the user is in recovery mode. 983 * 984 * @since 5.2.0 985 */ 986 function wp_recovery_mode_nag() { 987 if ( ! wp_is_recovery_mode() ) { 988 return; 989 } 990 991 $url = wp_login_url(); 992 $url = add_query_arg( 'action', WP_Recovery_Mode::EXIT_ACTION, $url ); 993 $url = wp_nonce_url( $url, WP_Recovery_Mode::EXIT_ACTION ); 994 995 ?> 996 <div class="notice notice-info"> 997 <p> 998 <?php 999 printf( 1000 /* translators: %s: Recovery Mode exit link. */ 1001 __( '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>' ), 1002 esc_url( $url ) 1003 ); 1004 ?> 1005 </p> 1006 </div> 1007 <?php 1008 } 1009 1010 /** 1011 * Checks whether auto-updates are enabled. 1012 * 1013 * @since 5.5.0 1014 * 1015 * @param string $type The type of update being checked: 'theme' or 'plugin'. 1016 * @return bool True if auto-updates are enabled for `$type`, false otherwise. 1017 */ 1018 function wp_is_auto_update_enabled_for_type( $type ) { 1019 if ( ! class_exists( 'WP_Automatic_Updater' ) ) { 1020 require_once ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php'; 1021 } 1022 1023 $updater = new WP_Automatic_Updater(); 1024 $enabled = ! $updater->is_disabled(); 1025 1026 switch ( $type ) { 1027 case 'plugin': 1028 /** 1029 * Filters whether plugins auto-update is enabled. 1030 * 1031 * @since 5.5.0 1032 * 1033 * @param bool $enabled True if plugins auto-update is enabled, false otherwise. 1034 */ 1035 return apply_filters( 'plugins_auto_update_enabled', $enabled ); 1036 case 'theme': 1037 /** 1038 * Filters whether themes auto-update is enabled. 1039 * 1040 * @since 5.5.0 1041 * 1042 * @param bool $enabled True if themes auto-update is enabled, false otherwise. 1043 */ 1044 return apply_filters( 'themes_auto_update_enabled', $enabled ); 1045 } 1046 1047 return false; 1048 } 1049 1050 /** 1051 * Checks whether auto-updates are forced for an item. 1052 * 1053 * @since 5.6.0 1054 * 1055 * @param string $type The type of update being checked: 'theme' or 'plugin'. 1056 * @param bool|null $update Whether to update. The value of null is internally used 1057 * to detect whether nothing has hooked into this filter. 1058 * @param object $item The update offer. 1059 * @return bool True if auto-updates are forced for `$item`, false otherwise. 1060 */ 1061 function wp_is_auto_update_forced_for_item( $type, $update, $item ) { 1062 /** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */ 1063 return apply_filters( "auto_update_{$type}", $update, $item ); 1064 } 1065 1066 /** 1067 * Determines the appropriate auto-update message to be displayed. 1068 * 1069 * @since 5.5.0 1070 * 1071 * @return string The update message to be shown. 1072 */ 1073 function wp_get_auto_update_message() { 1074 $next_update_time = wp_next_scheduled( 'wp_version_check' ); 1075 1076 // Check if the event exists. 1077 if ( false === $next_update_time ) { 1078 $message = __( 'Automatic update not scheduled. There may be a problem with WP-Cron.' ); 1079 } else { 1080 $time_to_next_update = human_time_diff( (int) $next_update_time ); 1081 1082 // See if cron is overdue. 1083 $overdue = ( time() - $next_update_time ) > 0; 1084 1085 if ( $overdue ) { 1086 $message = sprintf( 1087 /* translators: %s: Duration that WP-Cron has been overdue. */ 1088 __( 'Automatic update overdue by %s. There may be a problem with WP-Cron.' ), 1089 $time_to_next_update 1090 ); 1091 } else { 1092 $message = sprintf( 1093 /* translators: %s: Time until the next update. */ 1094 __( 'Automatic update scheduled in %s.' ), 1095 $time_to_next_update 1096 ); 1097 } 1098 } 1099 1100 return $message; 1101 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Feb 25 01:00:09 2021 | Cross-referenced by PHPXref 0.7.1 |