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


Generated : Mon Jul 15 08:20:02 2024 Cross-referenced by PHPXref