<!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-&gt;plugin_count = count($plugins);
-                $this-&gt;plugin_current = 0;
</del><ins>+                $this-&gt;update_count = count($plugins);
+                $this-&gt;update_current = 0;
</ins><span class="cx">                 foreach ( $plugins as $plugin ) {
</span><del>-                        $this-&gt;plugin_current++;
</del><ins>+                        $this-&gt;update_current++;
</ins><span class="cx">                         $this-&gt;skin-&gt;plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true);
</span><span class="cx"> 
</span><span class="cx">                         if ( !isset( $current-&gt;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-&gt;init();
+                $this-&gt;bulk = true;
+                $this-&gt;upgrade_strings();
+
+                $current = get_site_transient( 'update_themes' );
+
+                add_filter('upgrader_pre_install', array(&amp;$this, 'current_before'), 10, 2);
+                add_filter('upgrader_post_install', array(&amp;$this, 'current_after'), 10, 2);
+                add_filter('upgrader_clear_destination', array(&amp;$this, 'delete_old_theme'), 10, 4);
+
+                $this-&gt;skin-&gt;header();
+
+                // Connect to the Filesystem first.
+                $res = $this-&gt;fs_connect( array(WP_CONTENT_DIR) );
+                if ( ! $res ) {
+                        $this-&gt;skin-&gt;footer();
+                        return false;
+                }
+
+                $this-&gt;maintenance_mode(true);
+
+                $results = array();
+
+                $this-&gt;update_count = count($themes);
+                $this-&gt;update_current = 0;
+                foreach ( $themes as $theme ) {
+                        $this-&gt;update_current++;
+
+                        if ( !isset( $current-&gt;response[ $theme ] ) ) {
+                                $this-&gt;skin-&gt;set_result(false);
+                                $this-&gt;skin-&gt;before();
+                                $this-&gt;skin-&gt;error('up_to_date');
+                                $this-&gt;skin-&gt;after();
+                                $results[$theme] = false;
+                                continue;
+                        }
+
+                        $this-&gt;skin-&gt;theme_info = $this-&gt;theme_info($theme);
+
+                        // Get the URL to the zip file
+                        $r = $current-&gt;response[ $theme ];
+
+                        $options = array(
+                                                        'package' =&gt; $r['package'],
+                                                        'destination' =&gt; WP_CONTENT_DIR . '/themes',
+                                                        'clear_destination' =&gt; true,
+                                                        'clear_working' =&gt; true,
+                                                        'hook_extra' =&gt; array(
+                                                                                                'theme' =&gt; $theme
+                                                                                                )
+                                                        );
+
+                        $result = $this-&gt;run($options);
+
+                        $results[$theme] = $this-&gt;result;
+
+                        // Prevent credentials auth screen from displaying multiple times
+                        if ( false === $result )
+                                break;
+                } //end foreach $plugins
+                $this-&gt;maintenance_mode(false);
+                $this-&gt;skin-&gt;footer();
+
+                // Cleanup our hooks, incase something else does a upgrade on this connection.
+                remove_filter('upgrader_pre_install', array(&amp;$this, 'current_before'), 10, 2);
+                remove_filter('upgrader_post_install', array(&amp;$this, 'current_after'), 10, 2);
+                remove_filter('upgrader_clear_destination', array(&amp;$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-&gt;maintenance_mode(true);
</del><ins>+                if ( ! $this-&gt;bulk )
+                        $this-&gt;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-&gt;maintenance_mode(false);
</del><ins>+                if ( ! $this-&gt;bulk )
+                        $this-&gt;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-&gt;result['destination_name']) )
-                        return false;
-                return get_theme_data(WP_CONTENT_DIR . '/themes/' . $this-&gt;result['destination_name'] . '/style.css');
</del><ins>+        function theme_info($theme = null) {
+
+                if ( empty($theme) ) {
+                        if ( !empty($this-&gt;result['destination_name']) )
+                                $theme = $this-&gt;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(&amp;$upgrader) {
</span><span class="cx">                 if ( is_object($upgrader) )
</span><span class="cx">                         $this-&gt;upgrader =&amp; $upgrader;
</span><ins>+                $this-&gt;add_strings();
</ins><span class="cx">         }
</span><ins>+
+        function add_strings() {
+        }
+
</ins><span class="cx">         function set_result($result) {
</span><span class="cx">                 $this-&gt;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-&gt;__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-&gt;upgrader-&gt;strings['skin_update_failed_error'] = __('An error occured while updating %1$s: &lt;strong&gt;%2$s&lt;/strong&gt;.');
+                $this-&gt;upgrader-&gt;strings['skin_update_failed'] = __('The update of %1$s failed.');
+                $this-&gt;upgrader-&gt;strings['skin_update_successful'] = __('%1$s updated successfully. &lt;a onclick=&quot;%2$s&quot; href=&quot;#&quot;&gt;See Details&lt;/a&gt;.');
+        }
+
</ins><span class="cx">         function feedback($string) {
</span><span class="cx">                 if ( isset( $this-&gt;upgrader-&gt;strings[$string] ) )
</span><span class="cx">                         $string = $this-&gt;upgrader-&gt;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-&gt;in_loop = true;
</span><del>-                printf( '&lt;h4&gt;' . __('Updating Plugin %1$s (%2$d/%3$d)') . '&lt;/h4&gt;',  $this-&gt;plugin_info['Title'], $this-&gt;upgrader-&gt;plugin_current, $this-&gt;upgrader-&gt;plugin_count);
-                echo '&lt;div class=&quot;update-messages&quot; style=&quot;display:none&quot; id=&quot;progress-' . esc_attr($this-&gt;upgrader-&gt;plugin_current) . '&quot;&gt;&lt;p&gt;';
</del><ins>+                printf( '&lt;h4&gt;' . $this-&gt;upgrader-&gt;strings['skin_before_update_header'] . '&lt;/h4&gt;',  $title, $this-&gt;upgrader-&gt;update_current, $this-&gt;upgrader-&gt;update_count);
+                echo '&lt;div class=&quot;update-messages&quot; style=&quot;display:none&quot; id=&quot;progress-' . esc_attr($this-&gt;upgrader-&gt;update_current) . '&quot;&gt;&lt;p&gt;';
</ins><span class="cx">                 $this-&gt;flush_output();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        function after() {
</del><ins>+        function after($title = '') {
</ins><span class="cx">                 echo '&lt;/p&gt;&lt;/div&gt;';
</span><span class="cx">                 if ( $this-&gt;error || ! $this-&gt;result ) {
</span><span class="cx">                         if ( $this-&gt;error )
</span><del>-                                echo '&lt;div class=&quot;error&quot;&gt;&lt;p&gt;' . sprintf(__('An error occured while updating %1$s: &lt;strong&gt;%2$s&lt;/strong&gt;.'), $this-&gt;plugin_info['Title'], $this-&gt;error) . '&lt;/p&gt;&lt;/div&gt;';
</del><ins>+                                echo '&lt;div class=&quot;error&quot;&gt;&lt;p&gt;' . sprintf($this-&gt;upgrader-&gt;strings['skin_update_failed'], $title, $this-&gt;error) . '&lt;/p&gt;&lt;/div&gt;';
</ins><span class="cx">                         else
</span><del>-                                echo '&lt;div class=&quot;error&quot;&gt;&lt;p&gt;' . sprintf(__('The update of %1$s failed.'), $this-&gt;plugin_info['Title']) . '&lt;/p&gt;&lt;/div&gt;';
-                        echo '&lt;script type=&quot;text/javascript&quot;&gt;jQuery(\'#progress-' . esc_js($this-&gt;upgrader-&gt;plugin_current) . '\').show();&lt;/script&gt;';
</del><ins>+                                echo '&lt;div class=&quot;error&quot;&gt;&lt;p&gt;' . sprintf($this-&gt;upgrader-&gt;strings['skin_update_failed'], $title) . '&lt;/p&gt;&lt;/div&gt;';
+
+                        echo '&lt;script type=&quot;text/javascript&quot;&gt;jQuery(\'#progress-' . esc_js($this-&gt;upgrader-&gt;update_current) . '\').show();&lt;/script&gt;';
</ins><span class="cx">                 }
</span><span class="cx">                 if ( !empty($this-&gt;result) &amp;&amp; !is_wp_error($this-&gt;result) ) {
</span><del>-                        echo '&lt;div class=&quot;updated&quot;&gt;&lt;p&gt;' . sprintf(__('%1$s updated successfully. &lt;a onclick=&quot;%2$s&quot; href=&quot;#&quot;&gt;See Details&lt;/a&gt;.'), $this-&gt;plugin_info['Title'], 'jQuery(\'#progress-' . esc_js($this-&gt;upgrader-&gt;plugin_current) . '\').toggle(); return false;') . '&lt;/p&gt;&lt;/div&gt;';
</del><ins>+                        echo '&lt;div class=&quot;updated&quot;&gt;&lt;p&gt;' . sprintf($this-&gt;upgrader-&gt;strings['skin_update_successful'], $title, 'jQuery(\'#progress-' . esc_js($this-&gt;upgrader-&gt;update_current) . '\').toggle(); return false;') . '&lt;/p&gt;&lt;/div&gt;';
</ins><span class="cx">                 }
</span><span class="cx">                 $this-&gt;reset();
</span><span class="cx">                 $this-&gt;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-&gt;upgrader-&gt;strings['skin_before_update_header'] = __('Updating Plugin %1$s (%2$d/%3$d)');
+        }
+
+        function before() {
+                parent::before($this-&gt;plugin_info['Title']);
+        }
+
+        function after() {
+                parent::after($this-&gt;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-&gt;upgrader-&gt;strings['skin_before_update_header'] = __('Updating Theme %1$s (%2$d/%3$d)');
+        }
+
+        function before() {
+                parent::before($this-&gt;theme_info['Name']);
+        }
+
+        function after() {
+                parent::after($this-&gt;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 '&lt;div class=&quot;wrap&quot;&gt;';
</span><span class="cx">         screen_icon('themes');
</span><span class="cx">         echo '&lt;h2&gt;' . esc_html__('Update Themes') . '&lt;/h2&gt;';
</span><del>-        echo &quot;&lt;p&gt;@TODO: Sorry, This part of the functionality hasnt been written yet.&lt;/p&gt;&quot;;
</del><span class="cx">         echo &quot;&lt;iframe src='$url' style='width: 100%; height:100%; min-height:850px;'&gt;&lt;/iframe&gt;&quot;;
</span><span class="cx">         echo '&lt;/div&gt;';
</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-&gt;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-&gt;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;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-&gt;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>