web/wp-admin/includes/class-wp-ms-themes-list-table.php
changeset 194 32102edaa81b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
       
     1 <?php
       
     2 /**
       
     3  * MS Themes List Table class.
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage List_Table
       
     7  * @since 3.1.0
       
     8  * @access private
       
     9  */
       
    10 class WP_MS_Themes_List_Table extends WP_List_Table {
       
    11 
       
    12 	var $site_id;
       
    13 	var $is_site_themes;
       
    14 
       
    15 	function __construct() {
       
    16 		global $status, $page;
       
    17 
       
    18 		$status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : 'all';
       
    19 		if ( !in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search', 'broken' ) ) )
       
    20 			$status = 'all';
       
    21 
       
    22 		$page = $this->get_pagenum();
       
    23 
       
    24 		$screen = get_current_screen();
       
    25 		$this->is_site_themes = ( 'site-themes-network' == $screen->id ) ? true : false;
       
    26 
       
    27 		if ( $this->is_site_themes )
       
    28 			$this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
       
    29 
       
    30 		parent::__construct( array(
       
    31 			'plural' => 'themes'
       
    32 		) );
       
    33 	}
       
    34 
       
    35 	function get_table_classes() {
       
    36 		return array( 'widefat', 'plugins' );	// todo: remove and add CSS for .themes
       
    37 	}
       
    38 
       
    39 	function ajax_user_can() {
       
    40 		$menu_perms = get_site_option( 'menu_items', array() );
       
    41 
       
    42 		if ( empty( $menu_perms['themes'] ) && ! is_super_admin() )
       
    43 			return false;
       
    44 
       
    45 		if ( $this->is_site_themes && !current_user_can('manage_sites') )
       
    46 			return false;
       
    47 		elseif ( !$this->is_site_themes && !current_user_can('manage_network_themes') )
       
    48 			return false;
       
    49 		return true;
       
    50 	}
       
    51 
       
    52 	function prepare_items() {
       
    53 		global $status, $totals, $page, $orderby, $order, $s;
       
    54 
       
    55 		wp_reset_vars( array( 'orderby', 'order', 's' ) );
       
    56 
       
    57 		$themes = array(
       
    58 			'all' => apply_filters( 'all_themes', wp_get_themes() ),
       
    59 			'search' => array(),
       
    60 			'enabled' => array(),
       
    61 			'disabled' => array(),
       
    62 			'upgrade' => array(),
       
    63 			'broken' => $this->is_site_themes ? array() : wp_get_themes( array( 'errors' => true ) ),
       
    64 		);
       
    65 
       
    66 		if ( $this->is_site_themes ) {
       
    67 			$themes_per_page = $this->get_items_per_page( 'site_themes_network_per_page' );
       
    68 			$allowed_where = 'site';
       
    69 		} else {
       
    70 			$themes_per_page = $this->get_items_per_page( 'themes_network_per_page' );
       
    71 			$allowed_where = 'network';
       
    72 		}
       
    73 
       
    74 		$maybe_update = current_user_can( 'update_themes' ) && ! $this->is_site_themes && $current = get_site_transient( 'update_themes' );
       
    75 
       
    76 		foreach ( (array) $themes['all'] as $key => $theme ) {
       
    77 			if ( $this->is_site_themes && $theme->is_allowed( 'network' ) ) {
       
    78 				unset( $themes['all'][ $key ] );
       
    79 				continue;
       
    80 			}
       
    81 
       
    82 			if ( $maybe_update && isset( $current->response[ $key ] ) ) {
       
    83 				$themes['all'][ $key ]->update = true;
       
    84 				$themes['upgrade'][ $key ] = $themes['all'][ $key ];
       
    85 			}
       
    86 
       
    87 			$filter = $theme->is_allowed( $allowed_where, $this->site_id ) ? 'enabled' : 'disabled';
       
    88 			$themes[ $filter ][ $key ] = $themes['all'][ $key ];
       
    89 		}
       
    90 
       
    91 		if ( $s ) {
       
    92 			$status = 'search';
       
    93 			$themes['search'] = array_filter( array_merge( $themes['all'], $themes['broken'] ), array( &$this, '_search_callback' ) );
       
    94 		}
       
    95 
       
    96 		$totals = array();
       
    97 		foreach ( $themes as $type => $list )
       
    98 			$totals[ $type ] = count( $list );
       
    99 
       
   100 		if ( empty( $themes[ $status ] ) && !in_array( $status, array( 'all', 'search' ) ) )
       
   101 			$status = 'all';
       
   102 
       
   103 		$this->items = $themes[ $status ];
       
   104 		WP_Theme::sort_by_name( $this->items );
       
   105 
       
   106 		$this->has_items = ! empty( $themes['all'] );
       
   107 		$total_this_page = $totals[ $status ];
       
   108 
       
   109 		if ( $orderby ) {
       
   110 			$orderby = ucfirst( $orderby );
       
   111 			$order = strtoupper( $order );
       
   112 
       
   113 			if ( $orderby == 'Name' ) {
       
   114 				if ( 'ASC' == $order )
       
   115 					$this->items = array_reverse( $this->items );
       
   116 			} else {
       
   117 				uasort( $this->items, array( &$this, '_order_callback' ) );
       
   118 			}
       
   119 		}
       
   120 
       
   121 		$start = ( $page - 1 ) * $themes_per_page;
       
   122 
       
   123 		if ( $total_this_page > $themes_per_page )
       
   124 			$this->items = array_slice( $this->items, $start, $themes_per_page, true );
       
   125 
       
   126 		$this->set_pagination_args( array(
       
   127 			'total_items' => $total_this_page,
       
   128 			'per_page' => $themes_per_page,
       
   129 		) );
       
   130 	}
       
   131 
       
   132 	function _search_callback( $theme ) {
       
   133 		static $term;
       
   134 		if ( is_null( $term ) )
       
   135 			$term = stripslashes( $_REQUEST['s'] );
       
   136 
       
   137 		foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) {
       
   138 			// Don't mark up; Do translate.
       
   139 			if ( false !== stripos( $theme->display( $field, false, true ), $term ) )
       
   140 				return true;
       
   141 		}
       
   142 
       
   143 		if ( false !== stripos( $theme->get_stylesheet(), $term ) )
       
   144 			return true;
       
   145 
       
   146 		if ( false !== stripos( $theme->get_template(), $term ) )
       
   147 			return true;
       
   148 
       
   149 		return false;
       
   150 	}
       
   151 
       
   152 	// Not used by any core columns.
       
   153 	function _order_callback( $theme_a, $theme_b ) {
       
   154 		global $orderby, $order;
       
   155 
       
   156 		$a = $theme_a[ $orderby ];
       
   157 		$b = $theme_b[ $orderby ];
       
   158 
       
   159 		if ( $a == $b )
       
   160 			return 0;
       
   161 
       
   162 		if ( 'DESC' == $order )
       
   163 			return ( $a < $b ) ? 1 : -1;
       
   164 		else
       
   165 			return ( $a < $b ) ? -1 : 1;
       
   166 	}
       
   167 
       
   168 	function no_items() {
       
   169 		if ( ! $this->has_items )
       
   170 			_e( 'No themes found.' );
       
   171 		else
       
   172 			_e( 'You do not appear to have any themes available at this time.' );
       
   173 	}
       
   174 
       
   175 	function get_columns() {
       
   176 		global $status;
       
   177 
       
   178 		return array(
       
   179 			'cb'          => '<input type="checkbox" />',
       
   180 			'name'        => __( 'Theme' ),
       
   181 			'description' => __( 'Description' ),
       
   182 		);
       
   183 	}
       
   184 
       
   185 	function get_sortable_columns() {
       
   186 		return array(
       
   187 			'name'         => 'name',
       
   188 		);
       
   189 	}
       
   190 
       
   191 	function get_views() {
       
   192 		global $totals, $status;
       
   193 
       
   194 		$status_links = array();
       
   195 		foreach ( $totals as $type => $count ) {
       
   196 			if ( !$count )
       
   197 				continue;
       
   198 
       
   199 			switch ( $type ) {
       
   200 				case 'all':
       
   201 					$text = _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'themes' );
       
   202 					break;
       
   203 				case 'enabled':
       
   204 					$text = _n( 'Enabled <span class="count">(%s)</span>', 'Enabled <span class="count">(%s)</span>', $count );
       
   205 					break;
       
   206 				case 'disabled':
       
   207 					$text = _n( 'Disabled <span class="count">(%s)</span>', 'Disabled <span class="count">(%s)</span>', $count );
       
   208 					break;
       
   209 				case 'upgrade':
       
   210 					$text = _n( 'Update Available <span class="count">(%s)</span>', 'Update Available <span class="count">(%s)</span>', $count );
       
   211 					break;
       
   212 				case 'broken' :
       
   213 					$text = _n( 'Broken <span class="count">(%s)</span>', 'Broken <span class="count">(%s)</span>', $count );
       
   214 					break;
       
   215 			}
       
   216 
       
   217 			if ( $this->is_site_themes )
       
   218 				$url = 'site-themes.php?id=' . $this->site_id;
       
   219 			else
       
   220 				$url = 'themes.php';
       
   221 
       
   222 			if ( 'search' != $type ) {
       
   223 				$status_links[$type] = sprintf( "<a href='%s' %s>%s</a>",
       
   224 					esc_url( add_query_arg('theme_status', $type, $url) ),
       
   225 					( $type == $status ) ? ' class="current"' : '',
       
   226 					sprintf( $text, number_format_i18n( $count ) )
       
   227 				);
       
   228 			}
       
   229 		}
       
   230 
       
   231 		return $status_links;
       
   232 	}
       
   233 
       
   234 	function get_bulk_actions() {
       
   235 		global $status;
       
   236 
       
   237 		$actions = array();
       
   238 		if ( 'enabled' != $status )
       
   239 			$actions['enable-selected'] = $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' );
       
   240 		if ( 'disabled' != $status )
       
   241 			$actions['disable-selected'] = $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' );
       
   242 		if ( ! $this->is_site_themes ) {
       
   243 			if ( current_user_can( 'delete_themes' ) )
       
   244 				$actions['delete-selected'] = __( 'Delete' );
       
   245 			if ( current_user_can( 'update_themes' ) )
       
   246 				$actions['update-selected'] = __( 'Update' );
       
   247 		}
       
   248 		return $actions;
       
   249 	}
       
   250 
       
   251 	function bulk_actions( $which ) {
       
   252 		global $status;
       
   253 		parent::bulk_actions( $which );
       
   254 	}
       
   255 
       
   256 	function current_action() {
       
   257 		return parent::current_action();
       
   258 	}
       
   259 
       
   260 	function display_rows() {
       
   261 		foreach ( $this->items as $key => $theme )
       
   262 			$this->single_row( $key, $theme );
       
   263 	}
       
   264 
       
   265 	function single_row( $key, $theme ) {
       
   266 		global $status, $page, $s, $totals;
       
   267 
       
   268 		$context = $status;
       
   269 
       
   270 		if ( $this->is_site_themes ) {
       
   271 			$url = "site-themes.php?id={$this->site_id}&amp;";
       
   272 			$allowed = $theme->is_allowed( 'site', $this->site_id );
       
   273 		} else {
       
   274 			$url = 'themes.php?';
       
   275 			$allowed = $theme->is_allowed( 'network' );
       
   276 		}
       
   277 
       
   278 		// preorder
       
   279 		$actions = array(
       
   280 			'enable' => '',
       
   281 			'disable' => '',
       
   282 			'edit' => '',
       
   283 			'delete' => ''
       
   284 		);
       
   285 
       
   286 		$theme_key = $theme->get_stylesheet();
       
   287 
       
   288 		if ( ! $allowed ) {
       
   289 			if ( ! $theme->errors() )
       
   290 				$actions['enable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=enable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'enable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Enable this theme') . '" class="edit">' . ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) ) . '</a>';
       
   291 		} else {
       
   292 			$actions['disable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=disable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'disable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Disable this theme') . '">' . ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) ) . '</a>';
       
   293 		}
       
   294 
       
   295 		if ( current_user_can('edit_themes') )
       
   296 			$actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' . urlencode( $theme_key ) ) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>';
       
   297 
       
   298 		if ( ! $allowed && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) )
       
   299 			$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>';
       
   300 
       
   301 		$actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme_key, $theme, $context );
       
   302 		$actions = apply_filters( "theme_action_links_$theme_key", $actions, $theme_key, $theme, $context );
       
   303 
       
   304 		$class = ! $allowed ? 'inactive' : 'active';
       
   305 		$checkbox_id = "checkbox_" . md5( $theme->get('Name') );
       
   306 		$checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $theme_key ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme->display('Name') . "</label>";
       
   307 
       
   308 		$id = sanitize_html_class( $theme->get_stylesheet() );
       
   309 
       
   310 		if ( ! empty( $totals['upgrade'] ) && ! empty( $theme->update ) )
       
   311 			$class .= ' update';
       
   312 
       
   313 		echo "<tr id='$id' class='$class'>";
       
   314 
       
   315 		list( $columns, $hidden ) = $this->get_column_info();
       
   316 
       
   317 		foreach ( $columns as $column_name => $column_display_name ) {
       
   318 			$style = '';
       
   319 			if ( in_array( $column_name, $hidden ) )
       
   320 				$style = ' style="display:none;"';
       
   321 
       
   322 			switch ( $column_name ) {
       
   323 				case 'cb':
       
   324 					echo "<th scope='row' class='check-column'>$checkbox</th>";
       
   325 					break;
       
   326 				case 'name':
       
   327 					echo "<td class='theme-title'$style><strong>" . $theme->display('Name') . "</strong>";
       
   328 					echo $this->row_actions( $actions, true );
       
   329 					echo "</td>";
       
   330 					break;
       
   331 				case 'description':
       
   332 					echo "<td class='column-description desc'$style>";
       
   333 					if ( $theme->errors() ) {
       
   334 						$pre = $status == 'broken' ? '' : __( 'Broken Theme:' ) . ' ';
       
   335 						echo '<p><strong class="attention">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
       
   336 					}
       
   337 					echo "<div class='theme-description'><p>" . $theme->display( 'Description' ) . "</p></div>
       
   338 						<div class='$class second theme-version-author-uri'>";
       
   339 
       
   340 					$theme_meta = array();
       
   341 
       
   342 					if ( $theme->get('Version') )
       
   343 						$theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') );
       
   344 
       
   345 					$theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') );
       
   346 
       
   347 					if ( $theme->get('ThemeURI') )
       
   348 						$theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>';
       
   349 
       
   350 					$theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $theme_key, $theme, $status );
       
   351 					echo implode( ' | ', $theme_meta );
       
   352 
       
   353 					echo "</div></td>";
       
   354 					break;
       
   355 
       
   356 				default:
       
   357 					echo "<td class='$column_name column-$column_name'$style>";
       
   358 					do_action( 'manage_themes_custom_column', $column_name, $theme_key, $theme );
       
   359 					echo "</td>";
       
   360 			}
       
   361 		}
       
   362 
       
   363 		echo "</tr>";
       
   364 
       
   365 		if ( $this->is_site_themes )
       
   366 			remove_action( "after_theme_row_$theme_key", 'wp_theme_update_row' );
       
   367 		do_action( 'after_theme_row', $theme_key, $theme, $status );
       
   368 		do_action( "after_theme_row_$theme_key", $theme_key, $theme, $status );
       
   369 	}
       
   370 }