[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  <?php
   2  /**
   3   * List Table API: WP_Plugins_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 installed plugins in a list table.
  12   *
  13   * @since 3.1.0
  14   * @access private
  15   *
  16   * @see WP_List_Table
  17   */
  18  class WP_Plugins_List_Table extends WP_List_Table {
  19  
  20      /**
  21       * Constructor.
  22       *
  23       * @since 3.1.0
  24       *
  25       * @see WP_List_Table::__construct() for more information on default arguments.
  26       *
  27       * @global string $status
  28       * @global int    $page
  29       *
  30       * @param array $args An associative array of arguments.
  31       */
  32  	public function __construct( $args = array() ) {
  33          global $status, $page;
  34  
  35          parent::__construct(
  36              array(
  37                  'plural' => 'plugins',
  38                  'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
  39              )
  40          );
  41  
  42          $status = 'all';
  43          if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'active', 'inactive', 'recently_activated', 'upgrade', 'mustuse', 'dropins', 'search', 'paused' ) ) ) {
  44              $status = $_REQUEST['plugin_status'];
  45          }
  46  
  47          if ( isset( $_REQUEST['s'] ) ) {
  48              $_SERVER['REQUEST_URI'] = add_query_arg( 's', wp_unslash( $_REQUEST['s'] ) );
  49          }
  50  
  51          $page = $this->get_pagenum();
  52      }
  53  
  54      /**
  55       * @return array
  56       */
  57  	protected function get_table_classes() {
  58          return array( 'widefat', $this->_args['plural'] );
  59      }
  60  
  61      /**
  62       * @return bool
  63       */
  64  	public function ajax_user_can() {
  65          return current_user_can( 'activate_plugins' );
  66      }
  67  
  68      /**
  69       * @global string $status
  70       * @global array  $plugins
  71       * @global array  $totals
  72       * @global int    $page
  73       * @global string $orderby
  74       * @global string $order
  75       * @global string $s
  76       */
  77  	public function prepare_items() {
  78          global $status, $plugins, $totals, $page, $orderby, $order, $s;
  79  
  80          wp_reset_vars( array( 'orderby', 'order' ) );
  81  
  82          /**
  83           * Filters the full array of plugins to list in the Plugins list table.
  84           *
  85           * @since 3.0.0
  86           *
  87           * @see get_plugins()
  88           *
  89           * @param array $all_plugins An array of plugins to display in the list table.
  90           */
  91          $all_plugins = apply_filters( 'all_plugins', get_plugins() );
  92  
  93          $plugins = array(
  94              'all'                => $all_plugins,
  95              'search'             => array(),
  96              'active'             => array(),
  97              'inactive'           => array(),
  98              'recently_activated' => array(),
  99              'upgrade'            => array(),
 100              'mustuse'            => array(),
 101              'dropins'            => array(),
 102              'paused'             => array(),
 103          );
 104  
 105          $screen = $this->screen;
 106  
 107          if ( ! is_multisite() || ( $screen->in_admin( 'network' ) && current_user_can( 'manage_network_plugins' ) ) ) {
 108  
 109              /**
 110               * Filters whether to display the advanced plugins list table.
 111               *
 112               * There are two types of advanced plugins - must-use and drop-ins -
 113               * which can be used in a single site or Multisite network.
 114               *
 115               * The $type parameter allows you to differentiate between the type of advanced
 116               * plugins to filter the display of. Contexts include 'mustuse' and 'dropins'.
 117               *
 118               * @since 3.0.0
 119               *
 120               * @param bool   $show Whether to show the advanced plugins for the specified
 121               *                     plugin type. Default true.
 122               * @param string $type The plugin type. Accepts 'mustuse', 'dropins'.
 123               */
 124              if ( apply_filters( 'show_advanced_plugins', true, 'mustuse' ) ) {
 125                  $plugins['mustuse'] = get_mu_plugins();
 126              }
 127  
 128              /** This action is documented in wp-admin/includes/class-wp-plugins-list-table.php */
 129              if ( apply_filters( 'show_advanced_plugins', true, 'dropins' ) ) {
 130                  $plugins['dropins'] = get_dropins();
 131              }
 132  
 133              if ( current_user_can( 'update_plugins' ) ) {
 134                  $current = get_site_transient( 'update_plugins' );
 135                  foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
 136                      if ( isset( $current->response[ $plugin_file ] ) ) {
 137                          $plugins['all'][ $plugin_file ]['update'] = true;
 138                          $plugins['upgrade'][ $plugin_file ]       = $plugins['all'][ $plugin_file ];
 139                      }
 140                  }
 141              }
 142          }
 143  
 144          if ( ! $screen->in_admin( 'network' ) ) {
 145              $show = current_user_can( 'manage_network_plugins' );
 146              /**
 147               * Filters whether to display network-active plugins alongside plugins active for the current site.
 148               *
 149               * This also controls the display of inactive network-only plugins (plugins with
 150               * "Network: true" in the plugin header).
 151               *
 152               * Plugins cannot be network-activated or network-deactivated from this screen.
 153               *
 154               * @since 4.4.0
 155               *
 156               * @param bool $show Whether to show network-active plugins. Default is whether the current
 157               *                   user can manage network plugins (ie. a Super Admin).
 158               */
 159              $show_network_active = apply_filters( 'show_network_active_plugins', $show );
 160          }
 161  
 162          if ( $screen->in_admin( 'network' ) ) {
 163              $recently_activated = get_site_option( 'recently_activated', array() );
 164          } else {
 165              $recently_activated = get_option( 'recently_activated', array() );
 166          }
 167  
 168          foreach ( $recently_activated as $key => $time ) {
 169              if ( $time + WEEK_IN_SECONDS < time() ) {
 170                  unset( $recently_activated[ $key ] );
 171              }
 172          }
 173  
 174          if ( $screen->in_admin( 'network' ) ) {
 175              update_site_option( 'recently_activated', $recently_activated );
 176          } else {
 177              update_option( 'recently_activated', $recently_activated );
 178          }
 179  
 180          $plugin_info = get_site_transient( 'update_plugins' );
 181  
 182          foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
 183              // Extra info if known. array_merge() ensures $plugin_data has precedence if keys collide.
 184              if ( isset( $plugin_info->response[ $plugin_file ] ) ) {
 185                  $plugin_data                    = array_merge( (array) $plugin_info->response[ $plugin_file ], $plugin_data );
 186                  $plugins['all'][ $plugin_file ] = $plugin_data;
 187                  // Make sure that $plugins['upgrade'] also receives the extra info since it is used on ?plugin_status=upgrade.
 188                  if ( isset( $plugins['upgrade'][ $plugin_file ] ) ) {
 189                      $plugins['upgrade'][ $plugin_file ] = $plugin_data;
 190                  }
 191              } elseif ( isset( $plugin_info->no_update[ $plugin_file ] ) ) {
 192                  $plugin_data                    = array_merge( (array) $plugin_info->no_update[ $plugin_file ], $plugin_data );
 193                  $plugins['all'][ $plugin_file ] = $plugin_data;
 194                  // Make sure that $plugins['upgrade'] also receives the extra info since it is used on ?plugin_status=upgrade.
 195                  if ( isset( $plugins['upgrade'][ $plugin_file ] ) ) {
 196                      $plugins['upgrade'][ $plugin_file ] = $plugin_data;
 197                  }
 198              }
 199  
 200              // Filter into individual sections.
 201              if ( is_multisite() && ! $screen->in_admin( 'network' ) && is_network_only_plugin( $plugin_file ) && ! is_plugin_active( $plugin_file ) ) {
 202                  if ( $show_network_active ) {
 203                      // On the non-network screen, show inactive network-only plugins if allowed.
 204                      $plugins['inactive'][ $plugin_file ] = $plugin_data;
 205                  } else {
 206                      // On the non-network screen, filter out network-only plugins as long as they're not individually active.
 207                      unset( $plugins['all'][ $plugin_file ] );
 208                  }
 209              } elseif ( ! $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) {
 210                  if ( $show_network_active ) {
 211                      // On the non-network screen, show network-active plugins if allowed.
 212                      $plugins['active'][ $plugin_file ] = $plugin_data;
 213                  } else {
 214                      // On the non-network screen, filter out network-active plugins.
 215                      unset( $plugins['all'][ $plugin_file ] );
 216                  }
 217              } elseif ( ( ! $screen->in_admin( 'network' ) && is_plugin_active( $plugin_file ) )
 218                  || ( $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) ) {
 219                  // On the non-network screen, populate the active list with plugins that are individually activated.
 220                  // On the network admin screen, populate the active list with plugins that are network-activated.
 221                  $plugins['active'][ $plugin_file ] = $plugin_data;
 222  
 223                  if ( ! $screen->in_admin( 'network' ) && is_plugin_paused( $plugin_file ) ) {
 224                      $plugins['paused'][ $plugin_file ] = $plugin_data;
 225                  }
 226              } else {
 227                  if ( isset( $recently_activated[ $plugin_file ] ) ) {
 228                      // Populate the recently activated list with plugins that have been recently activated.
 229                      $plugins['recently_activated'][ $plugin_file ] = $plugin_data;
 230                  }
 231                  // Populate the inactive list with plugins that aren't activated.
 232                  $plugins['inactive'][ $plugin_file ] = $plugin_data;
 233              }
 234          }
 235  
 236          if ( strlen( $s ) ) {
 237              $status            = 'search';
 238              $plugins['search'] = array_filter( $plugins['all'], array( $this, '_search_callback' ) );
 239          }
 240  
 241          $totals = array();
 242          foreach ( $plugins as $type => $list ) {
 243              $totals[ $type ] = count( $list );
 244          }
 245  
 246          if ( empty( $plugins[ $status ] ) && ! in_array( $status, array( 'all', 'search' ) ) ) {
 247              $status = 'all';
 248          }
 249  
 250          $this->items = array();
 251          foreach ( $plugins[ $status ] as $plugin_file => $plugin_data ) {
 252              // Translate, don't apply markup, sanitize HTML.
 253              $this->items[ $plugin_file ] = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, false, true );
 254          }
 255  
 256          $total_this_page = $totals[ $status ];
 257  
 258          $js_plugins = array();
 259          foreach ( $plugins as $key => $list ) {
 260              $js_plugins[ $key ] = array_keys( (array) $list );
 261          }
 262  
 263          wp_localize_script(
 264              'updates',
 265              '_wpUpdatesItemCounts',
 266              array(
 267                  'plugins' => $js_plugins,
 268                  'totals'  => wp_get_update_data(),
 269              )
 270          );
 271  
 272          if ( ! $orderby ) {
 273              $orderby = 'Name';
 274          } else {
 275              $orderby = ucfirst( $orderby );
 276          }
 277  
 278          $order = strtoupper( $order );
 279  
 280          uasort( $this->items, array( $this, '_order_callback' ) );
 281  
 282          $plugins_per_page = $this->get_items_per_page( str_replace( '-', '_', $screen->id . '_per_page' ), 999 );
 283  
 284          $start = ( $page - 1 ) * $plugins_per_page;
 285  
 286          if ( $total_this_page > $plugins_per_page ) {
 287              $this->items = array_slice( $this->items, $start, $plugins_per_page );
 288          }
 289  
 290          $this->set_pagination_args(
 291              array(
 292                  'total_items' => $total_this_page,
 293                  'per_page'    => $plugins_per_page,
 294              )
 295          );
 296      }
 297  
 298      /**
 299       * @global string $s URL encoded search term.
 300       *
 301       * @param array $plugin
 302       * @return bool
 303       */
 304  	public function _search_callback( $plugin ) {
 305          global $s;
 306  
 307          foreach ( $plugin as $value ) {
 308              if ( is_string( $value ) && false !== stripos( strip_tags( $value ), urldecode( $s ) ) ) {
 309                  return true;
 310              }
 311          }
 312  
 313          return false;
 314      }
 315  
 316      /**
 317       * @global string $orderby
 318       * @global string $order
 319       * @param array $plugin_a
 320       * @param array $plugin_b
 321       * @return int
 322       */
 323  	public function _order_callback( $plugin_a, $plugin_b ) {
 324          global $orderby, $order;
 325  
 326          $a = $plugin_a[ $orderby ];
 327          $b = $plugin_b[ $orderby ];
 328  
 329          if ( $a == $b ) {
 330              return 0;
 331          }
 332  
 333          if ( 'DESC' === $order ) {
 334              return strcasecmp( $b, $a );
 335          } else {
 336              return strcasecmp( $a, $b );
 337          }
 338      }
 339  
 340      /**
 341       * @global array $plugins
 342       */
 343  	public function no_items() {
 344          global $plugins;
 345  
 346          if ( ! empty( $_REQUEST['s'] ) ) {
 347              $s = esc_html( wp_unslash( $_REQUEST['s'] ) );
 348  
 349              /* translators: %s: Plugin search term. */
 350              printf( __( 'No plugins found for &#8220;%s&#8221;.' ), $s );
 351  
 352              // We assume that somebody who can install plugins in multisite is experienced enough to not need this helper link.
 353              if ( ! is_multisite() && current_user_can( 'install_plugins' ) ) {
 354                  echo ' <a href="' . esc_url( admin_url( 'plugin-install.php?tab=search&s=' . urlencode( $s ) ) ) . '">' . __( 'Search for plugins in the WordPress Plugin Directory.' ) . '</a>';
 355              }
 356          } elseif ( ! empty( $plugins['all'] ) ) {
 357              _e( 'No plugins found.' );
 358          } else {
 359              _e( 'You do not appear to have any plugins available at this time.' );
 360          }
 361      }
 362  
 363      /**
 364       * Displays the search box.
 365       *
 366       * @since 4.6.0
 367       *
 368       * @param string $text     The 'submit' button label.
 369       * @param string $input_id ID attribute value for the search input field.
 370       */
 371  	public function search_box( $text, $input_id ) {
 372          if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) {
 373              return;
 374          }
 375  
 376          $input_id = $input_id . '-search-input';
 377  
 378          if ( ! empty( $_REQUEST['orderby'] ) ) {
 379              echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
 380          }
 381          if ( ! empty( $_REQUEST['order'] ) ) {
 382              echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
 383          }
 384          ?>
 385          <p class="search-box">
 386              <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?>:</label>
 387              <input type="search" id="<?php echo esc_attr( $input_id ); ?>" class="wp-filter-search" name="s" value="<?php _admin_search_query(); ?>" placeholder="<?php esc_attr_e( 'Search installed plugins...' ); ?>"/>
 388              <?php submit_button( $text, 'hide-if-js', '', false, array( 'id' => 'search-submit' ) ); ?>
 389          </p>
 390          <?php
 391      }
 392  
 393      /**
 394       * @global string $status
 395       * @return array
 396       */
 397  	public function get_columns() {
 398          global $status;
 399  
 400          return array(
 401              'cb'          => ! in_array( $status, array( 'mustuse', 'dropins' ) ) ? '<input type="checkbox" />' : '',
 402              'name'        => __( 'Plugin' ),
 403              'description' => __( 'Description' ),
 404          );
 405      }
 406  
 407      /**
 408       * @return array
 409       */
 410  	protected function get_sortable_columns() {
 411          return array();
 412      }
 413  
 414      /**
 415       * @global array $totals
 416       * @global string $status
 417       * @return array
 418       */
 419  	protected function get_views() {
 420          global $totals, $status;
 421  
 422          $status_links = array();
 423          foreach ( $totals as $type => $count ) {
 424              if ( ! $count ) {
 425                  continue;
 426              }
 427  
 428              switch ( $type ) {
 429                  case 'all':
 430                      /* translators: %s: Number of plugins. */
 431                      $text = _nx(
 432                          'All <span class="count">(%s)</span>',
 433                          'All <span class="count">(%s)</span>',
 434                          $count,
 435                          'plugins'
 436                      );
 437                      break;
 438                  case 'active':
 439                      /* translators: %s: Number of plugins. */
 440                      $text = _n(
 441                          'Active <span class="count">(%s)</span>',
 442                          'Active <span class="count">(%s)</span>',
 443                          $count
 444                      );
 445                      break;
 446                  case 'recently_activated':
 447                      /* translators: %s: Number of plugins. */
 448                      $text = _n(
 449                          'Recently Active <span class="count">(%s)</span>',
 450                          'Recently Active <span class="count">(%s)</span>',
 451                          $count
 452                      );
 453                      break;
 454                  case 'inactive':
 455                      /* translators: %s: Number of plugins. */
 456                      $text = _n(
 457                          'Inactive <span class="count">(%s)</span>',
 458                          'Inactive <span class="count">(%s)</span>',
 459                          $count
 460                      );
 461                      break;
 462                  case 'mustuse':
 463                      /* translators: %s: Number of plugins. */
 464                      $text = _n(
 465                          'Must-Use <span class="count">(%s)</span>',
 466                          'Must-Use <span class="count">(%s)</span>',
 467                          $count
 468                      );
 469                      break;
 470                  case 'dropins':
 471                      /* translators: %s: Number of plugins. */
 472                      $text = _n(
 473                          'Drop-in <span class="count">(%s)</span>',
 474                          'Drop-ins <span class="count">(%s)</span>',
 475                          $count
 476                      );
 477                      break;
 478                  case 'paused':
 479                      /* translators: %s: Number of plugins. */
 480                      $text = _n(
 481                          'Paused <span class="count">(%s)</span>',
 482                          'Paused <span class="count">(%s)</span>',
 483                          $count
 484                      );
 485                      break;
 486                  case 'upgrade':
 487                      /* translators: %s: Number of plugins. */
 488                      $text = _n(
 489                          'Update Available <span class="count">(%s)</span>',
 490                          'Update Available <span class="count">(%s)</span>',
 491                          $count
 492                      );
 493                      break;
 494              }
 495  
 496              if ( 'search' !== $type ) {
 497                  $status_links[ $type ] = sprintf(
 498                      "<a href='%s'%s>%s</a>",
 499                      add_query_arg( 'plugin_status', $type, 'plugins.php' ),
 500                      ( $type === $status ) ? ' class="current" aria-current="page"' : '',
 501                      sprintf( $text, number_format_i18n( $count ) )
 502                  );
 503              }
 504          }
 505  
 506          return $status_links;
 507      }
 508  
 509      /**
 510       * @global string $status
 511       * @return array
 512       */
 513  	protected function get_bulk_actions() {
 514          global $status;
 515  
 516          $actions = array();
 517  
 518          if ( 'active' != $status ) {
 519              $actions['activate-selected'] = $this->screen->in_admin( 'network' ) ? __( 'Network Activate' ) : __( 'Activate' );
 520          }
 521  
 522          if ( 'inactive' != $status && 'recent' != $status ) {
 523              $actions['deactivate-selected'] = $this->screen->in_admin( 'network' ) ? __( 'Network Deactivate' ) : __( 'Deactivate' );
 524          }
 525  
 526          if ( ! is_multisite() || $this->screen->in_admin( 'network' ) ) {
 527              if ( current_user_can( 'update_plugins' ) ) {
 528                  $actions['update-selected'] = __( 'Update' );
 529              }
 530              if ( current_user_can( 'delete_plugins' ) && ( 'active' != $status ) ) {
 531                  $actions['delete-selected'] = __( 'Delete' );
 532              }
 533          }
 534  
 535          return $actions;
 536      }
 537  
 538      /**
 539       * @global string $status
 540       * @param string $which
 541       */
 542  	public function bulk_actions( $which = '' ) {
 543          global $status;
 544  
 545          if ( in_array( $status, array( 'mustuse', 'dropins' ) ) ) {
 546              return;
 547          }
 548  
 549          parent::bulk_actions( $which );
 550      }
 551  
 552      /**
 553       * @global string $status
 554       * @param string $which
 555       */
 556  	protected function extra_tablenav( $which ) {
 557          global $status;
 558  
 559          if ( ! in_array( $status, array( 'recently_activated', 'mustuse', 'dropins' ) ) ) {
 560              return;
 561          }
 562  
 563          echo '<div class="alignleft actions">';
 564  
 565          if ( 'recently_activated' == $status ) {
 566              submit_button( __( 'Clear List' ), '', 'clear-recent-list', false );
 567          } elseif ( 'top' === $which && 'mustuse' === $status ) {
 568              echo '<p>' . sprintf(
 569                  /* translators: %s: mu-plugins directory name. */
 570                  __( 'Files in the %s directory are executed automatically.' ),
 571                  '<code>' . str_replace( ABSPATH, '/', WPMU_PLUGIN_DIR ) . '</code>'
 572              ) . '</p>';
 573          } elseif ( 'top' === $which && 'dropins' === $status ) {
 574              echo '<p>' . sprintf(
 575                  /* translators: %s: wp-content directory name. */
 576                  __( 'Drop-ins are single files, found in the %s directory, that replace or enhance WordPress features in ways that are not possible for traditional plugins.' ),
 577                  '<code>' . str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '</code>'
 578              ) . '</p>';
 579          }
 580          echo '</div>';
 581      }
 582  
 583      /**
 584       * @return string
 585       */
 586  	public function current_action() {
 587          if ( isset( $_POST['clear-recent-list'] ) ) {
 588              return 'clear-recent-list';
 589          }
 590  
 591          return parent::current_action();
 592      }
 593  
 594      /**
 595       * @global string $status
 596       */
 597  	public function display_rows() {
 598          global $status;
 599  
 600          if ( is_multisite() && ! $this->screen->in_admin( 'network' ) && in_array( $status, array( 'mustuse', 'dropins' ) ) ) {
 601              return;
 602          }
 603  
 604          foreach ( $this->items as $plugin_file => $plugin_data ) {
 605              $this->single_row( array( $plugin_file, $plugin_data ) );
 606          }
 607      }
 608  
 609      /**
 610       * @global string $status
 611       * @global int $page
 612       * @global string $s
 613       * @global array $totals
 614       *
 615       * @param array $item
 616       */
 617  	public function single_row( $item ) {
 618          global $status, $page, $s, $totals;
 619  
 620          list( $plugin_file, $plugin_data ) = $item;
 621          $context                           = $status;
 622          $screen                            = $this->screen;
 623  
 624          // Pre-order.
 625          $actions = array(
 626              'deactivate' => '',
 627              'activate'   => '',
 628              'details'    => '',
 629              'delete'     => '',
 630          );
 631  
 632          // Do not restrict by default.
 633          $restrict_network_active = false;
 634          $restrict_network_only   = false;
 635  
 636          if ( 'mustuse' === $context ) {
 637              $is_active = true;
 638          } elseif ( 'dropins' === $context ) {
 639              $dropins     = _get_dropins();
 640              $plugin_name = $plugin_file;
 641              if ( $plugin_file != $plugin_data['Name'] ) {
 642                  $plugin_name .= '<br/>' . $plugin_data['Name'];
 643              }
 644              if ( true === ( $dropins[ $plugin_file ][1] ) ) { // Doesn't require a constant.
 645                  $is_active   = true;
 646                  $description = '<p><strong>' . $dropins[ $plugin_file ][0] . '</strong></p>';
 647              } elseif ( defined( $dropins[ $plugin_file ][1] ) && constant( $dropins[ $plugin_file ][1] ) ) { // Constant is true.
 648                  $is_active   = true;
 649                  $description = '<p><strong>' . $dropins[ $plugin_file ][0] . '</strong></p>';
 650              } else {
 651                  $is_active   = false;
 652                  $description = '<p><strong>' . $dropins[ $plugin_file ][0] . ' <span class="error-message">' . __( 'Inactive:' ) . '</span></strong> ' .
 653                      sprintf(
 654                          /* translators: 1: Drop-in constant name, 2: wp-config.php */
 655                          __( 'Requires %1$s in %2$s file.' ),
 656                          "<code>define('" . $dropins[ $plugin_file ][1] . "', true);</code>",
 657                          '<code>wp-config.php</code>'
 658                      ) . '</p>';
 659              }
 660              if ( $plugin_data['Description'] ) {
 661                  $description .= '<p>' . $plugin_data['Description'] . '</p>';
 662              }
 663          } else {
 664              if ( $screen->in_admin( 'network' ) ) {
 665                  $is_active = is_plugin_active_for_network( $plugin_file );
 666              } else {
 667                  $is_active               = is_plugin_active( $plugin_file );
 668                  $restrict_network_active = ( is_multisite() && is_plugin_active_for_network( $plugin_file ) );
 669                  $restrict_network_only   = ( is_multisite() && is_network_only_plugin( $plugin_file ) && ! $is_active );
 670              }
 671  
 672              if ( $screen->in_admin( 'network' ) ) {
 673                  if ( $is_active ) {
 674                      if ( current_user_can( 'manage_network_plugins' ) ) {
 675                          $actions['deactivate'] = sprintf(
 676                              '<a href="%s" aria-label="%s">%s</a>',
 677                              wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file ),
 678                              /* translators: %s: Plugin name. */
 679                              esc_attr( sprintf( _x( 'Network Deactivate %s', 'plugin' ), $plugin_data['Name'] ) ),
 680                              __( 'Network Deactivate' )
 681                          );
 682                      }
 683                  } else {
 684                      if ( current_user_can( 'manage_network_plugins' ) ) {
 685                          $actions['activate'] = sprintf(
 686                              '<a href="%s" class="edit" aria-label="%s">%s</a>',
 687                              wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file ),
 688                              /* translators: %s: Plugin name. */
 689                              esc_attr( sprintf( _x( 'Network Activate %s', 'plugin' ), $plugin_data['Name'] ) ),
 690                              __( 'Network Activate' )
 691                          );
 692                      }
 693                      if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) ) {
 694                          $actions['delete'] = sprintf(
 695                              '<a href="%s" class="delete" aria-label="%s">%s</a>',
 696                              wp_nonce_url( 'plugins.php?action=delete-selected&amp;checked[]=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins' ),
 697                              /* translators: %s: Plugin name. */
 698                              esc_attr( sprintf( _x( 'Delete %s', 'plugin' ), $plugin_data['Name'] ) ),
 699                              __( 'Delete' )
 700                          );
 701                      }
 702                  }
 703              } else {
 704                  if ( $restrict_network_active ) {
 705                      $actions = array(
 706                          'network_active' => __( 'Network Active' ),
 707                      );
 708                  } elseif ( $restrict_network_only ) {
 709                      $actions = array(
 710                          'network_only' => __( 'Network Only' ),
 711                      );
 712                  } elseif ( $is_active ) {
 713                      if ( current_user_can( 'deactivate_plugin', $plugin_file ) ) {
 714                          $actions['deactivate'] = sprintf(
 715                              '<a href="%s" aria-label="%s">%s</a>',
 716                              wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file ),
 717                              /* translators: %s: Plugin name. */
 718                              esc_attr( sprintf( _x( 'Deactivate %s', 'plugin' ), $plugin_data['Name'] ) ),
 719                              __( 'Deactivate' )
 720                          );
 721                      }
 722                      if ( current_user_can( 'resume_plugin', $plugin_file ) && is_plugin_paused( $plugin_file ) ) {
 723                          $actions['resume'] = sprintf(
 724                              '<a class="resume-link" href="%s" aria-label="%s">%s</a>',
 725                              wp_nonce_url( 'plugins.php?action=resume&amp;plugin=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'resume-plugin_' . $plugin_file ),
 726                              /* translators: %s: Plugin name. */
 727                              esc_attr( sprintf( _x( 'Resume %s', 'plugin' ), $plugin_data['Name'] ) ),
 728                              __( 'Resume' )
 729                          );
 730                      }
 731                  } else {
 732                      if ( current_user_can( 'activate_plugin', $plugin_file ) ) {
 733                          $actions['activate'] = sprintf(
 734                              '<a href="%s" class="edit" aria-label="%s">%s</a>',
 735                              wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file ),
 736                              /* translators: %s: Plugin name. */
 737                              esc_attr( sprintf( _x( 'Activate %s', 'plugin' ), $plugin_data['Name'] ) ),
 738                              __( 'Activate' )
 739                          );
 740                      }
 741  
 742                      if ( ! is_multisite() && current_user_can( 'delete_plugins' ) ) {
 743                          $actions['delete'] = sprintf(
 744                              '<a href="%s" class="delete" aria-label="%s">%s</a>',
 745                              wp_nonce_url( 'plugins.php?action=delete-selected&amp;checked[]=' . urlencode( $plugin_file ) . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins' ),
 746                              /* translators: %s: Plugin name. */
 747                              esc_attr( sprintf( _x( 'Delete %s', 'plugin' ), $plugin_data['Name'] ) ),
 748                              __( 'Delete' )
 749                          );
 750                      }
 751                  } // End if $is_active.
 752              } // End if $screen->in_admin( 'network' ).
 753          } // End if $context.
 754  
 755          $actions = array_filter( $actions );
 756  
 757          if ( $screen->in_admin( 'network' ) ) {
 758  
 759              /**
 760               * Filters the action links displayed for each plugin in the Network Admin Plugins list table.
 761               *
 762               * @since 3.1.0
 763               *
 764               * @param string[] $actions     An array of plugin action links. By default this can include 'activate',
 765               *                              'deactivate', and 'delete'.
 766               * @param string   $plugin_file Path to the plugin file relative to the plugins directory.
 767               * @param array    $plugin_data An array of plugin data. See `get_plugin_data()`.
 768               * @param string   $context     The plugin context. By default this can include 'all', 'active', 'inactive',
 769               *                              'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
 770               */
 771              $actions = apply_filters( 'network_admin_plugin_action_links', $actions, $plugin_file, $plugin_data, $context );
 772  
 773              /**
 774               * Filters the list of action links displayed for a specific plugin in the Network Admin Plugins list table.
 775               *
 776               * The dynamic portion of the hook name, `$plugin_file`, refers to the path
 777               * to the plugin file, relative to the plugins directory.
 778               *
 779               * @since 3.1.0
 780               *
 781               * @param string[] $actions     An array of plugin action links. By default this can include 'activate',
 782               *                              'deactivate', and 'delete'.
 783               * @param string   $plugin_file Path to the plugin file relative to the plugins directory.
 784               * @param array    $plugin_data An array of plugin data. See `get_plugin_data()`.
 785               * @param string   $context     The plugin context. By default this can include 'all', 'active', 'inactive',
 786               *                              'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
 787               */
 788              $actions = apply_filters( "network_admin_plugin_action_links_{$plugin_file}", $actions, $plugin_file, $plugin_data, $context );
 789  
 790          } else {
 791  
 792              /**
 793               * Filters the action links displayed for each plugin in the Plugins list table.
 794               *
 795               * @since 2.5.0
 796               * @since 2.6.0 The `$context` parameter was added.
 797               * @since 4.9.0 The 'Edit' link was removed from the list of action links.
 798               *
 799               * @param string[] $actions     An array of plugin action links. By default this can include 'activate',
 800               *                              'deactivate', and 'delete'. With Multisite active this can also include
 801               *                              'network_active' and 'network_only' items.
 802               * @param string   $plugin_file Path to the plugin file relative to the plugins directory.
 803               * @param array    $plugin_data An array of plugin data. See `get_plugin_data()`.
 804               * @param string   $context     The plugin context. By default this can include 'all', 'active', 'inactive',
 805               *                              'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
 806               */
 807              $actions = apply_filters( 'plugin_action_links', $actions, $plugin_file, $plugin_data, $context );
 808  
 809              /**
 810               * Filters the list of action links displayed for a specific plugin in the Plugins list table.
 811               *
 812               * The dynamic portion of the hook name, `$plugin_file`, refers to the path
 813               * to the plugin file, relative to the plugins directory.
 814               *
 815               * @since 2.7.0
 816               * @since 4.9.0 The 'Edit' link was removed from the list of action links.
 817               *
 818               * @param string[] $actions     An array of plugin action links. By default this can include 'activate',
 819               *                              'deactivate', and 'delete'. With Multisite active this can also include
 820               *                              'network_active' and 'network_only' items.
 821               * @param string   $plugin_file Path to the plugin file relative to the plugins directory.
 822               * @param array    $plugin_data An array of plugin data. See `get_plugin_data()`.
 823               * @param string   $context     The plugin context. By default this can include 'all', 'active', 'inactive',
 824               *                              'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
 825               */
 826              $actions = apply_filters( "plugin_action_links_{$plugin_file}", $actions, $plugin_file, $plugin_data, $context );
 827  
 828          }
 829  
 830          $requires_php   = isset( $plugin_data['requires_php'] ) ? $plugin_data['requires_php'] : null;
 831          $compatible_php = is_php_version_compatible( $requires_php );
 832          $class          = $is_active ? 'active' : 'inactive';
 833          $checkbox_id    = 'checkbox_' . md5( $plugin_data['Name'] );
 834          if ( $restrict_network_active || $restrict_network_only || in_array( $status, array( 'mustuse', 'dropins' ) ) || ! $compatible_php ) {
 835              $checkbox = '';
 836          } else {
 837              $checkbox = sprintf(
 838                  '<label class="screen-reader-text" for="%1$s">%2$s</label>' .
 839                  '<input type="checkbox" name="checked[]" value="%3$s" id="%1$s" />',
 840                  $checkbox_id,
 841                  /* translators: %s: Plugin name. */
 842                  sprintf( __( 'Select %s' ), $plugin_data['Name'] ),
 843                  esc_attr( $plugin_file )
 844              );
 845          }
 846          if ( 'dropins' != $context ) {
 847              $description = '<p>' . ( $plugin_data['Description'] ? $plugin_data['Description'] : '&nbsp;' ) . '</p>';
 848              $plugin_name = $plugin_data['Name'];
 849          }
 850  
 851          if ( ! empty( $totals['upgrade'] ) && ! empty( $plugin_data['update'] ) ) {
 852              $class .= ' update';
 853          }
 854  
 855          $paused = ! $screen->in_admin( 'network' ) && is_plugin_paused( $plugin_file );
 856  
 857          if ( $paused ) {
 858              $class .= ' paused';
 859          }
 860  
 861          $plugin_slug = isset( $plugin_data['slug'] ) ? $plugin_data['slug'] : sanitize_title( $plugin_name );
 862          printf(
 863              '<tr class="%s" data-slug="%s" data-plugin="%s">',
 864              esc_attr( $class ),
 865              esc_attr( $plugin_slug ),
 866              esc_attr( $plugin_file )
 867          );
 868  
 869          list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
 870  
 871          foreach ( $columns as $column_name => $column_display_name ) {
 872              $extra_classes = '';
 873              if ( in_array( $column_name, $hidden ) ) {
 874                  $extra_classes = ' hidden';
 875              }
 876  
 877              switch ( $column_name ) {
 878                  case 'cb':
 879                      echo "<th scope='row' class='check-column'>$checkbox</th>";
 880                      break;
 881                  case 'name':
 882                      echo "<td class='plugin-title column-primary'><strong>$plugin_name</strong>";
 883                      echo $this->row_actions( $actions, true );
 884                      echo '</td>';
 885                      break;
 886                  case 'description':
 887                      $classes = 'column-description desc';
 888  
 889                      echo "<td class='$classes{$extra_classes}'>
 890                          <div class='plugin-description'>$description</div>
 891                          <div class='$class second plugin-version-author-uri'>";
 892  
 893                      $plugin_meta = array();
 894                      if ( ! empty( $plugin_data['Version'] ) ) {
 895                          /* translators: %s: Plugin version number. */
 896                          $plugin_meta[] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
 897                      }
 898                      if ( ! empty( $plugin_data['Author'] ) ) {
 899                          $author = $plugin_data['Author'];
 900                          if ( ! empty( $plugin_data['AuthorURI'] ) ) {
 901                              $author = '<a href="' . $plugin_data['AuthorURI'] . '">' . $plugin_data['Author'] . '</a>';
 902                          }
 903                          /* translators: %s: Plugin author name. */
 904                          $plugin_meta[] = sprintf( __( 'By %s' ), $author );
 905                      }
 906  
 907                      // Details link using API info, if available.
 908                      if ( isset( $plugin_data['slug'] ) && current_user_can( 'install_plugins' ) ) {
 909                          $plugin_meta[] = sprintf(
 910                              '<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>',
 911                              esc_url(
 912                                  network_admin_url(
 913                                      'plugin-install.php?tab=plugin-information&plugin=' . $plugin_data['slug'] .
 914                                      '&TB_iframe=true&width=600&height=550'
 915                                  )
 916                              ),
 917                              /* translators: %s: Plugin name. */
 918                              esc_attr( sprintf( __( 'More information about %s' ), $plugin_name ) ),
 919                              esc_attr( $plugin_name ),
 920                              __( 'View details' )
 921                          );
 922                      } elseif ( ! empty( $plugin_data['PluginURI'] ) ) {
 923                          $plugin_meta[] = sprintf(
 924                              '<a href="%s">%s</a>',
 925                              esc_url( $plugin_data['PluginURI'] ),
 926                              __( 'Visit plugin site' )
 927                          );
 928                      }
 929  
 930                      /**
 931                       * Filters the array of row meta for each plugin in the Plugins list table.
 932                       *
 933                       * @since 2.8.0
 934                       *
 935                       * @param string[] $plugin_meta An array of the plugin's metadata,
 936                       *                              including the version, author,
 937                       *                              author URI, and plugin URI.
 938                       * @param string   $plugin_file Path to the plugin file relative to the plugins directory.
 939                       * @param array    $plugin_data An array of plugin data.
 940                       * @param string   $status      Status of the plugin. Defaults are 'All', 'Active',
 941                       *                              'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
 942                       *                              'Drop-ins', 'Search', 'Paused'.
 943                       */
 944                      $plugin_meta = apply_filters( 'plugin_row_meta', $plugin_meta, $plugin_file, $plugin_data, $status );
 945                      echo implode( ' | ', $plugin_meta );
 946  
 947                      echo '</div>';
 948  
 949                      if ( $paused ) {
 950                          $notice_text = __( 'This plugin failed to load properly and is paused during recovery mode.' );
 951  
 952                          printf( '<p><span class="dashicons dashicons-warning"></span> <strong>%s</strong></p>', $notice_text );
 953  
 954                          $error = wp_get_plugin_error( $plugin_file );
 955  
 956                          if ( false !== $error ) {
 957                              printf( '<div class="error-display"><p>%s</p></div>', wp_get_extension_error_description( $error ) );
 958                          }
 959                      }
 960  
 961                      echo '</td>';
 962                      break;
 963                  default:
 964                      $classes = "$column_name column-$column_name $class";
 965  
 966                      echo "<td class='$classes{$extra_classes}'>";
 967  
 968                      /**
 969                       * Fires inside each custom column of the Plugins list table.
 970                       *
 971                       * @since 3.1.0
 972                       *
 973                       * @param string $column_name Name of the column.
 974                       * @param string $plugin_file Path to the plugin file relative to the plugins directory.
 975                       * @param array  $plugin_data An array of plugin data.
 976                       */
 977                      do_action( 'manage_plugins_custom_column', $column_name, $plugin_file, $plugin_data );
 978  
 979                      echo '</td>';
 980              }
 981          }
 982  
 983          echo '</tr>';
 984  
 985          /**
 986           * Fires after each row in the Plugins list table.
 987           *
 988           * @since 2.3.0
 989           *
 990           * @param string $plugin_file Path to the plugin file relative to the plugins directory.
 991           * @param array  $plugin_data An array of plugin data.
 992           * @param string $status      Status of the plugin. Defaults are 'All', 'Active',
 993           *                            'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
 994           *                            'Drop-ins', 'Search', 'Paused'.
 995           */
 996          do_action( 'after_plugin_row', $plugin_file, $plugin_data, $status );
 997  
 998          /**
 999           * Fires after each specific row in the Plugins list table.
1000           *
1001           * The dynamic portion of the hook name, `$plugin_file`, refers to the path
1002           * to the plugin file, relative to the plugins directory.
1003           *
1004           * @since 2.7.0
1005           *
1006           * @param string $plugin_file Path to the plugin file relative to the plugins directory.
1007           * @param array  $plugin_data An array of plugin data.
1008           * @param string $status      Status of the plugin. Defaults are 'All', 'Active',
1009           *                            'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
1010           *                            'Drop-ins', 'Search', 'Paused'.
1011           */
1012          do_action( "after_plugin_row_{$plugin_file}", $plugin_file, $plugin_data, $status );
1013      }
1014  
1015      /**
1016       * Gets the name of the primary column for this specific list table.
1017       *
1018       * @since 4.3.0
1019       *
1020       * @return string Unalterable name for the primary column, in this case, 'name'.
1021       */
1022  	protected function get_primary_column_name() {
1023          return 'name';
1024      }
1025  }


Generated: Mon Mar 30 01:00:03 2020 Cross-referenced by PHPXref 0.7.1