wp/wp-admin/includes/class-wp-ms-themes-list-table.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 <?php
     1 <?php
     2 /**
     2 /**
     3  * MS Themes List Table class.
     3  * List Table API: WP_MS_Themes_List_Table class
     4  *
     4  *
     5  * @package WordPress
     5  * @package WordPress
     6  * @subpackage List_Table
     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  *
     7  * @since 3.1.0
    13  * @since 3.1.0
     8  * @access private
    14  * @access private
       
    15  *
       
    16  * @see WP_List_Table
     9  */
    17  */
    10 class WP_MS_Themes_List_Table extends WP_List_Table {
    18 class WP_MS_Themes_List_Table extends WP_List_Table {
    11 
    19 
    12 	public $site_id;
    20 	public $site_id;
    13 	public $is_site_themes;
    21 	public $is_site_themes;
    16 
    24 
    17 	/**
    25 	/**
    18 	 * Constructor.
    26 	 * Constructor.
    19 	 *
    27 	 *
    20 	 * @since 3.1.0
    28 	 * @since 3.1.0
    21 	 * @access public
       
    22 	 *
    29 	 *
    23 	 * @see WP_List_Table::__construct() for more information on default arguments.
    30 	 * @see WP_List_Table::__construct() for more information on default arguments.
       
    31 	 *
       
    32 	 * @global string $status
       
    33 	 * @global int    $page
    24 	 *
    34 	 *
    25 	 * @param array $args An associative array of arguments.
    35 	 * @param array $args An associative array of arguments.
    26 	 */
    36 	 */
    27 	public function __construct( $args = array() ) {
    37 	public function __construct( $args = array() ) {
    28 		global $status, $page;
    38 		global $status, $page;
    36 		if ( !in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search', 'broken' ) ) )
    46 		if ( !in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search', 'broken' ) ) )
    37 			$status = 'all';
    47 			$status = 'all';
    38 
    48 
    39 		$page = $this->get_pagenum();
    49 		$page = $this->get_pagenum();
    40 
    50 
    41 		$this->is_site_themes = ( 'site-themes-network' == $this->screen->id ) ? true : false;
    51 		$this->is_site_themes = ( 'site-themes-network' === $this->screen->id ) ? true : false;
    42 
    52 
    43 		if ( $this->is_site_themes )
    53 		if ( $this->is_site_themes )
    44 			$this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
    54 			$this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
    45 	}
    55 	}
    46 
    56 
       
    57 	/**
       
    58 	 *
       
    59 	 * @return array
       
    60 	 */
    47 	protected function get_table_classes() {
    61 	protected function get_table_classes() {
    48 		// todo: remove and add CSS for .themes
    62 		// todo: remove and add CSS for .themes
    49 		return array( 'widefat', 'plugins' );
    63 		return array( 'widefat', 'plugins' );
    50 	}
    64 	}
    51 
    65 
       
    66 	/**
       
    67 	 *
       
    68 	 * @return bool
       
    69 	 */
    52 	public function ajax_user_can() {
    70 	public function ajax_user_can() {
    53 		if ( $this->is_site_themes )
    71 		if ( $this->is_site_themes )
    54 			return current_user_can( 'manage_sites' );
    72 			return current_user_can( 'manage_sites' );
    55 		else
    73 		else
    56 			return current_user_can( 'manage_network_themes' );
    74 			return current_user_can( 'manage_network_themes' );
    57 	}
    75 	}
    58 
    76 
       
    77 	/**
       
    78 	 *
       
    79 	 * @global string $status
       
    80 	 * @global array $totals
       
    81 	 * @global int $page
       
    82 	 * @global string $orderby
       
    83 	 * @global string $order
       
    84 	 * @global string $s
       
    85 	 */
    59 	public function prepare_items() {
    86 	public function prepare_items() {
    60 		global $status, $totals, $page, $orderby, $order, $s;
    87 		global $status, $totals, $page, $orderby, $order, $s;
    61 
    88 
    62 		wp_reset_vars( array( 'orderby', 'order', 's' ) );
    89 		wp_reset_vars( array( 'orderby', 'order', 's' ) );
    63 
    90 
    64 		$themes = array(
    91 		$themes = array(
    65 			/**
    92 			/**
    66 			 * Filter the full array of WP_Theme objects to list in the Multisite
    93 			 * Filters the full array of WP_Theme objects to list in the Multisite
    67 			 * themes list table.
    94 			 * themes list table.
    68 			 *
    95 			 *
    69 			 * @since 3.1.0
    96 			 * @since 3.1.0
    70 			 *
    97 			 *
    71 			 * @param array $all An array of WP_Theme objects to display in the list table.
    98 			 * @param array $all An array of WP_Theme objects to display in the list table.
   119 		WP_Theme::sort_by_name( $this->items );
   146 		WP_Theme::sort_by_name( $this->items );
   120 
   147 
   121 		$this->has_items = ! empty( $themes['all'] );
   148 		$this->has_items = ! empty( $themes['all'] );
   122 		$total_this_page = $totals[ $status ];
   149 		$total_this_page = $totals[ $status ];
   123 
   150 
       
   151 		wp_localize_script( 'updates', '_wpUpdatesItemCounts', array(
       
   152 			'themes' => $totals,
       
   153 			'totals' => wp_get_update_data(),
       
   154 		) );
       
   155 
   124 		if ( $orderby ) {
   156 		if ( $orderby ) {
   125 			$orderby = ucfirst( $orderby );
   157 			$orderby = ucfirst( $orderby );
   126 			$order = strtoupper( $order );
   158 			$order = strtoupper( $order );
   127 
   159 
   128 			if ( $orderby == 'Name' ) {
   160 			if ( $orderby === 'Name' ) {
   129 				if ( 'ASC' == $order )
   161 				if ( 'ASC' === $order ) {
   130 					$this->items = array_reverse( $this->items );
   162 					$this->items = array_reverse( $this->items );
       
   163 				}
   131 			} else {
   164 			} else {
   132 				uasort( $this->items, array( $this, '_order_callback' ) );
   165 				uasort( $this->items, array( $this, '_order_callback' ) );
   133 			}
   166 			}
   134 		}
   167 		}
   135 
   168 
   148 	 * @staticvar string $term
   181 	 * @staticvar string $term
   149 	 * @param WP_Theme $theme
   182 	 * @param WP_Theme $theme
   150 	 * @return bool
   183 	 * @return bool
   151 	 */
   184 	 */
   152 	public function _search_callback( $theme ) {
   185 	public function _search_callback( $theme ) {
   153 		static $term;
   186 		static $term = null;
   154 		if ( is_null( $term ) )
   187 		if ( is_null( $term ) )
   155 			$term = wp_unslash( $_REQUEST['s'] );
   188 			$term = wp_unslash( $_REQUEST['s'] );
   156 
   189 
   157 		foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) {
   190 		foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) {
   158 			// Don't mark up; Do translate.
   191 			// Don't mark up; Do translate.
   184 		$b = $theme_b[ $orderby ];
   217 		$b = $theme_b[ $orderby ];
   185 
   218 
   186 		if ( $a == $b )
   219 		if ( $a == $b )
   187 			return 0;
   220 			return 0;
   188 
   221 
   189 		if ( 'DESC' == $order )
   222 		if ( 'DESC' === $order )
   190 			return ( $a < $b ) ? 1 : -1;
   223 			return ( $a < $b ) ? 1 : -1;
   191 		else
   224 		else
   192 			return ( $a < $b ) ? -1 : 1;
   225 			return ( $a < $b ) ? -1 : 1;
   193 	}
   226 	}
   194 
   227 
       
   228 	/**
       
   229 	 */
   195 	public function no_items() {
   230 	public function no_items() {
   196 		if ( ! $this->has_items )
   231 		if ( $this->has_items ) {
   197 			_e( 'No themes found.' );
   232 			_e( 'No themes found.' );
   198 		else
   233 		} else {
   199 			_e( 'You do not appear to have any themes available at this time.' );
   234 			_e( 'You do not appear to have any themes available at this time.' );
   200 	}
   235 		}
   201 
   236 	}
       
   237 
       
   238 	/**
       
   239 	 *
       
   240 	 * @return array
       
   241 	 */
   202 	public function get_columns() {
   242 	public function get_columns() {
   203 		global $status;
       
   204 
       
   205 		return array(
   243 		return array(
   206 			'cb'          => '<input type="checkbox" />',
   244 			'cb'          => '<input type="checkbox" />',
   207 			'name'        => __( 'Theme' ),
   245 			'name'        => __( 'Theme' ),
   208 			'description' => __( 'Description' ),
   246 			'description' => __( 'Description' ),
   209 		);
   247 		);
   210 	}
   248 	}
   211 
   249 
       
   250 	/**
       
   251 	 *
       
   252 	 * @return array
       
   253 	 */
   212 	protected function get_sortable_columns() {
   254 	protected function get_sortable_columns() {
   213 		return array(
   255 		return array(
   214 			'name'         => 'name',
   256 			'name'         => 'name',
   215 		);
   257 		);
   216 	}
   258 	}
   217 
   259 
       
   260 	/**
       
   261 	 * Gets the name of the primary column.
       
   262 	 *
       
   263 	 * @since 4.3.0
       
   264 	 *
       
   265 	 * @return string Unalterable name of the primary column name, in this case, 'name'.
       
   266 	 */
       
   267 	protected function get_primary_column_name() {
       
   268 		return 'name';
       
   269 	}
       
   270 
       
   271 	/**
       
   272 	 *
       
   273 	 * @global array $totals
       
   274 	 * @global string $status
       
   275 	 * @return array
       
   276 	 */
   218 	protected function get_views() {
   277 	protected function get_views() {
   219 		global $totals, $status;
   278 		global $totals, $status;
   220 
   279 
   221 		$status_links = array();
   280 		$status_links = array();
   222 		foreach ( $totals as $type => $count ) {
   281 		foreach ( $totals as $type => $count ) {
   245 				$url = 'site-themes.php?id=' . $this->site_id;
   304 				$url = 'site-themes.php?id=' . $this->site_id;
   246 			else
   305 			else
   247 				$url = 'themes.php';
   306 				$url = 'themes.php';
   248 
   307 
   249 			if ( 'search' != $type ) {
   308 			if ( 'search' != $type ) {
   250 				$status_links[$type] = sprintf( "<a href='%s' %s>%s</a>",
   309 				$status_links[$type] = sprintf( "<a href='%s'%s>%s</a>",
   251 					esc_url( add_query_arg('theme_status', $type, $url) ),
   310 					esc_url( add_query_arg('theme_status', $type, $url) ),
   252 					( $type == $status ) ? ' class="current"' : '',
   311 					( $type === $status ) ? ' class="current" aria-current="page"' : '',
   253 					sprintf( $text, number_format_i18n( $count ) )
   312 					sprintf( $text, number_format_i18n( $count ) )
   254 				);
   313 				);
   255 			}
   314 			}
   256 		}
   315 		}
   257 
   316 
   258 		return $status_links;
   317 		return $status_links;
   259 	}
   318 	}
   260 
   319 
       
   320 	/**
       
   321 	 * @global string $status
       
   322 	 *
       
   323 	 * @return array
       
   324 	 */
   261 	protected function get_bulk_actions() {
   325 	protected function get_bulk_actions() {
   262 		global $status;
   326 		global $status;
   263 
   327 
   264 		$actions = array();
   328 		$actions = array();
   265 		if ( 'enabled' != $status )
   329 		if ( 'enabled' != $status )
   273 				$actions['delete-selected'] = __( 'Delete' );
   337 				$actions['delete-selected'] = __( 'Delete' );
   274 		}
   338 		}
   275 		return $actions;
   339 		return $actions;
   276 	}
   340 	}
   277 
   341 
       
   342 	/**
       
   343 	 */
   278 	public function display_rows() {
   344 	public function display_rows() {
   279 		foreach ( $this->items as $theme )
   345 		foreach ( $this->items as $theme )
   280 			$this->single_row( $theme );
   346 			$this->single_row( $theme );
   281 	}
   347 	}
   282 
   348 
   283 	/**
   349 	/**
       
   350 	 * Handles the checkbox column output.
       
   351 	 *
       
   352 	 * @since 4.3.0
       
   353 	 *
       
   354 	 * @param WP_Theme $theme The current WP_Theme object.
       
   355 	 */
       
   356 	public function column_cb( $theme ) {
       
   357 		$checkbox_id = 'checkbox_' . md5( $theme->get('Name') );
       
   358 		?>
       
   359 		<input type="checkbox" name="checked[]" value="<?php echo esc_attr( $theme->get_stylesheet() ) ?>" id="<?php echo $checkbox_id ?>" />
       
   360 		<label class="screen-reader-text" for="<?php echo $checkbox_id ?>" ><?php _e( 'Select' ) ?>  <?php echo $theme->display( 'Name' ) ?></label>
       
   361 		<?php
       
   362 	}
       
   363 
       
   364 	/**
       
   365 	 * Handles the name column output.
       
   366 	 *
       
   367 	 * @since 4.3.0
       
   368 	 *
   284 	 * @global string $status
   369 	 * @global string $status
   285 	 * @global int $page
   370 	 * @global int    $page
   286 	 * @global string $s
   371 	 * @global string $s
   287 	 * @global array $totals
   372 	 *
   288 	 * @param WP_Theme $theme
   373 	 * @param WP_Theme $theme The current WP_Theme object.
   289 	 */
   374 	 */
   290 	public function single_row( $theme ) {
   375 	public function column_name( $theme ) {
   291 		global $status, $page, $s, $totals;
   376 		global $status, $page, $s;
   292 
   377 
   293 		$context = $status;
   378 		$context = $status;
   294 
   379 
   295 		if ( $this->is_site_themes ) {
   380 		if ( $this->is_site_themes ) {
   296 			$url = "site-themes.php?id={$this->site_id}&amp;";
   381 			$url = "site-themes.php?id={$this->site_id}&amp;";
   302 
   387 
   303 		// Pre-order.
   388 		// Pre-order.
   304 		$actions = array(
   389 		$actions = array(
   305 			'enable' => '',
   390 			'enable' => '',
   306 			'disable' => '',
   391 			'disable' => '',
   307 			'edit' => '',
       
   308 			'delete' => ''
   392 			'delete' => ''
   309 		);
   393 		);
   310 
   394 
   311 		$stylesheet = $theme->get_stylesheet();
   395 		$stylesheet = $theme->get_stylesheet();
   312 		$theme_key = urlencode( $stylesheet );
   396 		$theme_key = urlencode( $stylesheet );
   313 
   397 
   314 		if ( ! $allowed ) {
   398 		if ( ! $allowed ) {
   315 			if ( ! $theme->errors() )
   399 			if ( ! $theme->errors() ) {
   316 				$actions['enable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=enable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'enable-theme_' . $stylesheet ) ) . '" title="' . esc_attr__('Enable this theme') . '" class="edit">' . ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) ) . '</a>';
   400 				$url = add_query_arg( array(
       
   401 					'action' => 'enable',
       
   402 					'theme'  => $theme_key,
       
   403 					'paged'  => $page,
       
   404 					's'      => $s,
       
   405 				), $url );
       
   406 
       
   407 				if ( $this->is_site_themes ) {
       
   408 					/* translators: %s: theme name */
       
   409 					$aria_label = sprintf( __( 'Enable %s' ), $theme->display( 'Name' ) );
       
   410 				} else {
       
   411 					/* translators: %s: theme name */
       
   412 					$aria_label = sprintf( __( 'Network Enable %s' ), $theme->display( 'Name' ) );
       
   413 				}
       
   414 
       
   415 				$actions['enable'] = sprintf( '<a href="%s" class="edit" aria-label="%s">%s</a>',
       
   416 					esc_url( wp_nonce_url( $url, 'enable-theme_' . $stylesheet ) ),
       
   417 					esc_attr( $aria_label ),
       
   418 					( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) )
       
   419 				);
       
   420 			}
   317 		} else {
   421 		} else {
   318 			$actions['disable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=disable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'disable-theme_' . $stylesheet ) ) . '" title="' . esc_attr__('Disable this theme') . '">' . ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) ) . '</a>';
   422 			$url = add_query_arg( array(
   319 		}
   423 				'action' => 'disable',
   320 
   424 				'theme'  => $theme_key,
   321 		if ( current_user_can('edit_themes') )
   425 				'paged'  => $page,
   322 			$actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' . $theme_key ) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>';
   426 				's'      => $s,
   323 
   427 			), $url );
   324 		if ( ! $allowed && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $stylesheet != get_option( 'stylesheet' ) && $stylesheet != get_option( 'template' ) )
   428 
   325 			$actions['delete'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=delete-selected&amp;checked[]=' . $theme_key . '&amp;theme_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-themes' ) ) . '" title="' . esc_attr__( 'Delete this theme' ) . '" class="delete">' . __( 'Delete' ) . '</a>';
   429 			if ( $this->is_site_themes ) {
   326 
   430 				/* translators: %s: theme name */
       
   431 				$aria_label = sprintf( __( 'Disable %s' ), $theme->display( 'Name' ) );
       
   432 			} else {
       
   433 				/* translators: %s: theme name */
       
   434 				$aria_label = sprintf( __( 'Network Disable %s' ), $theme->display( 'Name' ) );
       
   435 			}
       
   436 
       
   437 			$actions['disable'] = sprintf( '<a href="%s" aria-label="%s">%s</a>',
       
   438 				esc_url( wp_nonce_url( $url, 'disable-theme_' . $stylesheet ) ),
       
   439 				esc_attr( $aria_label ),
       
   440 				( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) )
       
   441 			);
       
   442 		}
       
   443 
       
   444 		if ( ! $allowed && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $stylesheet != get_option( 'stylesheet' ) && $stylesheet != get_option( 'template' ) ) {
       
   445 			$url = add_query_arg( array(
       
   446 				'action'       => 'delete-selected',
       
   447 				'checked[]'    => $theme_key,
       
   448 				'theme_status' => $context,
       
   449 				'paged'        => $page,
       
   450 				's'            => $s,
       
   451 			), 'themes.php' );
       
   452 
       
   453 			/* translators: %s: theme name */
       
   454 			$aria_label = sprintf( _x( 'Delete %s', 'theme' ), $theme->display( 'Name' ) );
       
   455 
       
   456 			$actions['delete'] = sprintf( '<a href="%s" class="delete" aria-label="%s">%s</a>',
       
   457 				esc_url( wp_nonce_url( $url, 'bulk-themes' ) ),
       
   458 				esc_attr( $aria_label ),
       
   459 				__( 'Delete' )
       
   460 			);
       
   461 		}
   327 		/**
   462 		/**
   328 		 * Filter the action links displayed for each theme in the Multisite
   463 		 * Filters the action links displayed for each theme in the Multisite
   329 		 * themes list table.
   464 		 * themes list table.
   330 		 *
   465 		 *
   331 		 * The action links displayed are determined by the theme's status, and
   466 		 * The action links displayed are determined by the theme's status, and
   332 		 * which Multisite themes list table is being displayed - the Network
   467 		 * which Multisite themes list table is being displayed - the Network
   333 		 * themes list table (themes.php), which displays all installed themes,
   468 		 * themes list table (themes.php), which displays all installed themes,
   334 		 * or the Site themes list table (site-themes.php), which displays the
   469 		 * or the Site themes list table (site-themes.php), which displays the
   335 		 * non-network enabled themes when editing a site in the Network admin.
   470 		 * non-network enabled themes when editing a site in the Network admin.
   336 		 *
   471 		 *
   337 		 * The default action links for the Network themes list table include
   472 		 * The default action links for the Network themes list table include
   338 		 * 'Network Enable', 'Network Disable', 'Edit', and 'Delete'.
   473 		 * 'Network Enable', 'Network Disable', and 'Delete'.
   339 		 *
   474 		 *
   340 		 * The default action links for the Site themes list table include
   475 		 * The default action links for the Site themes list table include
   341 		 * 'Enable', 'Disable', and 'Edit'.
   476 		 * 'Enable', and 'Disable'.
   342 		 *
   477 		 *
   343 		 * @since 2.8.0
   478 		 * @since 2.8.0
   344 		 *
   479 		 *
   345 		 * @param array    $actions An array of action links.
   480 		 * @param array    $actions An array of action links.
   346 		 * @param WP_Theme $theme   The current WP_Theme object.
   481 		 * @param WP_Theme $theme   The current WP_Theme object.
   347 		 * @param string   $context Status of the theme.
   482 		 * @param string   $context Status of the theme, one of 'all', 'enabled', or 'disabled'.
   348 		 */
   483 		 */
   349 		$actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme, $context );
   484 		$actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme, $context );
   350 
   485 
   351 		/**
   486 		/**
   352 		 * Filter the action links of a specific theme in the Multisite themes
   487 		 * Filters the action links of a specific theme in the Multisite themes
   353 		 * list table.
   488 		 * list table.
   354 		 *
   489 		 *
   355 		 * The dynamic portion of the hook name, `$stylesheet`, refers to the
   490 		 * The dynamic portion of the hook name, `$stylesheet`, refers to the
   356 		 * directory name of the theme, which in most cases is synonymous
   491 		 * directory name of the theme, which in most cases is synonymous
   357 		 * with the template name.
   492 		 * with the template name.
   358 		 *
   493 		 *
   359 		 * @since 3.1.0
   494 		 * @since 3.1.0
   360 		 *
   495 		 *
   361 		 * @param array    $actions An array of action links.
   496 		 * @param array    $actions An array of action links.
   362 		 * @param WP_Theme $theme   The current WP_Theme object.
   497 		 * @param WP_Theme $theme   The current WP_Theme object.
   363 		 * @param string   $context Status of the theme.
   498 		 * @param string   $context Status of the theme, one of 'all', 'enabled', or 'disabled'.
   364 		 */
   499 		 */
   365 		$actions = apply_filters( "theme_action_links_$stylesheet", $actions, $theme, $context );
   500 		$actions = apply_filters( "theme_action_links_{$stylesheet}", $actions, $theme, $context );
       
   501 
       
   502 		echo $this->row_actions( $actions, true );
       
   503 	}
       
   504 
       
   505 	/**
       
   506 	 * Handles the description column output.
       
   507 	 *
       
   508 	 * @since 4.3.0
       
   509 	 *
       
   510 	 * @global string $status
       
   511 	 * @global array  $totals
       
   512 	 *
       
   513 	 * @param WP_Theme $theme The current WP_Theme object.
       
   514 	 */
       
   515 	public function column_description( $theme ) {
       
   516 		global $status, $totals;
       
   517 		if ( $theme->errors() ) {
       
   518 			$pre = $status === 'broken' ? __( 'Broken Theme:' ) . ' ' : '';
       
   519 			echo '<p><strong class="error-message">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
       
   520 		}
       
   521 
       
   522 		if ( $this->is_site_themes ) {
       
   523 			$allowed = $theme->is_allowed( 'site', $this->site_id );
       
   524 		} else {
       
   525 			$allowed = $theme->is_allowed( 'network' );
       
   526 		}
   366 
   527 
   367 		$class = ! $allowed ? 'inactive' : 'active';
   528 		$class = ! $allowed ? 'inactive' : 'active';
   368 		$checkbox_id = "checkbox_" . md5( $theme->get('Name') );
       
   369 		$checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $stylesheet ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme->display('Name') . "</label>";
       
   370 
       
   371 		$id = sanitize_html_class( $theme->get_stylesheet() );
       
   372 
       
   373 		if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) )
   529 		if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) )
   374 			$class .= ' update';
   530 			$class .= ' update';
   375 
   531 
   376 		echo "<tr id='$id' class='$class'>";
   532 		echo "<div class='theme-description'><p>" . $theme->display( 'Description' ) . "</p></div>
   377 
   533 			<div class='$class second theme-version-author-uri'>";
   378 		list( $columns, $hidden ) = $this->get_column_info();
   534 
       
   535 		$stylesheet = $theme->get_stylesheet();
       
   536 		$theme_meta = array();
       
   537 
       
   538 		if ( $theme->get('Version') ) {
       
   539 			$theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') );
       
   540 		}
       
   541 		$theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') );
       
   542 
       
   543 		if ( $theme->get('ThemeURI') ) {
       
   544 			/* translators: %s: theme name */
       
   545 			$aria_label = sprintf( __( 'Visit %s homepage' ), $theme->display( 'Name' ) );
       
   546 
       
   547 			$theme_meta[] = sprintf( '<a href="%s" aria-label="%s">%s</a>',
       
   548 				$theme->display( 'ThemeURI' ),
       
   549 				esc_attr( $aria_label ),
       
   550 				__( 'Visit Theme Site' )
       
   551 			);
       
   552 		}
       
   553 		/**
       
   554 		 * Filters the array of row meta for each theme in the Multisite themes
       
   555 		 * list table.
       
   556 		 *
       
   557 		 * @since 3.1.0
       
   558 		 *
       
   559 		 * @param array    $theme_meta An array of the theme's metadata,
       
   560 		 *                             including the version, author, and
       
   561 		 *                             theme URI.
       
   562 		 * @param string   $stylesheet Directory name of the theme.
       
   563 		 * @param WP_Theme $theme      WP_Theme object.
       
   564 		 * @param string   $status     Status of the theme.
       
   565 		 */
       
   566 		$theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $stylesheet, $theme, $status );
       
   567 		echo implode( ' | ', $theme_meta );
       
   568 
       
   569 		echo '</div>';
       
   570 	}
       
   571 
       
   572 	/**
       
   573 	 * Handles default column output.
       
   574 	 *
       
   575 	 * @since 4.3.0
       
   576 	 *
       
   577 	 * @param WP_Theme $theme       The current WP_Theme object.
       
   578 	 * @param string   $column_name The current column name.
       
   579 	 */
       
   580 	public function column_default( $theme, $column_name ) {
       
   581 		$stylesheet = $theme->get_stylesheet();
       
   582 
       
   583 		/**
       
   584 		 * Fires inside each custom column of the Multisite themes list table.
       
   585 		 *
       
   586 		 * @since 3.1.0
       
   587 		 *
       
   588 		 * @param string   $column_name Name of the column.
       
   589 		 * @param string   $stylesheet  Directory name of the theme.
       
   590 		 * @param WP_Theme $theme       Current WP_Theme object.
       
   591 		 */
       
   592 		do_action( 'manage_themes_custom_column', $column_name, $stylesheet, $theme );
       
   593 	}
       
   594 
       
   595 	/**
       
   596 	 * Handles the output for a single table row.
       
   597 	 *
       
   598 	 * @since 4.3.0
       
   599 	 *
       
   600 	 * @param WP_Theme $item The current WP_Theme object.
       
   601 	 */
       
   602 	public function single_row_columns( $item ) {
       
   603 		list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
   379 
   604 
   380 		foreach ( $columns as $column_name => $column_display_name ) {
   605 		foreach ( $columns as $column_name => $column_display_name ) {
   381 			$style = '';
   606 			$extra_classes = '';
   382 			if ( in_array( $column_name, $hidden ) )
   607 			if ( in_array( $column_name, $hidden ) ) {
   383 				$style = ' style="display:none;"';
   608 				$extra_classes .= ' hidden';
       
   609 			}
   384 
   610 
   385 			switch ( $column_name ) {
   611 			switch ( $column_name ) {
   386 				case 'cb':
   612 				case 'cb':
   387 					echo "<th scope='row' class='check-column'>$checkbox</th>";
   613 					echo '<th scope="row" class="check-column">';
   388 					break;
   614 
       
   615 					$this->column_cb( $item );
       
   616 
       
   617 					echo '</th>';
       
   618 					break;
       
   619 
   389 				case 'name':
   620 				case 'name':
   390 					echo "<td class='theme-title'$style><strong>" . $theme->display('Name') . "</strong>";
   621 
   391 					echo $this->row_actions( $actions, true );
   622 					$active_theme_label = '';
       
   623 
       
   624 					/* 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 */
       
   625 					if ( ! empty( $this->site_id ) ) {
       
   626 						$stylesheet = get_blog_option( $this->site_id, 'stylesheet' );
       
   627 						$template   = get_blog_option( $this->site_id, 'template' );
       
   628 
       
   629 						/* Add a label for the active template */
       
   630 						if ( $item->get_template() === $template ) {
       
   631 							$active_theme_label = ' &mdash; ' . __( 'Active Theme' );
       
   632 						}
       
   633 
       
   634 						/* In case this is a child theme, label it properly */
       
   635 						if ( $stylesheet !== $template && $item->get_stylesheet() === $stylesheet) {
       
   636 							$active_theme_label = ' &mdash; ' . __( 'Active Child Theme' );
       
   637 						}
       
   638 					}
       
   639 
       
   640 					echo "<td class='theme-title column-primary{$extra_classes}'><strong>" . $item->display( 'Name' ) . $active_theme_label . '</strong>';
       
   641 
       
   642 					$this->column_name( $item );
       
   643 
   392 					echo "</td>";
   644 					echo "</td>";
   393 					break;
   645 					break;
       
   646 
   394 				case 'description':
   647 				case 'description':
   395 					echo "<td class='column-description desc'$style>";
   648 					echo "<td class='column-description desc{$extra_classes}'>";
   396 					if ( $theme->errors() ) {
   649 
   397 						$pre = $status == 'broken' ? __( 'Broken Theme:' ) . ' ' : '';
   650 					$this->column_description( $item );
   398 						echo '<p><strong class="attention">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
   651 
   399 					}
   652 					echo '</td>';
   400 					echo "<div class='theme-description'><p>" . $theme->display( 'Description' ) . "</p></div>
       
   401 						<div class='$class second theme-version-author-uri'>";
       
   402 
       
   403 					$theme_meta = array();
       
   404 
       
   405 					if ( $theme->get('Version') )
       
   406 						$theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') );
       
   407 
       
   408 					$theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') );
       
   409 
       
   410 					if ( $theme->get('ThemeURI') )
       
   411 						$theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>';
       
   412 
       
   413 					/**
       
   414 					 * Filter the array of row meta for each theme in the Multisite themes
       
   415 					 * list table.
       
   416 					 *
       
   417 					 * @since 3.1.0
       
   418 					 *
       
   419 					 * @param array    $theme_meta An array of the theme's metadata,
       
   420 					 *                             including the version, author, and
       
   421 					 *                             theme URI.
       
   422 					 * @param string   $stylesheet Directory name of the theme.
       
   423 					 * @param WP_Theme $theme      WP_Theme object.
       
   424 					 * @param string   $status     Status of the theme.
       
   425 					 */
       
   426 					$theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $stylesheet, $theme, $status );
       
   427 					echo implode( ' | ', $theme_meta );
       
   428 
       
   429 					echo "</div></td>";
       
   430 					break;
   653 					break;
   431 
   654 
   432 				default:
   655 				default:
   433 					echo "<td class='$column_name column-$column_name'$style>";
   656 					echo "<td class='$column_name column-$column_name{$extra_classes}'>";
   434 
   657 
   435 					/**
   658 					$this->column_default( $item, $column_name );
   436 					 * Fires inside each custom column of the Multisite themes list table.
   659 
   437 					 *
       
   438 					 * @since 3.1.0
       
   439 					 *
       
   440 					 * @param string   $column_name Name of the column.
       
   441 					 * @param string   $stylesheet  Directory name of the theme.
       
   442 					 * @param WP_Theme $theme       Current WP_Theme object.
       
   443 					 */
       
   444 					do_action( 'manage_themes_custom_column', $column_name, $stylesheet, $theme );
       
   445 					echo "</td>";
   660 					echo "</td>";
   446 			}
   661 					break;
   447 		}
   662 			}
       
   663 		}
       
   664 	}
       
   665 
       
   666 	/**
       
   667 	 * @global string $status
       
   668 	 * @global array  $totals
       
   669 	 *
       
   670 	 * @param WP_Theme $theme
       
   671 	 */
       
   672 	public function single_row( $theme ) {
       
   673 		global $status, $totals;
       
   674 
       
   675 		if ( $this->is_site_themes ) {
       
   676 			$allowed = $theme->is_allowed( 'site', $this->site_id );
       
   677 		} else {
       
   678 			$allowed = $theme->is_allowed( 'network' );
       
   679 		}
       
   680 
       
   681 		$stylesheet = $theme->get_stylesheet();
       
   682 
       
   683 		$class = ! $allowed ? 'inactive' : 'active';
       
   684 		if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) ) {
       
   685 			$class .= ' update';
       
   686 		}
       
   687 
       
   688 		printf( '<tr class="%s" data-slug="%s">',
       
   689 			esc_attr( $class ),
       
   690 			esc_attr( $stylesheet )
       
   691 		);
       
   692 
       
   693 		$this->single_row_columns( $theme );
   448 
   694 
   449 		echo "</tr>";
   695 		echo "</tr>";
   450 
   696 
   451 		if ( $this->is_site_themes )
   697 		if ( $this->is_site_themes )
   452 			remove_action( "after_theme_row_$stylesheet", 'wp_theme_update_row' );
   698 			remove_action( "after_theme_row_$stylesheet", 'wp_theme_update_row' );
   473 		 *
   719 		 *
   474 		 * @param string   $stylesheet Directory name of the theme.
   720 		 * @param string   $stylesheet Directory name of the theme.
   475 		 * @param WP_Theme $theme      Current WP_Theme object.
   721 		 * @param WP_Theme $theme      Current WP_Theme object.
   476 		 * @param string   $status     Status of the theme.
   722 		 * @param string   $status     Status of the theme.
   477 		 */
   723 		 */
   478 		do_action( "after_theme_row_$stylesheet", $stylesheet, $theme, $status );
   724 		do_action( "after_theme_row_{$stylesheet}", $stylesheet, $theme, $status );
   479 	}
   725 	}
   480 }
   726 }