<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[13686] trunk/wp-admin: Bulk Theme Upgrades.</title>
</head>
<body>
<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/13686">13686</a></dd>
<dt>Author</dt> <dd>dd32</dd>
<dt>Date</dt> <dd>2010-03-13 03:59:40 +0000 (Sat, 13 Mar 2010)</dd>
</dl>
<h3>Log Message</h3>
<pre>Bulk Theme Upgrades. See <a href="http://trac.wordpress.org/ticket/12528">#12528</a> See <a href="http://trac.wordpress.org/ticket/11232">#11232</a> for Bulk UI</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpadminincludesclasswpupgraderphp">trunk/wp-admin/includes/class-wp-upgrader.php</a></li>
<li><a href="#trunkwpadminupdatecorephp">trunk/wp-admin/update-core.php</a></li>
<li><a href="#trunkwpadminupdatephp">trunk/wp-admin/update.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpadminincludesclasswpupgraderphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/includes/class-wp-upgrader.php (13685 => 13686)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/includes/class-wp-upgrader.php        2010-03-12 21:57:52 UTC (rev 13685)
+++ trunk/wp-admin/includes/class-wp-upgrader.php        2010-03-13 03:59:40 UTC (rev 13686)
</span><span class="lines">@@ -469,10 +469,10 @@
</span><span class="cx">
</span><span class="cx">                 $results = array();
</span><span class="cx">
</span><del>-                $this->plugin_count = count($plugins);
-                $this->plugin_current = 0;
</del><ins>+                $this->update_count = count($plugins);
+                $this->update_current = 0;
</ins><span class="cx">                 foreach ( $plugins as $plugin ) {
</span><del>-                        $this->plugin_current++;
</del><ins>+                        $this->update_current++;
</ins><span class="cx">                         $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true);
</span><span class="cx">
</span><span class="cx">                         if ( !isset( $current->response[ $plugin ] ) ) {
</span><span class="lines">@@ -682,6 +682,82 @@
</span><span class="cx">                 return true;
</span><span class="cx">         }
</span><span class="cx">
</span><ins>+        function bulk_upgrade($themes) {
+
+                $this->init();
+                $this->bulk = true;
+                $this->upgrade_strings();
+
+                $current = get_site_transient( 'update_themes' );
+
+                add_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2);
+                add_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2);
+                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4);
+
+                $this->skin->header();
+
+                // Connect to the Filesystem first.
+                $res = $this->fs_connect( array(WP_CONTENT_DIR) );
+                if ( ! $res ) {
+                        $this->skin->footer();
+                        return false;
+                }
+
+                $this->maintenance_mode(true);
+
+                $results = array();
+
+                $this->update_count = count($themes);
+                $this->update_current = 0;
+                foreach ( $themes as $theme ) {
+                        $this->update_current++;
+
+                        if ( !isset( $current->response[ $theme ] ) ) {
+                                $this->skin->set_result(false);
+                                $this->skin->before();
+                                $this->skin->error('up_to_date');
+                                $this->skin->after();
+                                $results[$theme] = false;
+                                continue;
+                        }
+
+                        $this->skin->theme_info = $this->theme_info($theme);
+
+                        // Get the URL to the zip file
+                        $r = $current->response[ $theme ];
+
+                        $options = array(
+                                                        'package' => $r['package'],
+                                                        'destination' => WP_CONTENT_DIR . '/themes',
+                                                        'clear_destination' => true,
+                                                        'clear_working' => true,
+                                                        'hook_extra' => array(
+                                                                                                'theme' => $theme
+                                                                                                )
+                                                        );
+
+                        $result = $this->run($options);
+
+                        $results[$theme] = $this->result;
+
+                        // Prevent credentials auth screen from displaying multiple times
+                        if ( false === $result )
+                                break;
+                } //end foreach $plugins
+                $this->maintenance_mode(false);
+                $this->skin->footer();
+
+                // Cleanup our hooks, incase something else does a upgrade on this connection.
+                remove_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2);
+                remove_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2);
+                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4);
+
+                // Force refresh of theme update information
+                delete_site_transient('update_themes');
+
+                return $results;
+        }
+
</ins><span class="cx">         function current_before($return, $theme) {
</span><span class="cx">
</span><span class="cx">                 if ( is_wp_error($return) )
</span><span class="lines">@@ -692,7 +768,8 @@
</span><span class="cx">                 if ( $theme != get_stylesheet() ) //If not current
</span><span class="cx">                         return $return;
</span><span class="cx">                 //Change to maintainence mode now.
</span><del>-                $this->maintenance_mode(true);
</del><ins>+                if ( ! $this->bulk )
+                        $this->maintenance_mode(true);
</ins><span class="cx">
</span><span class="cx">                 return $return;
</span><span class="cx">         }
</span><span class="lines">@@ -714,7 +791,8 @@
</span><span class="cx">                 }
</span><span class="cx">
</span><span class="cx">                 //Time to remove maintainence mode
</span><del>-                $this->maintenance_mode(false);
</del><ins>+                if ( ! $this->bulk )
+                        $this->maintenance_mode(false);
</ins><span class="cx">                 return $return;
</span><span class="cx">         }
</span><span class="cx">
</span><span class="lines">@@ -733,10 +811,15 @@
</span><span class="cx">                 return true;
</span><span class="cx">         }
</span><span class="cx">
</span><del>-        function theme_info() {
-                if ( empty($this->result['destination_name']) )
-                        return false;
-                return get_theme_data(WP_CONTENT_DIR . '/themes/' . $this->result['destination_name'] . '/style.css');
</del><ins>+        function theme_info($theme = null) {
+
+                if ( empty($theme) ) {
+                        if ( !empty($this->result['destination_name']) )
+                                $theme = $this->result['destination_name'];
+                        else
+                                return false;
+                }
+                return get_theme_data(WP_CONTENT_DIR . '/themes/' . $theme . '/style.css');
</ins><span class="cx">         }
</span><span class="cx">
</span><span class="cx"> }
</span><span class="lines">@@ -826,7 +909,12 @@
</span><span class="cx">         function set_upgrader(&$upgrader) {
</span><span class="cx">                 if ( is_object($upgrader) )
</span><span class="cx">                         $this->upgrader =& $upgrader;
</span><ins>+                $this->add_strings();
</ins><span class="cx">         }
</span><ins>+
+        function add_strings() {
+        }
+
</ins><span class="cx">         function set_result($result) {
</span><span class="cx">                 $this->result = $result;
</span><span class="cx">         }
</span><span class="lines">@@ -949,11 +1037,11 @@
</span><span class="cx"> * @subpackage Upgrader
</span><span class="cx"> * @since 3.0
</span><span class="cx"> */
</span><del>-class Bulk_Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
</del><ins>+class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
</ins><span class="cx">         var $in_loop = false;
</span><span class="cx">         var $error = false;
</span><span class="cx">
</span><del>-        function Plugin_Upgrader_Skin($args = array()) {
</del><ins>+        function Bulk_Upgrader_Skin($args = array()) {
</ins><span class="cx">                 return $this->__construct($args);
</span><span class="cx">         }
</span><span class="cx">
</span><span class="lines">@@ -963,7 +1051,13 @@
</span><span class="cx">
</span><span class="cx">                 parent::__construct($args);
</span><span class="cx">         }
</span><del>-        
</del><ins>+
+        function add_strings() {
+                $this->upgrader->strings['skin_update_failed_error'] = __('An error occured while updating %1$s: <strong>%2$s</strong>.');
+                $this->upgrader->strings['skin_update_failed'] = __('The update of %1$s failed.');
+                $this->upgrader->strings['skin_update_successful'] = __('%1$s updated successfully. <a onclick="%2$s" href="#">See Details</a>.');
+        }
+
</ins><span class="cx">         function feedback($string) {
</span><span class="cx">                 if ( isset( $this->upgrader->strings[$string] ) )
</span><span class="cx">                         $string = $this->upgrader->strings[$string];
</span><span class="lines">@@ -1004,24 +1098,25 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx">
</span><del>-        function before() {
</del><ins>+        function before($title = '') {
</ins><span class="cx">                 $this->in_loop = true;
</span><del>-                printf( '<h4>' . __('Updating Plugin %1$s (%2$d/%3$d)') . '</h4>', $this->plugin_info['Title'], $this->upgrader->plugin_current, $this->upgrader->plugin_count);
-                echo '<div class="update-messages" style="display:none" id="progress-' . esc_attr($this->upgrader->plugin_current) . '"><p>';
</del><ins>+                printf( '<h4>' . $this->upgrader->strings['skin_before_update_header'] . '</h4>', $title, $this->upgrader->update_current, $this->upgrader->update_count);
+                echo '<div class="update-messages" style="display:none" id="progress-' . esc_attr($this->upgrader->update_current) . '"><p>';
</ins><span class="cx">                 $this->flush_output();
</span><span class="cx">         }
</span><span class="cx">
</span><del>-        function after() {
</del><ins>+        function after($title = '') {
</ins><span class="cx">                 echo '</p></div>';
</span><span class="cx">                 if ( $this->error || ! $this->result ) {
</span><span class="cx">                         if ( $this->error )
</span><del>-                                echo '<div class="error"><p>' . sprintf(__('An error occured while updating %1$s: <strong>%2$s</strong>.'), $this->plugin_info['Title'], $this->error) . '</p></div>';
</del><ins>+                                echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title, $this->error) . '</p></div>';
</ins><span class="cx">                         else
</span><del>-                                echo '<div class="error"><p>' . sprintf(__('The update of %1$s failed.'), $this->plugin_info['Title']) . '</p></div>';
-                        echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->plugin_current) . '\').show();</script>';
</del><ins>+                                echo '<div class="error"><p>' . sprintf($this->upgrader->strings['skin_update_failed'], $title) . '</p></div>';
+
+                        echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').show();</script>';
</ins><span class="cx">                 }
</span><span class="cx">                 if ( !empty($this->result) && !is_wp_error($this->result) ) {
</span><del>-                        echo '<div class="updated"><p>' . sprintf(__('%1$s updated successfully. <a onclick="%2$s" href="#">See Details</a>.'), $this->plugin_info['Title'], 'jQuery(\'#progress-' . esc_js($this->upgrader->plugin_current) . '\').toggle(); return false;') . '</p></div>';
</del><ins>+                        echo '<div class="updated"><p>' . sprintf($this->upgrader->strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this->upgrader->update_current) . '\').toggle(); return false;') . '</p></div>';
</ins><span class="cx">                 }
</span><span class="cx">                 $this->reset();
</span><span class="cx">                 $this->flush_output();
</span><span class="lines">@@ -1036,9 +1131,48 @@
</span><span class="cx">                 wp_ob_end_flush_all();
</span><span class="cx">                 flush();
</span><span class="cx">         }
</span><ins>+}
</ins><span class="cx">
</span><ins>+class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
+        var $plugin_info = array(); // Plugin_Upgrader::bulk() will fill this in.
+        function Plugin_Upgrader_Skin($args = array()) {
+                parent::__construct($args);
+        }
+
+        function add_strings() {
+                parent::add_strings();
+                $this->upgrader->strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
+        }
+
+        function before() {
+                parent::before($this->plugin_info['Title']);
+        }
+
+        function after() {
+                parent::after($this->plugin_info['Title']);
+        }
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
+        var $theme_info = array(); // Theme_Upgrader::bulk() will fill this in.
+        function Theme_Upgrader_Skin($args = array()) {
+                parent::__construct($args);
+        }
+
+        function add_strings() {
+                parent::add_strings();
+                $this->upgrader->strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
+        }
+
+        function before() {
+                parent::before($this->theme_info['Name']);
+        }
+
+        function after() {
+                parent::after($this->theme_info['Name']);
+        }
+}
+
</ins><span class="cx"> /**
</span><span class="cx"> * Plugin Installer Skin for WordPress Plugin Installer.
</span><span class="cx"> *
</span></span></pre></div>
<a id="trunkwpadminupdatecorephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/update-core.php (13685 => 13686)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/update-core.php        2010-03-12 21:57:52 UTC (rev 13685)
+++ trunk/wp-admin/update-core.php        2010-03-13 03:59:40 UTC (rev 13686)
</span><span class="lines">@@ -441,7 +441,6 @@
</span><span class="cx">         echo '<div class="wrap">';
</span><span class="cx">         screen_icon('themes');
</span><span class="cx">         echo '<h2>' . esc_html__('Update Themes') . '</h2>';
</span><del>-        echo "<p>@TODO: Sorry, This part of the functionality hasnt been written yet.</p>";
</del><span class="cx">         echo "<iframe src='$url' style='width: 100%; height:100%; min-height:850px;'></iframe>";
</span><span class="cx">         echo '</div>';
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkwpadminupdatephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/update.php (13685 => 13686)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/update.php        2010-03-12 21:57:52 UTC (rev 13685)
+++ trunk/wp-admin/update.php        2010-03-13 03:59:40 UTC (rev 13686)
</span><span class="lines">@@ -42,7 +42,6 @@
</span><span class="cx">                 $upgrader->bulk_upgrade( $plugins );
</span><span class="cx">
</span><span class="cx">                 iframe_footer();
</span><del>-                exit;
</del><span class="cx">                         
</span><span class="cx">         } elseif ( 'upgrade-plugin' == $action ) {
</span><span class="cx">                 if ( ! current_user_can('update_plugins') )
</span><span class="lines">@@ -163,7 +162,32 @@
</span><span class="cx">                 $upgrader->upgrade($theme);
</span><span class="cx">
</span><span class="cx">                 include('admin-footer.php');
</span><ins>+        } elseif ( 'update-selected-themes' == $action ) {
+                if ( ! current_user_can( 'update_themes' ) )
+                        wp_die( __( 'You do not have sufficient permissions to update themes for this blog.' ) );
</ins><span class="cx">
</span><ins>+                check_admin_referer( 'bulk-update-themes' );
+
+                if ( isset( $_GET['themes'] ) )
+                        $themes = explode( ',', stripslashes($_GET['themes']) );
+                elseif ( isset( $_POST['checked'] ) )
+                        $themes = (array) $_POST['checked'];
+                else
+                        $themes = array();
+
+                $themes = array_map('urldecode', $themes);
+
+                $url = 'update.php?action=update-selected-themes&amp;themess=' . urlencode(implode(',', $themes));
+                $nonce = 'bulk-update-themes';
+
+                require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
+                wp_enqueue_script('jquery');
+                iframe_header();
+
+                $upgrader = new Theme_Upgrader( new Bulk_Theme_Upgrader_Skin( compact( 'nonce', 'url' ) ) );
+                $upgrader->bulk_upgrade( $themes );
+
+                iframe_footer();
</ins><span class="cx">         } elseif ( 'install-theme' == $action ) {
</span><span class="cx">
</span><span class="cx">                 if ( ! current_user_can('install_themes') )
</span></span></pre>
</div>
</div>
</body>
</html>