[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/includes/ -> class-wp-ms-themes-list-table.php (source)

   1  <?php
   2  /**
   3   * List Table API: WP_MS_Themes_List_Table class
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   * @since 3.1.0
   8   */
   9  
  10  /**
  11   * Core class used to implement displaying themes in a list table for the network admin.
  12   *
  13   * @since 3.1.0
  14   * @access private
  15   *
  16   * @see WP_List_Table
  17   */
  18  class WP_MS_Themes_List_Table extends WP_List_Table {
  19  
  20      public $site_id;
  21      public $is_site_themes;
  22  
  23      private $has_items;
  24  
  25      /**
  26       * Whether to show the auto-updates UI.
  27       *
  28       * @since 5.5.0
  29       *
  30       * @var bool True if auto-updates UI is to be shown, false otherwise.
  31       */
  32      protected $show_autoupdates = true;
  33  
  34      /**
  35       * Constructor.
  36       *
  37       * @since 3.1.0
  38       *
  39       * @see WP_List_Table::__construct() for more information on default arguments.
  40       *
  41       * @global string $status
  42       * @global int    $page
  43       *
  44       * @param array $args An associative array of arguments.
  45       */
  46  	public function __construct( $args = array() ) {
  47          global $status, $page;
  48  
  49          parent::__construct(
  50              array(
  51                  'plural' => 'themes',
  52                  'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
  53              )
  54          );
  55  
  56          $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : 'all';
  57          if ( ! in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search', 'broken', 'auto-update-enabled', 'auto-update-disabled' ), true ) ) {
  58              $status = 'all';
  59          }
  60  
  61          $page = $this->get_pagenum();
  62  
  63          $this->is_site_themes = ( 'site-themes-network' === $this->screen->id ) ? true : false;
  64  
  65          if ( $this->is_site_themes ) {
  66              $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
  67          }
  68  
  69          $this->show_autoupdates = wp_is_auto_update_enabled_for_type( 'theme' ) &&
  70              ! $this->is_site_themes && current_user_can( 'update_themes' );
  71      }
  72  
  73      /**
  74       * @return array
  75       */
  76  	protected function get_table_classes() {
  77          // @todo Remove and add CSS for .themes.
  78          return array( 'widefat', 'plugins' );
  79      }
  80  
  81      /**
  82       * @return bool
  83       */
  84  	public function ajax_user_can() {
  85          if ( $this->is_site_themes ) {
  86              return current_user_can( 'manage_sites' );
  87          } else {
  88              return current_user_can( 'manage_network_themes' );
  89          }
  90      }
  91  
  92      /**
  93       * @global string $status
  94       * @global array $totals
  95       * @global int $page
  96       * @global string $orderby
  97       * @global string $order
  98       * @global string $s
  99       */
 100  	public function prepare_items() {
 101          global $status, $totals, $page, $orderby, $order, $s;
 102  
 103          wp_reset_vars( array( 'orderby', 'order', 's' ) );
 104  
 105          $themes = array(
 106              /**
 107               * Filters the full array of WP_Theme objects to list in the Multisite
 108               * themes list table.
 109               *
 110               * @since 3.1.0
 111               *
 112               * @param WP_Theme[] $all Array of WP_Theme objects to display in the list table.
 113               */
 114              'all'      => apply_filters( 'all_themes', wp_get_themes() ),
 115              'search'   => array(),
 116              'enabled'  => array(),
 117              'disabled' => array(),
 118              'upgrade'  => array(),
 119              'broken'   => $this->is_site_themes ? array() : wp_get_themes( array( 'errors' => true ) ),
 120          );
 121  
 122          if ( $this->show_autoupdates ) {
 123              $auto_updates = (array) get_site_option( 'auto_update_themes', array() );
 124  
 125              $themes['auto-update-enabled']  = array();
 126              $themes['auto-update-disabled'] = array();
 127          }
 128  
 129          if ( $this->is_site_themes ) {
 130              $themes_per_page = $this->get_items_per_page( 'site_themes_network_per_page' );
 131              $allowed_where   = 'site';
 132          } else {
 133              $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' );
 134              $allowed_where   = 'network';
 135          }
 136  
 137          $current      = get_site_transient( 'update_themes' );
 138          $maybe_update = current_user_can( 'update_themes' ) && ! $this->is_site_themes && $current;
 139  
 140          foreach ( (array) $themes['all'] as $key => $theme ) {
 141              if ( $this->is_site_themes && $theme->is_allowed( 'network' ) ) {
 142                  unset( $themes['all'][ $key ] );
 143                  continue;
 144              }
 145  
 146              if ( $maybe_update && isset( $current->response[ $key ] ) ) {
 147                  $themes['all'][ $key ]->update = true;
 148                  $themes['upgrade'][ $key ]     = $themes['all'][ $key ];
 149              }
 150  
 151              $filter                    = $theme->is_allowed( $allowed_where, $this->site_id ) ? 'enabled' : 'disabled';
 152              $themes[ $filter ][ $key ] = $themes['all'][ $key ];
 153  
 154              $theme_data = array(
 155                  'update_supported' => isset( $theme->update_supported ) ? $theme->update_supported : true,
 156              );
 157  
 158              // Extra info if known. array_merge() ensures $theme_data has precedence if keys collide.
 159              if ( isset( $current->response[ $key ] ) ) {
 160                  $theme_data = array_merge( (array) $current->response[ $key ], $theme_data );
 161              } elseif ( isset( $current->no_update[ $key ] ) ) {
 162                  $theme_data = array_merge( (array) $current->no_update[ $key ], $theme_data );
 163              } else {
 164                  $theme_data['update_supported'] = false;
 165              }
 166  
 167              $theme->update_supported = $theme_data['update_supported'];
 168  
 169              /*
 170               * Create the expected payload for the auto_update_theme filter, this is the same data
 171               * as contained within $updates or $no_updates but used when the Theme is not known.
 172               */
 173              $filter_payload = array(
 174                  'theme'        => $key,
 175                  'new_version'  => '',
 176                  'url'          => '',
 177                  'package'      => '',
 178                  'requires'     => '',
 179                  'requires_php' => '',
 180              );
 181  
 182              $filter_payload = array_merge( $filter_payload, array_intersect_key( $theme_data, $filter_payload ) );
 183  
 184              $type = 'theme';
 185              /** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
 186              $auto_update_forced = apply_filters( "auto_update_{$type}", null, (object) $filter_payload );
 187  
 188              if ( ! is_null( $auto_update_forced ) ) {
 189                  $theme->auto_update_forced = $auto_update_forced;
 190              }
 191  
 192              if ( $this->show_autoupdates ) {
 193                  $enabled = in_array( $key, $auto_updates, true ) && $theme->update_supported;
 194                  if ( isset( $theme->auto_update_forced ) ) {
 195                      $enabled = (bool) $theme->auto_update_forced;
 196                  }
 197  
 198                  if ( $enabled ) {
 199                      $themes['auto-update-enabled'][ $key ] = $theme;
 200                  } else {
 201                      $themes['auto-update-disabled'][ $key ] = $theme;
 202                  }
 203              }
 204          }
 205  
 206          if ( $s ) {
 207              $status           = 'search';
 208              $themes['search'] = array_filter( array_merge( $themes['all'], $themes['broken'] ), array( $this, '_search_callback' ) );
 209          }
 210  
 211          $totals = array();
 212          foreach ( $themes as $type => $list ) {
 213              $totals[ $type ] = count( $list );
 214          }
 215  
 216          if ( empty( $themes[ $status ] ) && ! in_array( $status, array( 'all', 'search' ), true ) ) {
 217              $status = 'all';
 218          }
 219  
 220          $this->items = $themes[ $status ];
 221          WP_Theme::sort_by_name( $this->items );
 222  
 223          $this->has_items = ! empty( $themes['all'] );
 224          $total_this_page = $totals[ $status ];
 225  
 226          wp_localize_script(
 227              'updates',
 228              '_wpUpdatesItemCounts',
 229              array(
 230                  'themes' => $totals,
 231                  'totals' => wp_get_update_data(),
 232              )
 233          );
 234  
 235          if ( $orderby ) {
 236              $orderby = ucfirst( $orderby );
 237              $order   = strtoupper( $order );
 238  
 239              if ( 'Name' === $orderby ) {
 240                  if ( 'ASC' === $order ) {
 241                      $this->items = array_reverse( $this->items );
 242                  }
 243              } else {
 244                  uasort( $this->items, array( $this, '_order_callback' ) );
 245              }
 246          }
 247  
 248          $start = ( $page - 1 ) * $themes_per_page;
 249  
 250          if ( $total_this_page > $themes_per_page ) {
 251              $this->items = array_slice( $this->items, $start, $themes_per_page, true );
 252          }
 253  
 254          $this->set_pagination_args(
 255              array(
 256                  'total_items' => $total_this_page,
 257                  'per_page'    => $themes_per_page,
 258              )
 259          );
 260      }
 261  
 262      /**
 263       * @param WP_Theme $theme
 264       * @return bool
 265       */
 266  	public function _search_callback( $theme ) {
 267          static $term = null;
 268          if ( is_null( $term ) ) {
 269              $term = wp_unslash( $_REQUEST['s'] );
 270          }
 271  
 272          foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) {
 273              // Don't mark up; Do translate.
 274              if ( false !== stripos( $theme->display( $field, false, true ), $term ) ) {
 275                  return true;
 276              }
 277          }
 278  
 279          if ( false !== stripos( $theme->get_stylesheet(), $term ) ) {
 280              return true;
 281          }
 282  
 283          if ( false !== stripos( $theme->get_template(), $term ) ) {
 284              return true;
 285          }
 286  
 287          return false;
 288      }
 289  
 290      // Not used by any core columns.
 291      /**
 292       * @global string $orderby
 293       * @global string $order
 294       * @param array $theme_a
 295       * @param array $theme_b
 296       * @return int
 297       */
 298  	public function _order_callback( $theme_a, $theme_b ) {
 299          global $orderby, $order;
 300  
 301          $a = $theme_a[ $orderby ];
 302          $b = $theme_b[ $orderby ];
 303  
 304          if ( $a === $b ) {
 305              return 0;
 306          }
 307  
 308          if ( 'DESC' === $order ) {
 309              return ( $a < $b ) ? 1 : -1;
 310          } else {
 311              return ( $a < $b ) ? -1 : 1;
 312          }
 313      }
 314  
 315      /**
 316       */
 317  	public function no_items() {
 318          if ( $this->has_items ) {
 319              _e( 'No themes found.' );
 320          } else {
 321              _e( 'No themes are currently available.' );
 322          }
 323      }
 324  
 325      /**
 326       * @return array
 327       */
 328  	public function get_columns() {
 329          $columns = array(
 330              'cb'          => '<input type="checkbox" />',
 331              'name'        => __( 'Theme' ),
 332              'description' => __( 'Description' ),
 333          );
 334  
 335          if ( $this->show_autoupdates ) {
 336              $columns['auto-updates'] = __( 'Automatic Updates' );
 337          }
 338  
 339          return $columns;
 340      }
 341  
 342      /**
 343       * @return array
 344       */
 345  	protected function get_sortable_columns() {
 346          return array(
 347              'name' => 'name',
 348          );
 349      }
 350  
 351      /**
 352       * Gets the name of the primary column.
 353       *
 354       * @since 4.3.0
 355       *
 356       * @return string Unalterable name of the primary column name, in this case, 'name'.
 357       */
 358  	protected function get_primary_column_name() {
 359          return 'name';
 360      }
 361  
 362      /**
 363       * @global array $totals
 364       * @global string $status
 365       * @return array
 366       */
 367  	protected function get_views() {
 368          global $totals, $status;
 369  
 370          $status_links = array();
 371          foreach ( $totals as $type => $count ) {
 372              if ( ! $count ) {
 373                  continue;
 374              }
 375  
 376              switch ( $type ) {
 377                  case 'all':
 378                      /* translators: %s: Number of themes. */
 379                      $text = _nx(
 380                          'All <span class="count">(%s)</span>',
 381                          'All <span class="count">(%s)</span>',
 382                          $count,
 383                          'themes'
 384                      );
 385                      break;
 386                  case 'enabled':
 387                      /* translators: %s: Number of themes. */
 388                      $text = _nx(
 389                          'Enabled <span class="count">(%s)</span>',
 390                          'Enabled <span class="count">(%s)</span>',
 391                          $count,
 392                          'themes'
 393                      );
 394                      break;
 395                  case 'disabled':
 396                      /* translators: %s: Number of themes. */
 397                      $text = _nx(
 398                          'Disabled <span class="count">(%s)</span>',
 399                          'Disabled <span class="count">(%s)</span>',
 400                          $count,
 401                          'themes'
 402                      );
 403                      break;
 404                  case 'upgrade':
 405                      /* translators: %s: Number of themes. */
 406                      $text = _nx(
 407                          'Update Available <span class="count">(%s)</span>',
 408                          'Update Available <span class="count">(%s)</span>',
 409                          $count,
 410                          'themes'
 411                      );
 412                      break;
 413                  case 'broken':
 414                      /* translators: %s: Number of themes. */
 415                      $text = _nx(
 416                          'Broken <span class="count">(%s)</span>',
 417                          'Broken <span class="count">(%s)</span>',
 418                          $count,
 419                          'themes'
 420                      );
 421                      break;
 422                  case 'auto-update-enabled':
 423                      /* translators: %s: Number of themes. */
 424                      $text = _n(
 425                          'Auto-updates Enabled <span class="count">(%s)</span>',
 426                          'Auto-updates Enabled <span class="count">(%s)</span>',
 427                          $count
 428                      );
 429                      break;
 430                  case 'auto-update-disabled':
 431                      /* translators: %s: Number of themes. */
 432                      $text = _n(
 433                          'Auto-updates Disabled <span class="count">(%s)</span>',
 434                          'Auto-updates Disabled <span class="count">(%s)</span>',
 435                          $count
 436                      );
 437                      break;
 438              }
 439  
 440              if ( $this->is_site_themes ) {
 441                  $url = 'site-themes.php?id=' . $this->site_id;
 442              } else {
 443                  $url = 'themes.php';
 444              }
 445  
 446              if ( 'search' !== $type ) {
 447                  $status_links[ $type ] = sprintf(
 448                      "<a href='%s'%s>%s</a>",
 449                      esc_url( add_query_arg( 'theme_status', $type, $url ) ),
 450                      ( $type === $status ) ? ' class="current" aria-current="page"' : '',
 451                      sprintf( $text, number_format_i18n( $count ) )
 452                  );
 453              }
 454          }
 455  
 456          return $status_links;
 457      }
 458  
 459      /**
 460       * @global string $status
 461       *
 462       * @return array
 463       */
 464  	protected function get_bulk_actions() {
 465          global $status;
 466  
 467          $actions = array();
 468          if ( 'enabled' !== $status ) {
 469              $actions['enable-selected'] = $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' );
 470          }
 471          if ( 'disabled' !== $status ) {
 472              $actions['disable-selected'] = $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' );
 473          }
 474          if ( ! $this->is_site_themes ) {
 475              if ( current_user_can( 'update_themes' ) ) {
 476                  $actions['update-selected'] = __( 'Update' );
 477              }
 478              if ( current_user_can( 'delete_themes' ) ) {
 479                  $actions['delete-selected'] = __( 'Delete' );
 480              }
 481          }
 482  
 483          if ( $this->show_autoupdates ) {
 484              if ( 'auto-update-enabled' !== $status ) {
 485                  $actions['enable-auto-update-selected'] = __( 'Enable Auto-updates' );
 486              }
 487  
 488              if ( 'auto-update-disabled' !== $status ) {
 489                  $actions['disable-auto-update-selected'] = __( 'Disable Auto-updates' );
 490              }
 491          }
 492  
 493          return $actions;
 494      }
 495  
 496      /**
 497       */
 498  	public function display_rows() {
 499          foreach ( $this->items as $theme ) {
 500              $this->single_row( $theme );
 501          }
 502      }
 503  
 504      /**
 505       * Handles the checkbox column output.
 506       *
 507       * @since 4.3.0
 508       *
 509       * @param WP_Theme $theme The current WP_Theme object.
 510       */
 511  	public function column_cb( $theme ) {
 512          $checkbox_id = 'checkbox_' . md5( $theme->get( 'Name' ) );
 513          ?>
 514          <input type="checkbox" name="checked[]" value="<?php echo esc_attr( $theme->get_stylesheet() ); ?>" id="<?php echo $checkbox_id; ?>" />
 515          <label class="screen-reader-text" for="<?php echo $checkbox_id; ?>" ><?php _e( 'Select' ); ?>  <?php echo $theme->display( 'Name' ); ?></label>
 516          <?php
 517      }
 518  
 519      /**
 520       * Handles the name column output.
 521       *
 522       * @since 4.3.0
 523       *
 524       * @global string $status
 525       * @global int    $page
 526       * @global string $s
 527       *
 528       * @param WP_Theme $theme The current WP_Theme object.
 529       */
 530  	public function column_name( $theme ) {
 531          global $status, $page, $s;
 532  
 533          $context = $status;
 534  
 535          if ( $this->is_site_themes ) {
 536              $url     = "site-themes.php?id={$this->site_id}&amp;";
 537              $allowed = $theme->is_allowed( 'site', $this->site_id );
 538          } else {
 539              $url     = 'themes.php?';
 540              $allowed = $theme->is_allowed( 'network' );
 541          }
 542  
 543          // Pre-order.
 544          $actions = array(
 545              'enable'  => '',
 546              'disable' => '',
 547              'delete'  => '',
 548          );
 549  
 550          $stylesheet = $theme->get_stylesheet();
 551          $theme_key  = urlencode( $stylesheet );
 552  
 553          if ( ! $allowed ) {
 554              if ( ! $theme->errors() ) {
 555                  $url = add_query_arg(
 556                      array(
 557                          'action' => 'enable',
 558                          'theme'  => $theme_key,
 559                          'paged'  => $page,
 560                          's'      => $s,
 561                      ),
 562                      $url
 563                  );
 564  
 565                  if ( $this->is_site_themes ) {
 566                      /* translators: %s: Theme name. */
 567                      $aria_label = sprintf( __( 'Enable %s' ), $theme->display( 'Name' ) );
 568                  } else {
 569                      /* translators: %s: Theme name. */
 570                      $aria_label = sprintf( __( 'Network Enable %s' ), $theme->display( 'Name' ) );
 571                  }
 572  
 573                  $actions['enable'] = sprintf(
 574                      '<a href="%s" class="edit" aria-label="%s">%s</a>',
 575                      esc_url( wp_nonce_url( $url, 'enable-theme_' . $stylesheet ) ),
 576                      esc_attr( $aria_label ),
 577                      ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) )
 578                  );
 579              }
 580          } else {
 581              $url = add_query_arg(
 582                  array(
 583                      'action' => 'disable',
 584                      'theme'  => $theme_key,
 585                      'paged'  => $page,
 586                      's'      => $s,
 587                  ),
 588                  $url
 589              );
 590  
 591              if ( $this->is_site_themes ) {
 592                  /* translators: %s: Theme name. */
 593                  $aria_label = sprintf( __( 'Disable %s' ), $theme->display( 'Name' ) );
 594              } else {
 595                  /* translators: %s: Theme name. */
 596                  $aria_label = sprintf( __( 'Network Disable %s' ), $theme->display( 'Name' ) );
 597              }
 598  
 599              $actions['disable'] = sprintf(
 600                  '<a href="%s" aria-label="%s">%s</a>',
 601                  esc_url( wp_nonce_url( $url, 'disable-theme_' . $stylesheet ) ),
 602                  esc_attr( $aria_label ),
 603                  ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) )
 604              );
 605          }
 606  
 607          if ( ! $allowed && ! $this->is_site_themes
 608              && current_user_can( 'delete_themes' )
 609              && get_option( 'stylesheet' ) !== $stylesheet
 610              && get_option( 'template' ) !== $stylesheet
 611          ) {
 612              $url = add_query_arg(
 613                  array(
 614                      'action'       => 'delete-selected',
 615                      'checked[]'    => $theme_key,
 616                      'theme_status' => $context,
 617                      'paged'        => $page,
 618                      's'            => $s,
 619                  ),
 620                  'themes.php'
 621              );
 622  
 623              /* translators: %s: Theme name. */
 624              $aria_label = sprintf( _x( 'Delete %s', 'theme' ), $theme->display( 'Name' ) );
 625  
 626              $actions['delete'] = sprintf(
 627                  '<a href="%s" class="delete" aria-label="%s">%s</a>',
 628                  esc_url( wp_nonce_url( $url, 'bulk-themes' ) ),
 629                  esc_attr( $aria_label ),
 630                  __( 'Delete' )
 631              );
 632          }
 633          /**
 634           * Filters the action links displayed for each theme in the Multisite
 635           * themes list table.
 636           *
 637           * The action links displayed are determined by the theme's status, and
 638           * which Multisite themes list table is being displayed - the Network
 639           * themes list table (themes.php), which displays all installed themes,
 640           * or the Site themes list table (site-themes.php), which displays the
 641           * non-network enabled themes when editing a site in the Network admin.
 642           *
 643           * The default action links for the Network themes list table include
 644           * 'Network Enable', 'Network Disable', and 'Delete'.
 645           *
 646           * The default action links for the Site themes list table include
 647           * 'Enable', and 'Disable'.
 648           *
 649           * @since 2.8.0
 650           *
 651           * @param string[] $actions An array of action links.
 652           * @param WP_Theme $theme   The current WP_Theme object.
 653           * @param string   $context Status of the theme, one of 'all', 'enabled', or 'disabled'.
 654           */
 655          $actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme, $context );
 656  
 657          /**
 658           * Filters the action links of a specific theme in the Multisite themes
 659           * list table.
 660           *
 661           * The dynamic portion of the hook name, `$stylesheet`, refers to the
 662           * directory name of the theme, which in most cases is synonymous
 663           * with the template name.
 664           *
 665           * @since 3.1.0
 666           *
 667           * @param string[] $actions An array of action links.
 668           * @param WP_Theme $theme   The current WP_Theme object.
 669           * @param string   $context Status of the theme, one of 'all', 'enabled', or 'disabled'.
 670           */
 671          $actions = apply_filters( "theme_action_links_{$stylesheet}", $actions, $theme, $context );
 672  
 673          echo $this->row_actions( $actions, true );
 674      }
 675  
 676      /**
 677       * Handles the description column output.
 678       *
 679       * @since 4.3.0
 680       *
 681       * @global string $status
 682       * @global array  $totals
 683       *
 684       * @param WP_Theme $theme The current WP_Theme object.
 685       */
 686  	public function column_description( $theme ) {
 687          global $status, $totals;
 688  
 689          if ( $theme->errors() ) {
 690              $pre = 'broken' === $status ? __( 'Broken Theme:' ) . ' ' : '';
 691              echo '<p><strong class="error-message">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
 692          }
 693  
 694          if ( $this->is_site_themes ) {
 695              $allowed = $theme->is_allowed( 'site', $this->site_id );
 696          } else {
 697              $allowed = $theme->is_allowed( 'network' );
 698          }
 699  
 700          $class = ! $allowed ? 'inactive' : 'active';
 701          if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) ) {
 702              $class .= ' update';
 703          }
 704  
 705          echo "<div class='theme-description'><p>" . $theme->display( 'Description' ) . "</p></div>
 706              <div class='$class second theme-version-author-uri'>";
 707  
 708          $stylesheet = $theme->get_stylesheet();
 709          $theme_meta = array();
 710  
 711          if ( $theme->get( 'Version' ) ) {
 712              /* translators: %s: Theme version. */
 713              $theme_meta[] = sprintf( __( 'Version %s' ), $theme->display( 'Version' ) );
 714          }
 715  
 716          /* translators: %s: Theme author. */
 717          $theme_meta[] = sprintf( __( 'By %s' ), $theme->display( 'Author' ) );
 718  
 719          if ( $theme->get( 'ThemeURI' ) ) {
 720              /* translators: %s: Theme name. */
 721              $aria_label = sprintf( __( 'Visit %s homepage' ), $theme->display( 'Name' ) );
 722  
 723              $theme_meta[] = sprintf(
 724                  '<a href="%s" aria-label="%s">%s</a>',
 725                  $theme->display( 'ThemeURI' ),
 726                  esc_attr( $aria_label ),
 727                  __( 'Visit Theme Site' )
 728              );
 729          }
 730  
 731          /**
 732           * Filters the array of row meta for each theme in the Multisite themes
 733           * list table.
 734           *
 735           * @since 3.1.0
 736           *
 737           * @param string[] $theme_meta An array of the theme's metadata, including
 738           *                             the version, author, and theme URI.
 739           * @param string   $stylesheet Directory name of the theme.
 740           * @param WP_Theme $theme      WP_Theme object.
 741           * @param string   $status     Status of the theme.
 742           */
 743          $theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $stylesheet, $theme, $status );
 744  
 745          echo implode( ' | ', $theme_meta );
 746  
 747          echo '</div>';
 748      }
 749  
 750      /**
 751       * Handles the auto-updates column output.
 752       *
 753       * @since 5.5.0
 754       *
 755       * @global string $status
 756       * @global int  $page
 757       *
 758       * @param WP_Theme $theme The current WP_Theme object.
 759       */
 760  	public function column_autoupdates( $theme ) {
 761          global $status, $page;
 762  
 763          static $auto_updates, $available_updates;
 764  
 765          if ( ! $auto_updates ) {
 766              $auto_updates = (array) get_site_option( 'auto_update_themes', array() );
 767          }
 768          if ( ! $available_updates ) {
 769              $available_updates = get_site_transient( 'update_themes' );
 770          }
 771  
 772          $stylesheet = $theme->get_stylesheet();
 773  
 774          if ( isset( $theme->auto_update_forced ) ) {
 775              if ( $theme->auto_update_forced ) {
 776                  // Forced on.
 777                  $text = __( 'Auto-updates enabled' );
 778              } else {
 779                  $text = __( 'Auto-updates disabled' );
 780              }
 781              $action     = 'unavailable';
 782              $time_class = ' hidden';
 783          } elseif ( empty( $theme->update_supported ) ) {
 784              $text       = '';
 785              $action     = 'unavailable';
 786              $time_class = ' hidden';
 787          } elseif ( in_array( $stylesheet, $auto_updates, true ) ) {
 788              $text       = __( 'Disable auto-updates' );
 789              $action     = 'disable';
 790              $time_class = '';
 791          } else {
 792              $text       = __( 'Enable auto-updates' );
 793              $action     = 'enable';
 794              $time_class = ' hidden';
 795          }
 796  
 797          $query_args = array(
 798              'action'       => "{$action}-auto-update",
 799              'theme'        => $stylesheet,
 800              'paged'        => $page,
 801              'theme_status' => $status,
 802          );
 803  
 804          $url = add_query_arg( $query_args, 'themes.php' );
 805  
 806          if ( 'unavailable' === $action ) {
 807              $html[] = '<span class="label">' . $text . '</span>';
 808          } else {
 809              $html[] = sprintf(
 810                  '<a href="%s" class="toggle-auto-update aria-button-if-js" data-wp-action="%s">',
 811                  wp_nonce_url( $url, 'updates' ),
 812                  $action
 813              );
 814  
 815              $html[] = '<span class="dashicons dashicons-update spin hidden" aria-hidden="true"></span>';
 816              $html[] = '<span class="label">' . $text . '</span>';
 817              $html[] = '</a>';
 818  
 819          }
 820  
 821          if ( isset( $available_updates->response[ $stylesheet ] ) ) {
 822              $html[] = sprintf(
 823                  '<div class="auto-update-time%s">%s</div>',
 824                  $time_class,
 825                  wp_get_auto_update_message()
 826              );
 827          }
 828  
 829          $html = implode( '', $html );
 830  
 831          /**
 832           * Filters the HTML of the auto-updates setting for each theme in the Themes list table.
 833           *
 834           * @since 5.5.0
 835           *
 836           * @param string   $html       The HTML for theme's auto-update setting, including
 837           *                             toggle auto-update action link and time to next update.
 838           * @param string   $stylesheet Directory name of the theme.
 839           * @param WP_Theme $theme      WP_Theme object.
 840           */
 841          echo apply_filters( 'theme_auto_update_setting_html', $html, $stylesheet, $theme );
 842  
 843          echo '<div class="notice notice-error notice-alt inline hidden"><p></p></div>';
 844      }
 845  
 846      /**
 847       * Handles default column output.
 848       *
 849       * @since 4.3.0
 850       *
 851       * @param WP_Theme $theme       The current WP_Theme object.
 852       * @param string   $column_name The current column name.
 853       */
 854  	public function column_default( $theme, $column_name ) {
 855          $stylesheet = $theme->get_stylesheet();
 856  
 857          /**
 858           * Fires inside each custom column of the Multisite themes list table.
 859           *
 860           * @since 3.1.0
 861           *
 862           * @param string   $column_name Name of the column.
 863           * @param string   $stylesheet  Directory name of the theme.
 864           * @param WP_Theme $theme       Current WP_Theme object.
 865           */
 866          do_action( 'manage_themes_custom_column', $column_name, $stylesheet, $theme );
 867      }
 868  
 869      /**
 870       * Handles the output for a single table row.
 871       *
 872       * @since 4.3.0
 873       *
 874       * @param WP_Theme $item The current WP_Theme object.
 875       */
 876  	public function single_row_columns( $item ) {
 877          list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
 878  
 879          foreach ( $columns as $column_name => $column_display_name ) {
 880              $extra_classes = '';
 881              if ( in_array( $column_name, $hidden, true ) ) {
 882                  $extra_classes .= ' hidden';
 883              }
 884  
 885              switch ( $column_name ) {
 886                  case 'cb':
 887                      echo '<th scope="row" class="check-column">';
 888  
 889                      $this->column_cb( $item );
 890  
 891                      echo '</th>';
 892                      break;
 893  
 894                  case 'name':
 895                      $active_theme_label = '';
 896  
 897                      /* The presence of the site_id property means that this is a subsite view and a label for the active theme needs to be added */
 898                      if ( ! empty( $this->site_id ) ) {
 899                          $stylesheet = get_blog_option( $this->site_id, 'stylesheet' );
 900                          $template   = get_blog_option( $this->site_id, 'template' );
 901  
 902                          /* Add a label for the active template */
 903                          if ( $item->get_template() === $template ) {
 904                              $active_theme_label = ' &mdash; ' . __( 'Active Theme' );
 905                          }
 906  
 907                          /* In case this is a child theme, label it properly */
 908                          if ( $stylesheet !== $template && $item->get_stylesheet() === $stylesheet ) {
 909                              $active_theme_label = ' &mdash; ' . __( 'Active Child Theme' );
 910                          }
 911                      }
 912  
 913                      echo "<td class='theme-title column-primary{$extra_classes}'><strong>" . $item->display( 'Name' ) . $active_theme_label . '</strong>';
 914  
 915                      $this->column_name( $item );
 916  
 917                      echo '</td>';
 918                      break;
 919  
 920                  case 'description':
 921                      echo "<td class='column-description desc{$extra_classes}'>";
 922  
 923                      $this->column_description( $item );
 924  
 925                      echo '</td>';
 926                      break;
 927  
 928                  case 'auto-updates':
 929                      echo "<td class='column-auto-updates{$extra_classes}'>";
 930  
 931                      $this->column_autoupdates( $item );
 932  
 933                      echo '</td>';
 934                      break;
 935                  default:
 936                      echo "<td class='$column_name column-$column_name{$extra_classes}'>";
 937  
 938                      $this->column_default( $item, $column_name );
 939  
 940                      echo '</td>';
 941                      break;
 942              }
 943          }
 944      }
 945  
 946      /**
 947       * @global string $status
 948       * @global array  $totals
 949       *
 950       * @param WP_Theme $theme
 951       */
 952  	public function single_row( $theme ) {
 953          global $status, $totals;
 954  
 955          if ( $this->is_site_themes ) {
 956              $allowed = $theme->is_allowed( 'site', $this->site_id );
 957          } else {
 958              $allowed = $theme->is_allowed( 'network' );
 959          }
 960  
 961          $stylesheet = $theme->get_stylesheet();
 962  
 963          $class = ! $allowed ? 'inactive' : 'active';
 964          if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) ) {
 965              $class .= ' update';
 966          }
 967  
 968          printf(
 969              '<tr class="%s" data-slug="%s">',
 970              esc_attr( $class ),
 971              esc_attr( $stylesheet )
 972          );
 973  
 974          $this->single_row_columns( $theme );
 975  
 976          echo '</tr>';
 977  
 978          if ( $this->is_site_themes ) {
 979              remove_action( "after_theme_row_$stylesheet", 'wp_theme_update_row' );
 980          }
 981  
 982          /**
 983           * Fires after each row in the Multisite themes list table.
 984           *
 985           * @since 3.1.0
 986           *
 987           * @param string   $stylesheet Directory name of the theme.
 988           * @param WP_Theme $theme      Current WP_Theme object.
 989           * @param string   $status     Status of the theme.
 990           */
 991          do_action( 'after_theme_row', $stylesheet, $theme, $status );
 992  
 993          /**
 994           * Fires after each specific row in the Multisite themes list table.
 995           *
 996           * The dynamic portion of the hook name, `$stylesheet`, refers to the
 997           * directory name of the theme, most often synonymous with the template
 998           * name of the theme.
 999           *
1000           * @since 3.5.0
1001           *
1002           * @param string   $stylesheet Directory name of the theme.
1003           * @param WP_Theme $theme      Current WP_Theme object.
1004           * @param string   $status     Status of the theme.
1005           */
1006          do_action( "after_theme_row_{$stylesheet}", $stylesheet, $theme, $status );
1007      }
1008  }


Generated: Sun Sep 20 01:00:03 2020 Cross-referenced by PHPXref 0.7.1