WordPress.org

Make WordPress Core

Changeset 37406


Ignore:
Timestamp:
05/10/2016 11:10:22 AM (4 years ago)
Author:
ocean90
Message:

Upgrader: Copy WP_Upgrader_Skin and its subclasses into one file per class.

Part 1/8.
See #36618.

Location:
trunk/src/wp-admin/includes
Files:
10 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-automatic-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    8529
    85310/**
  • trunk/src/wp-admin/includes/class-bulk-plugin-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    4209
    42110class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
     
    47059    }
    47160}
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-bulk-theme-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    4729
    47310class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
     
    52259    }
    52360}
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-bulk-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    2549
    25510/**
     
    418173    }
    419174}
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-language-pack-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    7749
    77510/**
     
    85085    }
    85186}
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-plugin-installer-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    5249
    52510/**
     
    60994    }
    61095}
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-plugin-upgrader-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    1929
    19310/**
     
    25269    }
    25370}
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'] = __('An error occurred while updating %1$s: %2$s');
    287         /* translators: 1: Title of an update */
    288         $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
    289         /* translators: 1: Title of an update */
    290         $this->upgrader->strings['skin_update_successful'] = __( '%1$s updated successfully.' ) . ' <a onclick="%2$s" href="#" class="hide-if-no-js"><span>' . __( 'Show Details' ) . '</span><span class="hidden">' . __( 'Hide Details' ) . '</span></a>';
    291         $this->upgrader->strings['skin_upgrade_end'] = __('All updates have been completed.');
    292     }
    293 
    294     /**
    295      * @param string $string
    296      */
    297     public function feedback($string) {
    298         if ( isset( $this->upgrader->strings[$string] ) )
    299             $string = $this->upgrader->strings[$string];
    300 
    301         if ( strpos($string, '%') !== false ) {
    302             $args = func_get_args();
    303             $args = array_splice($args, 1);
    304             if ( $args ) {
    305                 $args = array_map( 'strip_tags', $args );
    306                 $args = array_map( 'esc_html', $args );
    307                 $string = vsprintf($string, $args);
    308             }
    309         }
    310         if ( empty($string) )
    311             return;
    312         if ( $this->in_loop )
    313             echo "$string<br />\n";
    314         else
    315             echo "<p>$string</p>\n";
    316     }
    317 
    318     /**
    319      * @access public
    320      */
    321     public function header() {
    322         // Nothing, This will be displayed within a iframe.
    323     }
    324 
    325     /**
    326      * @access public
    327      */
    328     public function footer() {
    329         // Nothing, This will be displayed within a iframe.
    330     }
    331 
    332     /**
    333      *
    334      * @param string|WP_Error $error
    335      */
    336     public function error($error) {
    337         if ( is_string($error) && isset( $this->upgrader->strings[$error] ) )
    338             $this->error = $this->upgrader->strings[$error];
    339 
    340         if ( is_wp_error($error) ) {
    341             $messages = array();
    342             foreach ( $error->get_error_messages() as $emessage ) {
    343                 if ( $error->get_error_data() && is_string( $error->get_error_data() ) )
    344                     $messages[] = $emessage . ' ' . esc_html( strip_tags( $error->get_error_data() ) );
    345                 else
    346                     $messages[] = $emessage;
    347             }
    348             $this->error = implode(', ', $messages);
    349         }
    350         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    351     }
    352 
    353     /**
    354      * @access public
    355      */
    356     public function bulk_header() {
    357         $this->feedback('skin_upgrade_start');
    358     }
    359 
    360     /**
    361      * @access public
    362      */
    363     public function bulk_footer() {
    364         $this->feedback('skin_upgrade_end');
    365     }
    366 
    367     /**
    368      *
    369      * @param string $title
    370      */
    371     public function before($title = '') {
    372         $this->in_loop = true;
    373         printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    374         echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').css("display", "inline-block");</script>';
    375         echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
    376         $this->flush_output();
    377     }
    378 
    379     /**
    380      *
    381      * @param string $title
    382      */
    383     public function after($title = '') {
    384         echo '</p></div>';
    385         if ( $this->error || ! $this->result ) {
    386             if ( $this->error ) {
    387                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    388             } else {
    389                 echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
    390             }
    391 
    392             echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
    393         }
    394         if ( $this->result && ! is_wp_error( $this->result ) ) {
    395             if ( ! $this->error )
    396                 echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle();jQuery(\'span\', this).toggle(); return false;') . '</p></div>';
    397             echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js($this->upgrader->update_current) . '\').hide();</script>';
    398         }
    399 
    400         $this->reset();
    401         $this->flush_output();
    402     }
    403 
    404     /**
    405      * @access public
    406      */
    407     public function reset() {
    408         $this->in_loop = false;
    409         $this->error = false;
    410     }
    411 
    412     /**
    413      * @access public
    414      */
    415     public function flush_output() {
    416         wp_ob_end_flush_all();
    417         flush();
    418     }
    419 }
    420 
    421 class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
    422     public $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
    423 
    424     public function add_strings() {
    425         parent::add_strings();
    426         $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
    427     }
    428 
    429     /**
    430      *
    431      * @param string $title
    432      */
    433     public function before($title = '') {
    434         parent::before($this->plugin_info['Title']);
    435     }
    436 
    437     /**
    438      *
    439      * @param string $title
    440      */
    441     public function after($title = '') {
    442         parent::after($this->plugin_info['Title']);
    443         $this->decrement_update_count( 'plugin' );
    444     }
    445 
    446     /**
    447      * @access public
    448      */
    449     public function bulk_footer() {
    450         parent::bulk_footer();
    451         $update_actions =  array(
    452             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>',
    453             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    454         );
    455         if ( ! current_user_can( 'activate_plugins' ) )
    456             unset( $update_actions['plugins_page'] );
    457 
    458         /**
    459          * Filter the list of action links available following bulk plugin updates.
    460          *
    461          * @since 3.0.0
    462          *
    463          * @param array $update_actions Array of plugin action links.
    464          * @param array $plugin_info    Array of information for the last-updated plugin.
    465          */
    466         $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
    467 
    468         if ( ! empty($update_actions) )
    469             $this->feedback(implode(' | ', (array)$update_actions));
    470     }
    471 }
    472 
    473 class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    474     public $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
    475 
    476     public function add_strings() {
    477         parent::add_strings();
    478         $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
    479     }
    480 
    481     /**
    482      *
    483      * @param string $title
    484      */
    485     public function before($title = '') {
    486         parent::before( $this->theme_info->display('Name') );
    487     }
    488 
    489     /**
    490      *
    491      * @param string $title
    492      */
    493     public function after($title = '') {
    494         parent::after( $this->theme_info->display('Name') );
    495         $this->decrement_update_count( 'theme' );
    496     }
    497 
    498     /**
    499      * @access public
    500      */
    501     public function bulk_footer() {
    502         parent::bulk_footer();
    503         $update_actions =  array(
    504             'themes_page' => '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>',
    505             'updates_page' => '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>'
    506         );
    507         if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) )
    508             unset( $update_actions['themes_page'] );
    509 
    510         /**
    511          * Filter the list of action links available following bulk theme updates.
    512          *
    513          * @since 3.0.0
    514          *
    515          * @param array $update_actions Array of theme action links.
    516          * @param array $theme_info     Array of information for the last-updated theme.
    517          */
    518         $update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
    519 
    520         if ( ! empty($update_actions) )
    521             $this->feedback(implode(' | ', (array)$update_actions));
    522     }
    523 }
    524 
    525 /**
    526  * Plugin Installer Skin for WordPress Plugin Installer.
    527  *
    528  * @package WordPress
    529  * @subpackage Upgrader
    530  * @since 2.8.0
    531  */
    532 class Plugin_Installer_Skin extends WP_Upgrader_Skin {
    533     public $api;
    534     public $type;
    535 
    536     /**
    537      *
    538      * @param array $args
    539      */
    540     public function __construct($args = array()) {
    541         $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
    542         $args = wp_parse_args($args, $defaults);
    543 
    544         $this->type = $args['type'];
    545         $this->api = isset($args['api']) ? $args['api'] : array();
    546 
    547         parent::__construct($args);
    548     }
    549 
    550     /**
    551      * @access public
    552      */
    553     public function before() {
    554         if ( !empty($this->api) )
    555             $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
    556     }
    557 
    558     /**
    559      * @access public
    560      */
    561     public function after() {
    562         $plugin_file = $this->upgrader->plugin_info();
    563 
    564         $install_actions = array();
    565 
    566         $from = isset($_GET['from']) ? wp_unslash( $_GET['from'] ) : 'plugins';
    567 
    568         if ( 'import' == $from )
    569             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;from=import&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin &amp; Run Importer' ) . '</a>';
    570         else
    571             $install_actions['activate_plugin'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>';
    572 
    573         if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
    574             $install_actions['network_activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;networkwide=1&amp;plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) . '" target="_parent">' . __( 'Network Activate' ) . '</a>';
    575             unset( $install_actions['activate_plugin'] );
    576         }
    577 
    578         if ( 'import' == $from ) {
    579             $install_actions['importers_page'] = '<a href="' . admin_url( 'import.php' ) . '" target="_parent">' . __( 'Return to Importers' ) . '</a>';
    580         } elseif ( $this->type == 'web' ) {
    581             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '" target="_parent">' . __( 'Return to Plugin Installer' ) . '</a>';
    582         } elseif ( 'upload' == $this->type && 'plugins' == $from ) {
    583             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugin-install.php' ) . '">' . __( 'Return to Plugin Installer' ) . '</a>';
    584         } else {
    585             $install_actions['plugins_page'] = '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>';
    586         }
    587 
    588         if ( ! $this->result || is_wp_error($this->result) ) {
    589             unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    590         } elseif ( ! current_user_can( 'activate_plugins' ) ) {
    591             unset( $install_actions['activate_plugin'] );
    592         }
    593 
    594         /**
    595          * Filter the list of action links available following a single plugin installation.
    596          *
    597          * @since 2.7.0
    598          *
    599          * @param array  $install_actions Array of plugin action links.
    600          * @param object $api             Object containing WordPress.org API plugin data. Empty
    601          *                                for non-API installs, such as when a plugin is installed
    602          *                                via upload.
    603          * @param string $plugin_file     Path to the plugin file.
    604          */
    605         $install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
    606 
    607         if ( ! empty($install_actions) )
    608             $this->feedback(implode(' | ', (array)$install_actions));
    609     }
    610 }
    611 
    612 /**
    613  * Theme Installer Skin for the WordPress Theme Installer.
    614  *
    615  * @package WordPress
    616  * @subpackage Upgrader
    617  * @since 2.8.0
    618  */
    619 class Theme_Installer_Skin extends WP_Upgrader_Skin {
    620     public $api;
    621     public $type;
    622 
    623     /**
    624      *
    625      * @param array $args
    626      */
    627     public function __construct($args = array()) {
    628         $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
    629         $args = wp_parse_args($args, $defaults);
    630 
    631         $this->type = $args['type'];
    632         $this->api = isset($args['api']) ? $args['api'] : array();
    633 
    634         parent::__construct($args);
    635     }
    636 
    637     /**
    638      * @access public
    639      */
    640     public function before() {
    641         if ( !empty($this->api) )
    642             $this->upgrader->strings['process_success'] = sprintf( $this->upgrader->strings['process_success_specific'], $this->api->name, $this->api->version);
    643     }
    644 
    645     /**
    646      * @access public
    647      */
    648     public function after() {
    649         if ( empty($this->upgrader->result['destination_name']) )
    650             return;
    651 
    652         $theme_info = $this->upgrader->theme_info();
    653         if ( empty( $theme_info ) )
    654             return;
    655 
    656         $name       = $theme_info->display('Name');
    657         $stylesheet = $this->upgrader->result['destination_name'];
    658         $template   = $theme_info->get_template();
    659 
    660         $activate_link = add_query_arg( array(
    661             'action'     => 'activate',
    662             'template'   => urlencode( $template ),
    663             'stylesheet' => urlencode( $stylesheet ),
    664         ), admin_url('themes.php') );
    665         $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    666 
    667         $install_actions = array();
    668 
    669         if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    670             $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    671         }
    672         $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    673 
    674         if ( is_network_admin() && current_user_can( 'manage_network_themes' ) )
    675             $install_actions['network_enable'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ) . '" target="_parent">' . __( 'Network Enable' ) . '</a>';
    676 
    677         if ( $this->type == 'web' )
    678             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'theme-install.php' ) . '" target="_parent">' . __( 'Return to Theme Installer' ) . '</a>';
    679         elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) )
    680             $install_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    681 
    682         if ( ! $this->result || is_wp_error($this->result) || is_network_admin() || ! current_user_can( 'switch_themes' ) )
    683             unset( $install_actions['activate'], $install_actions['preview'] );
    684 
    685         /**
    686          * Filter the list of action links available following a single theme installation.
    687          *
    688          * @since 2.8.0
    689          *
    690          * @param array    $install_actions Array of theme action links.
    691          * @param object   $api             Object containing WordPress.org API theme data.
    692          * @param string   $stylesheet      Theme directory name.
    693          * @param WP_Theme $theme_info      Theme object.
    694          */
    695         $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
    696         if ( ! empty($install_actions) )
    697             $this->feedback(implode(' | ', (array)$install_actions));
    698     }
    699 }
    700 
    701 /**
    702  * Theme Upgrader Skin for WordPress Theme Upgrades.
    703  *
    704  * @package WordPress
    705  * @subpackage Upgrader
    706  * @since 2.8.0
    707  */
    708 class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
    709     public $theme = '';
    710 
    711     /**
    712      *
    713      * @param array $args
    714      */
    715     public function __construct($args = array()) {
    716         $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Update Theme') );
    717         $args = wp_parse_args($args, $defaults);
    718 
    719         $this->theme = $args['theme'];
    720 
    721         parent::__construct($args);
    722     }
    723 
    724     /**
    725      * @access public
    726      */
    727     public function after() {
    728         $this->decrement_update_count( 'theme' );
    729 
    730         $update_actions = array();
    731         if ( ! empty( $this->upgrader->result['destination_name'] ) && $theme_info = $this->upgrader->theme_info() ) {
    732             $name       = $theme_info->display('Name');
    733             $stylesheet = $this->upgrader->result['destination_name'];
    734             $template   = $theme_info->get_template();
    735 
    736             $activate_link = add_query_arg( array(
    737                 'action'     => 'activate',
    738                 'template'   => urlencode( $template ),
    739                 'stylesheet' => urlencode( $stylesheet ),
    740             ), admin_url('themes.php') );
    741             $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
    742 
    743             if ( get_stylesheet() == $stylesheet ) {
    744                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    745                     $update_actions['preview']  = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Customize' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize &#8220;%s&#8221;' ), $name ) . '</span></a>';
    746                 }
    747             } elseif ( current_user_can( 'switch_themes' ) ) {
    748                 if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
    749                     $update_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
    750                 }
    751                 $update_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';
    752             }
    753 
    754             if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() )
    755                 unset( $update_actions['preview'], $update_actions['activate'] );
    756         }
    757 
    758         $update_actions['themes_page'] = '<a href="' . self_admin_url( 'themes.php' ) . '" target="_parent">' . __( 'Return to Themes page' ) . '</a>';
    759 
    760         /**
    761          * Filter the list of action links available following a single theme update.
    762          *
    763          * @since 2.8.0
    764          *
    765          * @param array  $update_actions Array of theme action links.
    766          * @param string $theme          Theme directory name.
    767          */
    768         $update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
    769 
    770         if ( ! empty($update_actions) )
    771             $this->feedback(implode(' | ', (array)$update_actions));
    772     }
    773 }
    774 
    775 /**
    776  * Translation Upgrader Skin for WordPress Translation Upgrades.
    777  *
    778  * @package WordPress
    779  * @subpackage Upgrader
    780  * @since 3.7.0
    781  */
    782 class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
    783     public $language_update = null;
    784     public $done_header = false;
    785     public $done_footer = false;
    786     public $display_footer_actions = true;
    787 
    788     /**
    789      *
    790      * @param array $args
    791      */
    792     public function __construct( $args = array() ) {
    793         $defaults = array( 'url' => '', 'nonce' => '', 'title' => __( 'Update Translations' ), 'skip_header_footer' => false );
    794         $args = wp_parse_args( $args, $defaults );
    795         if ( $args['skip_header_footer'] ) {
    796             $this->done_header = true;
    797             $this->done_footer = true;
    798             $this->display_footer_actions = false;
    799         }
    800         parent::__construct( $args );
    801     }
    802 
    803     /**
    804      * @access public
    805      */
    806     public function before() {
    807         $name = $this->upgrader->get_name_for_update( $this->language_update );
    808 
    809         echo '<div class="update-messages lp-show-latest">';
    810 
    811         printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)&#8230;' ) . '</h2>', $name, $this->language_update->language );
    812     }
    813 
    814     /**
    815      *
    816      * @param string|WP_Error $error
    817      */
    818     public function error( $error ) {
    819         echo '<div class="lp-error">';
    820         parent::error( $error );
    821         echo '</div>';
    822     }
    823 
    824     /**
    825      * @access public
    826      */
    827     public function after() {
    828         echo '</div>';
    829     }
    830 
    831     /**
    832      * @access public
    833      */
    834     public function bulk_footer() {
    835         $this->decrement_update_count( 'translation' );
    836         $update_actions = array();
    837         $update_actions['updates_page'] = '<a href="' . self_admin_url( 'update-core.php' ) . '" target="_parent">' . __( 'Return to WordPress Updates page' ) . '</a>';
    838 
    839         /**
    840          * Filter the list of action links available following a translations update.
    841          *
    842          * @since 3.7.0
    843          *
    844          * @param array $update_actions Array of translations update links.
    845          */
    846         $update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
    847 
    848         if ( $update_actions && $this->display_footer_actions )
    849             $this->feedback( implode( ' | ', $update_actions ) );
    850     }
    851 }
    852 
    853 /**
    854  * Upgrader Skin for Automatic WordPress Upgrades
    855  *
    856  * This skin is designed to be used when no output is intended, all output
    857  * is captured and stored for the caller to process and log/email/discard.
    858  *
    859  * @package WordPress
    860  * @subpackage Upgrader
    861  * @since 3.7.0
    862  */
    863 class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
    864     protected $messages = array();
    865 
    866     /**
    867      *
    868      * @param bool   $error
    869      * @param string $context
    870      * @param bool   $allow_relaxed_file_ownership
    871      * @return bool
    872      */
    873     public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
    874         if ( $context ) {
    875             $this->options['context'] = $context;
    876         }
    877         // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    878         // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    879         ob_start();
    880         $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    881         ob_end_clean();
    882         return $result;
    883     }
    884 
    885     /**
    886      * @access public
    887      *
    888      * @return array
    889      */
    890     public function get_upgrade_messages() {
    891         return $this->messages;
    892     }
    893 
    894     /**
    895      * @param string|array|WP_Error $data
    896      */
    897     public function feedback( $data ) {
    898         if ( is_wp_error( $data ) ) {
    899             $string = $data->get_error_message();
    900         } elseif ( is_array( $data ) ) {
    901             return;
    902         } else {
    903             $string = $data;
    904         }
    905         if ( ! empty( $this->upgrader->strings[ $string ] ) )
    906             $string = $this->upgrader->strings[ $string ];
    907 
    908         if ( strpos( $string, '%' ) !== false ) {
    909             $args = func_get_args();
    910             $args = array_splice( $args, 1 );
    911             if ( ! empty( $args ) )
    912                 $string = vsprintf( $string, $args );
    913         }
    914 
    915         $string = trim( $string );
    916 
    917         // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
    918         $string = wp_kses( $string, array(
    919             'a' => array(
    920                 'href' => true
    921             ),
    922             'br' => true,
    923             'em' => true,
    924             'strong' => true,
    925         ) );
    926 
    927         if ( empty( $string ) )
    928             return;
    929 
    930         $this->messages[] = $string;
    931     }
    932 
    933     /**
    934      * @access public
    935      */
    936     public function header() {
    937         ob_start();
    938     }
    939 
    940     /**
    941      * @access public
    942      */
    943     public function footer() {
    944         $output = ob_get_clean();
    945         if ( ! empty( $output ) )
    946             $this->feedback( $output );
    947     }
    948 }
  • trunk/src/wp-admin/includes/class-theme-installer-skin.php

    r37383 r37406  
    77 * @since 2.8.0
    88 */
    9 
    10 /**
    11  * Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
    12  *
    13  * @package WordPress
    14  * @subpackage Upgrader
    15  * @since 2.8.0
    16  */
    17 class WP_Upgrader_Skin {
    18 
    19     public $upgrader;
    20     public $done_header = false;
    21     public $done_footer = false;
    22     public $result = false;
    23     public $options = array();
    24 
    25     /**
    26      *
    27      * @param array $args
    28      */
    29     public function __construct($args = array()) {
    30         $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
    31         $this->options = wp_parse_args($args, $defaults);
    32     }
    33 
    34     /**
    35      * @param WP_Upgrader $upgrader
    36      */
    37     public function set_upgrader(&$upgrader) {
    38         if ( is_object($upgrader) )
    39             $this->upgrader =& $upgrader;
    40         $this->add_strings();
    41     }
    42 
    43     /**
    44      * @access public
    45      */
    46     public function add_strings() {
    47     }
    48 
    49     /**
    50      *
    51      * @param string|false|WP_Error $result
    52      */
    53     public function set_result($result) {
    54         $this->result = $result;
    55     }
    56 
    57     /**
    58      *
    59      * @param bool   $error
    60      * @param string $context
    61      * @param bool   $allow_relaxed_file_ownership
    62      * @return type
    63      */
    64     public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    65         $url = $this->options['url'];
    66         if ( ! $context ) {
    67             $context = $this->options['context'];
    68         }
    69         if ( !empty($this->options['nonce']) ) {
    70             $url = wp_nonce_url($url, $this->options['nonce']);
    71         }
    72 
    73         $extra_fields = array();
    74 
    75         return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    76     }
    77 
    78     /**
    79      * @access public
    80      */
    81     public function header() {
    82         if ( $this->done_header ) {
    83             return;
    84         }
    85         $this->done_header = true;
    86         echo '<div class="wrap">';
    87         echo '<h1>' . $this->options['title'] . '</h1>';
    88     }
    89 
    90     /**
    91      * @access public
    92      */
    93     public function footer() {
    94         if ( $this->done_footer ) {
    95             return;
    96         }
    97         $this->done_footer = true;
    98         echo '</div>';
    99     }
    100 
    101     /**
    102      *
    103      * @param string|WP_Error $errors
    104      */
    105     public function error($errors) {
    106         if ( ! $this->done_header )
    107             $this->header();
    108         if ( is_string($errors) ) {
    109             $this->feedback($errors);
    110         } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
    111             foreach ( $errors->get_error_messages() as $message ) {
    112                 if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) )
    113                     $this->feedback($message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
    114                 else
    115                     $this->feedback($message);
    116             }
    117         }
    118     }
    119 
    120     /**
    121      *
    122      * @param string $string
    123      */
    124     public function feedback($string) {
    125         if ( isset( $this->upgrader->strings[$string] ) )
    126             $string = $this->upgrader->strings[$string];
    127 
    128         if ( strpos($string, '%') !== false ) {
    129             $args = func_get_args();
    130             $args = array_splice($args, 1);
    131             if ( $args ) {
    132                 $args = array_map( 'strip_tags', $args );
    133                 $args = array_map( 'esc_html', $args );
    134                 $string = vsprintf($string, $args);
    135             }
    136         }
    137         if ( empty($string) )
    138             return;
    139         show_message($string);
    140     }
    141 
    142     /**
    143      * @access public
    144      */
    145     public function before() {}
    146 
    147     /**
    148      * @access public
    149      */
    150     public function after() {}
    151 
    152     /**
    153      * Output JavaScript that calls function to decrement the update counts.
    154      *
    155      * @since 3.9.0
    156      *
    157      * @param string $type Type of update count to decrement. Likely values include 'plugin',
    158      *                     'theme', 'translation', etc.
    159      */
    160     protected function decrement_update_count( $type ) {
    161         if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
    162             return;
    163         }
    164 
    165         if ( defined( 'IFRAME_REQUEST' ) ) {
    166             echo '<script type="text/javascript">
    167                     if ( window.postMessage && JSON ) {
    168                         window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
    169                     }
    170                 </script>';
    171         } else {
    172             echo '<script type="text/javascript">
    173                     (function( wp ) {
    174                         if ( wp && wp.updates.decrementCount ) {
    175                             wp.updates.decrementCount( "' . $type . '" );
    176                         }
    177                     })( window.wp );
    178                 </script>';
    179         }
    180     }
    181 
    182     /**
    183      * @access public
    184      */
    185     public function bulk_header() {}
    186 
    187     /**
    188      * @access public
    189      */
    190     public function bulk_footer() {}
    191 }
    192 
    193 /**
    194  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    195  *
    196  * @package WordPress
    197  * @subpackage Upgrader
    198  * @since 2.8.0
    199  */
    200 class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
    201     public $plugin = '';
    202     public $plugin_active = false;
    203     public $plugin_network_active = false;
    204 
    205     /**
    206      *
    207      * @param array $args
    208      */
    209     public function __construct( $args = array() ) {
    210         $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Update Plugin') );
    211         $args = wp_parse_args($args, $defaults);
    212 
    213         $this->plugin = $args['plugin'];
    214 
    215         $this->plugin_active = is_plugin_active( $this->plugin );
    216         $this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
    217 
    218         parent::__construct($args);
    219     }
    220 
    221     /**
    222      * @access public
    223      */
    224     public function after() {
    225         $this->plugin = $this->upgrader->plugin_info();
    226         if ( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
    227             // Currently used only when JS is off for a single plugin update?
    228             echo '<iframe title="' . esc_attr__( 'Update progress' ) . '" style="border:0;overflow:hidden" width="100%" height="170" src="' . wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ) . '"></iframe>';
    229         }
    230 
    231         $this->decrement_update_count( 'plugin' );
    232 
    233         $update_actions =  array(
    234             'activate_plugin' => '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin) . '" target="_parent">' . __( 'Activate Plugin' ) . '</a>',
    235             'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    236         );
    237         if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
    238             unset( $update_actions['activate_plugin'] );
    239 
    240         /**
    241          * Filter the list of action links available following a single plugin update.
    242          *
    243          * @since 2.7.0
    244          *
    245          * @param array  $update_actions Array of plugin action links.
    246          * @param string $plugin         Path to the plugin file.
    247          */
    248         $update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
    249 
    250         if ( ! empty($update_actions) )
    251             $this->feedback(implode(' | ', (array)$update_actions));
    252     }
    253 }
    254 
    255 /**
    256  * Plugin Upgrader Skin for WordPress Plugin Upgrades.
    257  *
    258  * @package WordPress
    259  * @subpackage Upgrader
    260  * @since 3.0.0
    261  */
    262 class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
    263     public $in_loop = false;
    264     /**
    265      * @var string|false
    266      */
    267     public $error = false;
    268 
    269     /**
    270      *
    271      * @param array $args
    272      */
    273     public function __construct($args = array()) {
    274         $defaults = array( 'url' => '', 'nonce' => '' );
    275         $args = wp_parse_args($args, $defaults);
    276 
    277         parent::__construct($args);
    278     }
    279 
    280     /**
    281      * @access public
    282      */
    283     public function add_strings() {
    284         $this->upgrader->strings['skin_upgrade_start'] = __('The update process is starting. This process may take a while on some hosts, so please be patient.');
    285         /* translators: 1: Title of an update, 2: Error message */
    286         $this->upgrader->strings['skin_update_failed_error'