[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/includes/ -> update.php (source)

   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&#8217;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 . '&section=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  }


Generated : Thu Apr 25 08:20:02 2024 Cross-referenced by PHPXref