Make WordPress Core

Ticket #7875: 7875.4.diff

File 7875.4.diff, 88.5 KB (added by DD32, 15 years ago)
  • wp-admin/includes/class-wp-filesystem-ftpext.php

     
    1414 * @subpackage Filesystem
    1515 * @uses WP_Filesystem_Base Extends class
    1616 */
    17 class WP_Filesystem_FTPext extends WP_Filesystem_Base {
     17class _WP_Filesystem_FTPext extends WP_Filesystem_Base {
    1818        var $link;
    1919        var $timeout = 5;
    20         var $errors = array();
     20        var $errors = null;
    2121        var $options = array();
    2222
    2323        var $permission = null;
     
    6565        }
    6666
    6767        function connect() {
    68                 if ( $this->options['ssl'] && function_exists('ftp_ssl_connect') )
     68                if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    6969                        $this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'],$this->timeout);
    7070                else
    7171                        $this->link = @ftp_connect($this->options['hostname'], $this->options['port'],$this->timeout);
     
    187187                return ftp_rename($this->link, $source, $destination);
    188188        }
    189189
    190         function delete($file,$recursive=false) {
     190        function delete($file, $recursive = false ) {
     191                if ( empty($file) )
     192                        return false;
    191193                if ( $this->is_file($file) )
    192194                        return @ftp_delete($this->link, $file);
    193195                if ( !$recursive )
    194196                        return @ftp_rmdir($this->link, $file);
    195                 $filelist = $this->dirlist($file);
    196                 foreach ((array) $filelist as $filename => $fileinfo) {
    197                         $this->delete($file . '/' . $filename, $recursive);
    198                 }
     197
     198                $filelist = $this->dirlist( trailingslashit($file) );
     199                if ( !empty($filelist) )
     200                        foreach ( $filelist as $delete_file )
     201                                $this->delete( trailingslashit($file) . $delete_file['name'], $recursive);
    199202                return @ftp_rmdir($this->link, $file);
    200203        }
    201204
    202205        function exists($file) {
    203                 $list = ftp_rawlist($this->link, $file, false);
    204                 if( ! $list )
    205                         return false;
    206                 return count($list) == 1 ? true : false;
     206                $list = @ftp_rawlist($this->link, $file, false);
     207                return !empty($list); //empty list = no file, so invert.
    207208        }
    208209        function is_file($file) {
    209                 return $this->is_dir($file) ? false : true;
     210                return $this->exists($file) && !$this->is_dir($file);
    210211        }
    211212        function is_dir($path) {
    212213                $cwd = $this->cwd();
    213                 $result = @ftp_chdir($this->link, $path);
     214                $result = @ftp_chdir($this->link, trailingslashit($path) );
    214215                if( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
    215216                        @ftp_chdir($this->link, $cwd);
    216217                        return true;
     
    218219                return false;
    219220        }
    220221        function is_readable($file) {
    221                 //Get dir list, Check if the file is writable by the current user??
     222                //Get dir list, Check if the file is readable by the current user??
    222223                return true;
    223224        }
    224225        function is_writable($file) {
     
    238239                return false;
    239240        }
    240241        function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
    241                 if( !@ftp_mkdir($this->link, $path) )
     242                if( !ftp_mkdir($this->link, $path) )
    242243                        return false;
    243244                if( $chmod )
    244245                        $this->chmod($path, $chmod);
     
    249250                return true;
    250251        }
    251252        function rmdir($path, $recursive = false) {
    252                 if( ! $recursive )
    253                         return @ftp_rmdir($this->link, $path);
    254 
    255                 //TODO: Recursive Directory delete, Have to delete files from the folder first.
    256                 //$dir = $this->dirlist($path);
    257                 //foreach($dir as $file)
    258 
     253                return $this->delete($path, $recursive);
    259254        }
    260255
    261256        function parselisting($line) {
    262                 $is_windows = ($this->OS_remote == FTP_OS_Windows);
     257                static $is_windows;
     258                if ( is_null($is_windows) )
     259                        $is_windows = strpos( strtolower(ftp_systype($this->link)), 'win') !== false;
     260
    263261                if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/", $line, $lucifer)) {
    264262                        $b = array();
    265263                        if ($lucifer[3]<70) { $lucifer[3] +=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
  • wp-admin/includes/class-wp-filesystem-ftpsockets.php

     
    1717class WP_Filesystem_ftpsockets extends WP_Filesystem_Base {
    1818        var $ftp = false;
    1919        var $timeout = 5;
    20         var $errors;
     20        var $errors = null;
    2121        var $options = array();
    2222
    2323        var $permission = null;
     
    210210        }
    211211
    212212        function delete($file, $recursive = false ) {
     213                if ( empty($file) )
     214                        return false;
    213215                if ( $this->is_file($file) )
    214216                        return $this->ftp->delete($file);
    215217                if ( !$recursive )
  • wp-admin/includes/file.php

     
    598598
    599599        $wp_filesystem = new $method($args);
    600600
    601         if ( $wp_filesystem->errors->get_error_code() )
     601        if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
    602602                return false;
    603603
    604604        if ( !$wp_filesystem->connect() )
  • wp-admin/includes/plugin-install.php

     
    208208?>
    209209        <h4><?php _e('Install a plugin in .zip format') ?></h4>
    210210        <p class="install-help"><?php _e('If you have a plugin in a .zip format, You may install it by uploading it here.') ?></p>
    211         <form method="post" enctype="multipart/form-data" action="<?php echo admin_url('plugin-install.php?tab=do_upload') ?>">
     211        <form method="post" enctype="multipart/form-data" action="<?php echo admin_url('update.php?action=upload-plugin') ?>">
    212212                <?php wp_nonce_field( 'plugin-upload') ?>
    213213                <input type="file" name="pluginzip" />
    214214                <input type="submit" class="button" value="<?php _e('Install Now') ?>" />
     
    461461                                default:
    462462                                case 'install':
    463463                                        if ( current_user_can('install_plugins') ) :
    464                                 ?><a href="<?php echo wp_nonce_url(admin_url('plugin-install.php?tab=install&plugin=' . $api->slug), 'install-plugin_' . $api->slug) ?>" target="_parent"><?php _e('Install Now') ?></a><?php
     464                                ?><a href="<?php echo wp_nonce_url(admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug) ?>" target="_parent"><?php _e('Install Now') ?></a><?php
    465465                                        endif;
    466466                                break;
    467467                                case 'update_available':
     
    544544        iframe_footer();
    545545        exit;
    546546}
    547 
    548 
    549 add_action('install_plugins_do_upload', 'upload_plugin');
    550 function upload_plugin() {
    551 
    552         if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
    553                 wp_die($uploads['error']);
    554 
    555         if ( !empty($_FILES) )
    556                 $filename = $_FILES['pluginzip']['name'];
    557         else if ( isset($_GET['package']) )
    558                 $filename = $_GET['package'];
    559 
    560         check_admin_referer('plugin-upload');
    561 
    562         echo '<div class="wrap">';
    563         echo '<h2>', sprintf( __('Installing Plugin from file: %s'), basename($filename) ), '</h2>';
    564 
    565         //Handle a newly uploaded file, Else assume it was
    566         if ( !empty($_FILES) ) {
    567                 $filename = wp_unique_filename( $uploads['basedir'], $filename );
    568                 $local_file = $uploads['basedir'] . '/' . $filename;
    569 
    570                 // Move the file to the uploads dir
    571                 if ( false === @ move_uploaded_file( $_FILES['pluginzip']['tmp_name'], $local_file) )
    572                         wp_die( sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path']));
    573         } else {
    574                 $local_file = $uploads['basedir'] . '/' . $filename;
    575         }
    576 
    577         do_plugin_install_local_package($local_file, $filename);
    578         echo '</div>';
    579 }
    580 
    581 add_action('install_plugins_install', 'install_plugin');
    582 
    583 /**
    584  * Display plugin link and execute install.
    585  *
    586  * @since 2.7.0
    587  */
    588 function install_plugin() {
    589 
    590         $plugin = isset($_REQUEST['plugin']) ? stripslashes( $_REQUEST['plugin'] ) : '';
    591 
    592         check_admin_referer('install-plugin_' . $plugin);
    593         $api = plugins_api('plugin_information', array('slug' => $plugin, 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth.
    594 
    595         if ( is_wp_error($api) )
    596                 wp_die($api);
    597 
    598         echo '<div class="wrap">';
    599         echo '<h2>', sprintf( __('Installing Plugin: %s'), $api->name . ' ' . $api->version ), '</h2>';
    600 
    601         do_plugin_install($api->download_link, $api);
    602         echo '</div>';
    603 
    604 }
    605 
    606 /**
    607  * Retrieve plugin and install.
    608  *
    609  * @since 2.7.0
    610  *
    611  * @param string $download_url Download URL.
    612  * @param object $plugin_information Optional. Plugin information
    613  */
    614 function do_plugin_install($download_url, $plugin_information = null) {
    615         global $wp_filesystem;
    616 
    617         if ( empty($download_url) ) {
    618                 show_message( __('No plugin Specified') );
    619                 return;
    620         }
    621 
    622         $plugin = isset($_REQUEST['plugin']) ? stripslashes( $_REQUEST['plugin'] ) : '';
    623 
    624         $url = 'plugin-install.php?tab=install';
    625         $url = add_query_arg(array('plugin' => $plugin, 'plugin_name' => stripslashes( $_REQUEST['plugin_name'] ), 'download_url' => stripslashes( $_REQUEST['download_url'] ) ), $url);
    626 
    627         $url = wp_nonce_url($url, 'install-plugin_' . $plugin);
    628         if ( false === ($credentials = request_filesystem_credentials($url)) )
    629                 return;
    630 
    631         if ( ! WP_Filesystem($credentials) ) {
    632                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
    633                 return;
    634         }
    635 
    636         if ( $wp_filesystem->errors->get_error_code() ) {
    637                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
    638                         show_message($message);
    639                 return;
    640         }
    641 
    642         $result = wp_install_plugin( $download_url, 'show_message' );
    643 
    644         if ( is_wp_error($result) ) {
    645                 show_message($result);
    646                 show_message( __('Installation Failed') );
    647         } else {
    648                 show_message( sprintf(__('Successfully installed the plugin <strong>%s %s</strong>.'), $plugin_information->name, $plugin_information->version) );
    649                 $plugin_file = $result;
    650 
    651                 $install_actions = apply_filters('install_plugin_complete_actions', array(
    652                         'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file, 'activate-plugin_' . $plugin_file) . '" title="' . attribute_escape(__('Activate this plugin')) . '" target="_parent">' . __('Activate Plugin') . '</a>',
    653                         'plugins_page' => '<a href="' . admin_url('plugins.php') . '" title="' . attribute_escape(__('Goto plugins page')) . '" target="_parent">' . __('Return to Plugins page') . '</a>'
    654                                                         ), $plugin_information, $plugin_file);
    655                 if ( ! empty($install_actions) )
    656                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
    657         }
    658 }
    659 
    660 /**
    661  * Install a plugin from a local file.
    662  *
    663  * @since 2.7.0
    664  *
    665  * @param string $package Local Plugin zip
    666  * @param string $filename Optional. Original filename
    667  * @param object $plugin_information Optional. Plugin information
    668  */
    669 function do_plugin_install_local_package($package, $filename = '') {
    670         global $wp_filesystem;
    671 
    672         if ( empty($package) ) {
    673                 show_message( __('No plugin Specified') );
    674                 return;
    675         }
    676 
    677         if ( empty($filename) )
    678                 $filename = basename($package);
    679 
    680         $url = 'plugin-install.php?tab=upload';
    681         $url = add_query_arg(array('package' => $filename), $url);
    682 
    683         $url = wp_nonce_url($url, 'plugin-upload');
    684         if ( false === ($credentials = request_filesystem_credentials($url)) )
    685                 return;
    686 
    687         if ( ! WP_Filesystem($credentials) ) {
    688                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
    689                 return;
    690         }
    691 
    692         if ( $wp_filesystem->errors->get_error_code() ) {
    693                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
    694                         show_message($message);
    695                 return;
    696         }
    697 
    698         $result = wp_install_plugin_local_package( $package, 'show_message' );
    699 
    700         if ( is_wp_error($result) ) {
    701                 show_message($result);
    702                 show_message( __('Installation Failed') );
    703         } else {
    704                 show_message( __('Successfully installed the plugin.') );
    705                 $plugin_file = $result;
    706 
    707                 $install_actions = apply_filters('install_plugin_complete_actions', array(
    708                                                         'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file, 'activate-plugin_' . $plugin_file) . '" title="' . __('Activate this plugin') . '" target="_parent">' . __('Activate Plugin') . '</a>',
    709                                                         'plugins_page' => '<a href="' . admin_url('plugins.php') . '" title="' . __('Goto plugins page') . '" target="_parent">' . __('Return to Plugins page') . '</a>'
    710                                                         ), array(), $plugin_file);
    711                 if ( ! empty($install_actions) )
    712                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
    713         }
    714 }
    715 
    716 /**
    717  * Install plugin.
    718  *
    719  * @since 2.7.0
    720  *
    721  * @param string $package
    722  * @param string $feedback Optional.
    723  * @return mixed.
    724  */
    725 function wp_install_plugin($package, $feedback = '') {
    726         global $wp_filesystem;
    727 
    728         if ( !empty($feedback) )
    729                 add_filter('install_feedback', $feedback);
    730 
    731         // Is a filesystem accessor setup?
    732         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    733                 WP_Filesystem();
    734 
    735         if ( ! is_object($wp_filesystem) )
    736                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    737 
    738         if ( $wp_filesystem->errors->get_error_code() )
    739                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    740 
    741         //Get the base plugin folder
    742         $plugins_dir = $wp_filesystem->wp_plugins_dir();
    743         if ( empty($plugins_dir) )
    744                 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
    745 
    746         //And the same for the Content directory.
    747         $content_dir = $wp_filesystem->wp_content_dir();
    748         if( empty($content_dir) )
    749                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
    750 
    751         $plugins_dir = trailingslashit( $plugins_dir );
    752         $content_dir = trailingslashit( $content_dir );
    753 
    754         if ( empty($package) )
    755                 return new WP_Error('no_package', __('Install package not available.'));
    756 
    757         // Download the package
    758         apply_filters('install_feedback', sprintf(__('Downloading plugin package from %s'), $package));
    759         $download_file = download_url($package);
    760 
    761         if ( is_wp_error($download_file) )
    762                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
    763 
    764         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
    765 
    766         // Clean up working directory
    767         if ( $wp_filesystem->is_dir($working_dir) )
    768                 $wp_filesystem->delete($working_dir, true);
    769 
    770         apply_filters('install_feedback', __('Unpacking the plugin package'));
    771         // Unzip package to working directory
    772         $result = unzip_file($download_file, $working_dir);
    773 
    774         // Once extracted, delete the package
    775         @unlink($download_file);
    776 
    777         if ( is_wp_error($result) ) {
    778                 $wp_filesystem->delete($working_dir, true);
    779                 return $result;
    780         }
    781 
    782         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    783         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    784 
    785         if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
    786                 $wp_filesystem->delete($working_dir, true);
    787                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
    788         }
    789 
    790         apply_filters('install_feedback', __('Installing the plugin'));
    791         // Copy new version of plugin into place.
    792         $result = copy_dir($working_dir, $plugins_dir);
    793         if ( is_wp_error($result) ) {
    794                 $wp_filesystem->delete($working_dir, true);
    795                 return $result;
    796         }
    797 
    798         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    799         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    800 
    801         // Remove working directory
    802         $wp_filesystem->delete($working_dir, true);
    803 
    804         if( empty($filelist) )
    805                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
    806 
    807         $folder = $filelist[0];
    808         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
    809         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
    810 
    811         //Return the plugin files name.
    812         return  $folder . '/' . $pluginfiles[0];
    813 }
    814 
    815 /**
    816  * Install plugin from local package
    817  *
    818  * @since 2.7.0
    819  *
    820  * @param string $package
    821  * @param string $feedback Optional.
    822  * @return mixed.
    823  */
    824 function wp_install_plugin_local_package($package, $feedback = '') {
    825         global $wp_filesystem;
    826 
    827         if ( !empty($feedback) )
    828                 add_filter('install_feedback', $feedback);
    829 
    830         // Is a filesystem accessor setup?
    831         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    832                 WP_Filesystem();
    833 
    834         if ( ! is_object($wp_filesystem) )
    835                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    836 
    837         if ( $wp_filesystem->errors->get_error_code() )
    838                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    839 
    840         //Get the base plugin folder
    841         $plugins_dir = $wp_filesystem->wp_plugins_dir();
    842         if ( empty($plugins_dir) )
    843                 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
    844 
    845         //And the same for the Content directory.
    846         $content_dir = $wp_filesystem->wp_content_dir();
    847         if( empty($content_dir) )
    848                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
    849 
    850         $plugins_dir = trailingslashit( $plugins_dir );
    851         $content_dir = trailingslashit( $content_dir );
    852 
    853         if ( empty($package) )
    854                 return new WP_Error('no_package', __('Install package not available.'));
    855 
    856         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
    857 
    858         // Clean up working directory
    859         if ( $wp_filesystem->is_dir($working_dir) )
    860                 $wp_filesystem->delete($working_dir, true);
    861 
    862         apply_filters('install_feedback', __('Unpacking the plugin package'));
    863         // Unzip package to working directory
    864         $result = unzip_file($package, $working_dir);
    865 
    866         // Once extracted, delete the package
    867         unlink($package);
    868 
    869         if ( is_wp_error($result) ) {
    870                 $wp_filesystem->delete($working_dir, true);
    871                 return $result;
    872         }
    873 
    874         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    875         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    876 
    877         if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
    878                 $wp_filesystem->delete($working_dir, true);
    879                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
    880         }
    881 
    882         apply_filters('install_feedback', __('Installing the plugin'));
    883         // Copy new version of plugin into place.
    884         $result = copy_dir($working_dir, $plugins_dir);
    885         if ( is_wp_error($result) ) {
    886                 $wp_filesystem->delete($working_dir, true);
    887                 return $result;
    888         }
    889 
    890         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    891         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    892 
    893         // Remove working directory
    894         $wp_filesystem->delete($working_dir, true);
    895 
    896         if( empty($filelist) )
    897                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
    898 
    899         $folder = $filelist[0];
    900         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
    901         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
    902 
    903         //Return the plugin files name.
    904         return  $folder . '/' . $pluginfiles[0];
    905 }
    906 
    907 ?>
  • wp-admin/includes/plugin.php

     
    216216
    217217        // Files in wp-content/plugins directory
    218218        $plugins_dir = @ opendir( $plugin_root);
     219        $plugin_files = array();
    219220        if ( $plugins_dir ) {
    220221                while (($file = readdir( $plugins_dir ) ) !== false ) {
    221222                        if ( substr($file, 0, 1) == '.' )
     
    239240        @closedir( $plugins_dir );
    240241        @closedir( $plugins_subdir );
    241242
    242         if ( !$plugins_dir || !$plugin_files )
     243        if ( !$plugins_dir || empty($plugin_files) )
    243244                return $wp_plugins;
    244245
    245246        foreach ( $plugin_files as $plugin_file ) {
     
    432433                return;
    433434        }
    434435
    435         if ( $wp_filesystem->errors->get_error_code() ) {
    436                 return $wp_filesystem->errors;
    437         }
    438 
    439436        if ( ! is_object($wp_filesystem) )
    440437                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    441438
    442         if ( $wp_filesystem->errors->get_error_code() )
     439        if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
    443440                return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    444441
    445442        //Get the base plugin folder
  • wp-admin/includes/theme-install.php

     
    277277?>
    278278<h4><?php _e('Install a theme in .zip format') ?></h4>
    279279<p class="install-help"><?php _e('If you have a theme in a .zip format, you may install it by uploading it here.') ?></p>
    280 <form method="post" enctype="multipart/form-data" action="<?php echo admin_url('theme-install.php?tab=do_upload') ?>">
     280<form method="post" enctype="multipart/form-data" action="<?php echo admin_url('update.php?action=upload-theme') ?>">
    281281        <?php wp_nonce_field( 'theme-upload') ?>
    282282        <input type="file" name="themezip" />
    283         <input type="submit" class="button" value="<?php _e('Install Now') ?>" />
     283        <input type="submit"
     284        class="button" value="<?php _e('Install Now') ?>" />
    284285</form>
    285 <?php
     286        <?php
    286287}
    287288
    288289function display_theme($theme, $actions = null, $show_details = true) {
     
    411412        ?>
    412413        <tr>
    413414        <?php
     415
    414416        foreach ( $cols as $col => $theme_index ) {
    415417                $class = array('available-theme');
    416418                if ( $row == 1 ) $class[] = 'top';
     
    511513default:
    512514case 'install':
    513515        if ( current_user_can('install_themes') ) :
    514         $buttons .= '<a class="button-primary" id="install" href="' . wp_nonce_url(admin_url('theme-install.php?tab=install&theme=' . $api->slug), 'install-theme_' . $api->slug) . '" target="_parent">' . __('Install Now') . '</a>';
     516        $buttons .= '<a class="button-primary" id="install" href="' . wp_nonce_url(admin_url('update.php?action=install-theme&theme=' . $api->slug), 'install-theme_' . $api->slug) . '" target="_parent">' . __('Install Now') . '</a>';
    515517        endif;
    516518        break;
    517519case 'update_available':
     
    542544        iframe_footer();
    543545        exit;
    544546}
    545 
    546 add_action('install_themes_do_upload', 'upload_theme');
    547 function upload_theme() {
    548 
    549         if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
    550                 wp_die($uploads['error']);
    551 
    552         if ( !empty($_FILES) )
    553                 $filename = $_FILES['themezip']['name'];
    554         else if ( isset($_GET['package']) )
    555                 $filename = $_GET['package'];
    556 
    557         check_admin_referer('theme-upload');
    558 
    559         echo '<div class="wrap">';
    560         echo '<h2>', sprintf( __('Installing theme from file: %s'), basename($filename) ), '</h2>';
    561 
    562         //Handle a newly uploaded file, Else assume it was
    563         if ( !empty($_FILES) ) {
    564                 $filename = wp_unique_filename( $uploads['basedir'], $filename );
    565                 $local_file = $uploads['basedir'] . '/' . $filename;
    566 
    567                 // Move the file to the uploads dir
    568                 if ( false === @ move_uploaded_file( $_FILES['themezip']['tmp_name'], $local_file) )
    569                         wp_die( sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path']));
    570         } else {
    571                 $local_file = $uploads['basedir'] . '/' . $filename;
    572         }
    573 
    574         do_theme_install_local_package($local_file, $filename);
    575         echo '</div>';
    576 }
    577 
    578 add_action('install_themes_install', 'install_theme');
    579 
    580 /**
    581  * Display theme link and execute install.
    582  *
    583  * @since 2.8.0
    584  */
    585 function install_theme() {
    586 
    587         $theme = isset($_REQUEST['theme']) ? stripslashes( $_REQUEST['theme'] ) : '';
    588 
    589         check_admin_referer('install-theme_' . $theme);
    590         $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth.
    591 
    592         if ( is_wp_error($api) )
    593                 wp_die($api);
    594 
    595         echo '<div class="wrap">';
    596         echo '<h2>', sprintf( __('Installing theme: %s'), $api->name . ' ' . $api->version ), '</h2>';
    597 
    598         do_theme_install($api->download_link, $api);
    599         echo '</div>';
    600 
    601 }
    602 
    603 /**
    604  * Retrieve theme and install.
    605  *
    606  * @since 2.8.0
    607  *
    608  * @param string $download_url Download URL.
    609  * @param object $theme_information Optional. Theme information
    610  */
    611 function do_theme_install($download_url, $theme_information = null) {
    612         global $wp_filesystem;
    613 
    614         if ( empty($download_url) ) {
    615                 show_message( __('No theme specified') );
    616                 return;
    617         }
    618 
    619         $theme        = isset($_REQUEST['theme'])        ? stripslashes( $_REQUEST['theme'] )        : '';
    620         $theme_name   = isset($_REQUEST['theme_name'])   ? stripslashes( $_REQUEST['theme_name'] )   : '';
    621 
    622         $url = 'theme-install.php?tab=install';
    623         $url = add_query_arg(array('theme' => $theme, 'theme_name' => $theme_name, 'download_url' => $download_url ), $url);
    624 
    625         $url = wp_nonce_url($url, 'install-theme_' . $theme);
    626         if ( false === ($credentials = request_filesystem_credentials($url)) )
    627                 return;
    628 
    629         if ( ! WP_Filesystem($credentials) ) {
    630                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
    631                 return;
    632         }
    633 
    634         if ( $wp_filesystem->errors->get_error_code() ) {
    635                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
    636                 show_message($message);
    637                 return;
    638         }
    639 
    640         $result = wp_install_theme( $download_url, 'show_message' );
    641 
    642         if ( is_wp_error($result) ) {
    643                 show_message($result);
    644                 show_message( __('Installation Failed') );
    645         } else {
    646                 show_message( sprintf(__('Successfully installed the theme <strong>%s %s</strong>.'), $theme_information->name, $theme_information->version) );
    647                 $theme_file = $result;
    648 
    649                 $install_actions = apply_filters('install_theme_complete_actions', array(
    650                 //'activate_theme' => '<a href="' . wp_nonce_url('themes.php?action=activate&amp;theme=' . $theme_file, 'activate-theme_' . $theme_file) . '" title="' . attribute_escape(__('Activate this theme')) . '" target="_parent">' . __('Activate Theme') . '</a>',
    651                         'themes_page' => '<a href="' . admin_url('themes.php') . '" title="' . attribute_escape(__('Return to Themes page')) . '" target="_parent">' . __('Return to Themes page') . '</a>'
    652                         ), $theme_information, $theme_file);
    653                         if ( ! empty($install_actions) )
    654                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
    655         }
    656 }
    657 
    658 /**
    659  * Install a theme from a local file.
    660  *
    661  * @since 2.8.0
    662  *
    663  * @param string $package Local Theme zip
    664  * @param string $filename Optional. Original filename
    665  * @param object $theme_information Optional. Theme information
    666  */
    667 function do_theme_install_local_package($package, $filename = '') {
    668         global $wp_filesystem;
    669 
    670         if ( empty($package) ) {
    671                 show_message( __('No theme specified') );
    672                 return;
    673         }
    674 
    675         if ( empty($filename) )
    676                 $filename = basename($package);
    677 
    678         $url = 'theme-install.php?tab=upload';
    679         $url = add_query_arg(array('package' => $filename), $url);
    680 
    681         $url = wp_nonce_url($url, 'theme-upload');
    682         if ( false === ($credentials = request_filesystem_credentials($url)) )
    683                 return;
    684 
    685         if ( ! WP_Filesystem($credentials) ) {
    686                 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
    687                 return;
    688         }
    689 
    690         if ( $wp_filesystem->errors->get_error_code() ) {
    691                 foreach ( $wp_filesystem->errors->get_error_messages() as $message )
    692                 show_message($message);
    693                 return;
    694         }
    695 
    696         $result = wp_install_theme_local_package( $package, 'show_message' );
    697 
    698         if ( is_wp_error($result) ) {
    699                 show_message($result);
    700                 show_message( __('Installation Failed') );
    701         } else {
    702                 show_message( __('Successfully installed the theme.') );
    703                 $theme_file = $result;
    704 
    705                 $install_actions = apply_filters('install_theme_complete_actions', array(
    706                 //'activate_theme' => '<a href="' . wp_nonce_url('themes.php?action=activate&amp;theme=' . $theme_file, 'activate-theme_' . $theme_file) . '" title="' . __('Activate this theme') . '" target="_parent">' . __('Activate Theme') . '</a>',
    707                                                         'themes_page' => '<a href="' . admin_url('themes.php') . '" title="' . __('Goto themes page') . '" target="_parent">' . __('Return to Themes page') . '</a>'
    708                                                         ), array(), $theme_file);
    709                                                         if ( ! empty($install_actions) )
    710                                                         show_message('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
    711         }
    712 }
    713 
    714 /**
    715  * Install theme.
    716  *
    717  * @since 2.8.0
    718  *
    719  * @param string $package
    720  * @param string $feedback Optional.
    721  * @return mixed.
    722  */
    723 function wp_install_theme($package, $feedback = '') {
    724         global $wp_filesystem;
    725 
    726         if ( !empty($feedback) )
    727                 add_filter('install_feedback', $feedback);
    728 
    729         // Is a filesystem accessor setup?
    730         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    731                 WP_Filesystem();
    732 
    733         if ( ! is_object($wp_filesystem) )
    734                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    735 
    736         if ( $wp_filesystem->errors->get_error_code() )
    737                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    738 
    739         // Get the base theme folder
    740         $themes_dir = $wp_filesystem->wp_themes_dir();
    741         if ( empty($themes_dir) )
    742                 return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress themes directory.'));
    743 
    744         // And the same for the Content directory.
    745         $content_dir = $wp_filesystem->wp_content_dir();
    746         if ( empty($content_dir) )
    747                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress content directory (wp-content).'));
    748 
    749         $themes_dir = trailingslashit( $themes_dir );
    750         $content_dir = trailingslashit( $content_dir );
    751 
    752         if ( empty($package) )
    753                 return new WP_Error('no_package', __('Install package not available.'));
    754 
    755         // Download the package
    756         apply_filters('install_feedback', sprintf(__('Downloading theme package from %s'), $package));
    757         $download_file = download_url($package);
    758 
    759         if ( is_wp_error($download_file) )
    760                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
    761 
    762         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
    763 
    764         // Clean up working directory
    765         if ( $wp_filesystem->is_dir($working_dir) )
    766                 $wp_filesystem->delete($working_dir, true);
    767 
    768         apply_filters('install_feedback', __('Unpacking the theme package'));
    769         // Unzip package to working directory
    770         $result = unzip_file($download_file, $working_dir);
    771 
    772         // Once extracted, delete the package
    773         @unlink($download_file);
    774 
    775         if ( is_wp_error($result) ) {
    776                 $wp_filesystem->delete($working_dir, true);
    777                 return $result;
    778         }
    779 
    780         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the theme
    781         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    782 
    783         if ( $wp_filesystem->exists( $themes_dir . $filelist[0] ) ) {
    784                 $wp_filesystem->delete($working_dir, true);
    785                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
    786         }
    787 
    788         apply_filters('install_feedback', __('Installing the theme'));
    789         // Copy new version of theme into place.
    790         $result = copy_dir($working_dir, $themes_dir);
    791         if ( is_wp_error($result) ) {
    792                 $wp_filesystem->delete($working_dir, true);
    793                 return $result;
    794         }
    795 
    796         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the theme
    797         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    798 
    799         // Remove working directory
    800         $wp_filesystem->delete($working_dir, true);
    801 
    802         if ( empty($filelist) )
    803                 return false; //We couldnt find any files in the working dir, therefor no theme installed? Failsafe backup.
    804 
    805         //TODO: TODO: TODO
    806         $stylesheet = $filelist[0];
    807         //      $theme = get_themes('/' . $folder); //Ensure to pass with leading slash //TODO: TODO: TODO
    808         //      $themefiles = array_keys($theme); //Assume the requested theme is the first in the list
    809 
    810         //Return the theme files name.
    811         return  $stylesheet; //$folder . '/' . $themefiles[0];
    812 }
    813 
    814 /**
    815  * Install theme from local package
    816  *
    817  * @since 2.8.0
    818  *
    819  * @param string $package
    820  * @param string $feedback Optional.
    821  * @return mixed.
    822  */
    823 function wp_install_theme_local_package($package, $feedback = '') {
    824         global $wp_filesystem;
    825 
    826         if ( !empty($feedback) )
    827                 add_filter('install_feedback', $feedback);
    828 
    829         // Is a filesystem accessor setup?
    830         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    831                 WP_Filesystem();
    832 
    833         if ( ! is_object($wp_filesystem) )
    834                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    835 
    836         if ( $wp_filesystem->errors->get_error_code() )
    837                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    838 
    839         //Get the base theme folder
    840         $themes_dir = $wp_filesystem->wp_themes_dir();
    841         if ( empty($themes_dir) )
    842                 return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress themes directory.'));
    843 
    844         //And the same for the Content directory.
    845         $content_dir = $wp_filesystem->wp_content_dir();
    846         if ( empty($content_dir) )
    847                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress content directory (wp-content).'));
    848 
    849         $themes_dir = trailingslashit( $themes_dir );
    850         $content_dir = trailingslashit( $content_dir );
    851 
    852         if ( empty($package) )
    853                 return new WP_Error('no_package', __('Install package not available.'));
    854 
    855         $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
    856 
    857 
    858         // Clean up working directory
    859         if ( $wp_filesystem->is_dir($working_dir) )
    860                 $wp_filesystem->delete($working_dir, true);
    861 
    862         apply_filters('install_feedback', __('Unpacking the theme package'));
    863         // Unzip package to working directory
    864         $result = unzip_file($package, $working_dir);
    865 
    866         // Once extracted, delete the package
    867         unlink($package);
    868 
    869         if ( is_wp_error($result) ) {
    870                 $wp_filesystem->delete($working_dir, true);
    871                 return $result;
    872         }
    873 
    874         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the theme
    875         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    876 
    877         if ( $wp_filesystem->exists( $themes_dir . $filelist[0] ) ) {
    878                 $wp_filesystem->delete($working_dir, true);
    879                 return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
    880         }
    881 
    882         apply_filters('install_feedback', __('Installing the theme'));
    883         // Copy new version of theme into place.
    884         $result = copy_dir($working_dir, $themes_dir);
    885         if ( is_wp_error($result) ) {
    886                 $wp_filesystem->delete($working_dir, true);
    887                 return $result;
    888         }
    889 
    890         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the theme
    891         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    892 
    893         // Remove working directory
    894         $wp_filesystem->delete($working_dir, true);
    895 
    896         if ( empty($filelist) )
    897                 return false; //We couldnt find any files in the working dir, therefor no theme installed? Failsafe backup.
    898 
    899         //TODO TODO TODO
    900         $stylesheet = $filelist[0];
    901         //      $theme = get_themes('/' . $folder); //Ensure to pass with leading slash
    902         //      $themefiles = array_keys($theme); //Assume the requested theme is the first in the list
    903 
    904         //Return the theme files name.
    905         return  $stylsheet; //$folder . '/' . $themefiles[0];
    906 }
  • wp-admin/includes/theme.php

     
    7272                return;
    7373        }
    7474
    75         if ( $wp_filesystem->errors->get_error_code() ) {
    76                 return $wp_filesystem->errors;
    77         }
    7875
    7976        if ( ! is_object($wp_filesystem) )
    8077                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    8178
    82         if ( $wp_filesystem->errors->get_error_code() )
     79        if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
    8380                return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    8481
    8582        //Get the base plugin folder
  • wp-admin/includes/update-core.php

     
    229229        $result = copy_dir($from . '/wordpress', $to);
    230230        if ( is_wp_error($result) ) {
    231231                $wp_filesystem->delete($maintenance_file);
    232                 //$wp_filesystem->delete($working_dir, true); //TODO: Uncomment? This DOES mean that the new files are available in the upgrade folder if it fails.
     232                $wp_filesystem->delete($working_dir, true);
    233233                return $result;
    234234        }
    235235
  • wp-admin/includes/update.php

     
    167167add_action( 'after_plugin_row', 'wp_plugin_update_row', 10, 2 );
    168168
    169169function wp_update_plugin($plugin, $feedback = '') {
    170         global $wp_filesystem;
    171170
    172171        if ( !empty($feedback) )
    173172                add_filter('update_feedback', $feedback);
    174173
    175         // Is an update available?
    176         $current = get_transient( 'update_plugins' );
    177         if ( !isset( $current->response[ $plugin ] ) )
    178                 return new WP_Error('up_to_date', __('The plugin is at the latest version.'));
    179 
    180         // Is a filesystem accessor setup?
    181         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    182                 WP_Filesystem();
    183 
    184         if ( ! is_object($wp_filesystem) )
    185                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    186 
    187         if ( $wp_filesystem->errors->get_error_code() )
    188                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    189 
    190         //Get the base plugin folder
    191         $plugins_dir = $wp_filesystem->wp_plugins_dir();
    192         if ( empty($plugins_dir) )
    193                 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
    194 
    195         //And the same for the Content directory.
    196         $content_dir = $wp_filesystem->wp_content_dir();
    197         if( empty($content_dir) )
    198                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
    199 
    200         $plugins_dir = trailingslashit( $plugins_dir );
    201         $content_dir = trailingslashit( $content_dir );
    202 
    203         // Get the URL to the zip file
    204         $r = $current->response[ $plugin ];
    205 
    206         if ( empty($r->package) )
    207                 return new WP_Error('no_package', __('Upgrade package not available.'));
    208 
    209         // Download the package
    210         $package = $r->package;
    211         apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $package));
    212         $download_file = download_url($package);
    213 
    214         if ( is_wp_error($download_file) )
    215                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
    216 
    217         $working_dir = $content_dir . 'upgrade/' . basename($plugin, '.php');
    218 
    219         // Clean up working directory
    220         if ( $wp_filesystem->is_dir($working_dir) )
    221                 $wp_filesystem->delete($working_dir, true);
    222 
    223         apply_filters('update_feedback', __('Unpacking the update'));
    224         // Unzip package to working directory
    225         $result = unzip_file($download_file, $working_dir);
    226 
    227         // Once extracted, delete the package
    228         unlink($download_file);
    229 
    230         if ( is_wp_error($result) ) {
    231                 $wp_filesystem->delete($working_dir, true);
    232                 return $result;
    233         }
    234 
    235         if ( is_plugin_active($plugin) ) {
    236                 //Deactivate the plugin silently, Prevent deactivation hooks from running.
    237                 apply_filters('update_feedback', __('Deactivating the plugin'));
    238                 deactivate_plugins($plugin, true);
    239         }
    240 
    241         // Remove the existing plugin.
    242         apply_filters('update_feedback', __('Removing the old version of the plugin'));
    243         $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) );
    244 
    245         // If plugin is in its own directory, recursively delete the directory.
    246         if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
    247                 $deleted = $wp_filesystem->delete($this_plugin_dir, true);
    248         else
    249                 $deleted = $wp_filesystem->delete($plugins_dir . $plugin);
    250 
    251         if ( ! $deleted ) {
    252                 $wp_filesystem->delete($working_dir, true);
    253                 return new WP_Error('delete_failed', __('Could not remove the old plugin'));
    254         }
    255 
    256         apply_filters('update_feedback', __('Installing the latest version'));
    257         // Copy new version of plugin into place.
    258         $result = copy_dir($working_dir, $plugins_dir);
    259         if ( is_wp_error($result) ) {
    260                 $wp_filesystem->delete($working_dir, true);
    261                 return $result;
    262         }
    263 
    264         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    265         $filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    266 
    267         // Remove working directory
    268         $wp_filesystem->delete($working_dir, true);
    269 
    270         // Force refresh of plugin update information
    271         delete_transient('update_plugins');
    272 
    273         if( empty($filelist) )
    274                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
    275 
    276         $folder = $filelist[0];
    277         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
    278         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
    279 
    280         return  $folder . '/' . $pluginfiles[0];
     174        include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     175        $upgrader = new Plugin_Upgrader();
     176        return $upgrader->upgrade($plugin);
    281177}
    282178
    283179function wp_update_theme($theme, $feedback = '') {
    284         global $wp_filesystem;
    285 
     180       
    286181        if ( !empty($feedback) )
    287182                add_filter('update_feedback', $feedback);
    288183
    289         // Is an update available?
    290         $current = get_transient( 'update_themes' );
    291         if ( !isset( $current->response[ $theme ] ) )
    292                 return new WP_Error('up_to_date', __('The theme is at the latest version.'));
    293 
    294         $r = $current->response[ $theme ];
    295 
    296         $themes = get_themes();
    297         foreach ( (array) $themes as $this_theme ) {
    298                 if ( $this_theme['Stylesheet'] == $theme ) {
    299                         $theme_directory = preg_replace('!^/themes/!i', '', $this_theme['Stylesheet Dir']);
    300                         break;
    301                 }
    302         }
    303         unset($themes);
    304 
    305         if ( empty($theme_directory) )
    306                 return new WP_Error('theme_non_existant', __('Theme does not exist.'));
    307 
    308         // Is a filesystem accessor setup?
    309         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    310                 WP_Filesystem();
    311 
    312         if ( ! is_object($wp_filesystem) )
    313                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    314 
    315         if ( $wp_filesystem->errors->get_error_code() )
    316                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    317 
    318         //Get the base plugin folder
    319         $themes_dir = $wp_filesystem->wp_themes_dir();
    320         if ( empty($themes_dir) )
    321                 return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress Theme directory.'));
    322 
    323         //And the same for the Content directory.
    324         $content_dir = $wp_filesystem->wp_content_dir();
    325         if( empty($content_dir) )
    326                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
    327 
    328         $themes_dir = trailingslashit( $themes_dir );
    329         $content_dir = trailingslashit( $content_dir );
    330 
    331         if ( empty($r->package) )
    332                 return new WP_Error('no_package', __('Upgrade package not available.'));
    333 
    334         // Download the package
    335         apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $r['package']));
    336         $download_file = download_url($r['package']);
    337 
    338         if ( is_wp_error($download_file) )
    339                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
    340 
    341         $working_dir = $content_dir . 'upgrade/' . basename($theme_directory);
    342 
    343         // Clean up working directory
    344         if ( $wp_filesystem->is_dir($working_dir) )
    345                 $wp_filesystem->delete($working_dir, true);
    346 
    347         apply_filters('update_feedback', __('Unpacking the update'));
    348         // Unzip package to working directory
    349         $result = unzip_file($download_file, $working_dir);
    350 
    351         // Once extracted, delete the package
    352         unlink($download_file);
    353 
    354         if ( is_wp_error($result) ) {
    355                 $wp_filesystem->delete($working_dir, true);
    356                 return $result;
    357         }
    358 
    359         //TODO: Is theme currently active? If so, set default theme
    360         /*
    361         if ( is_plugin_active($plugin) ) {
    362                 //Deactivate the plugin silently, Prevent deactivation hooks from running.
    363                 apply_filters('update_feedback', __('Deactivating the plugin'));
    364                 deactivate_plugins($plugin, true);
    365         }*/
    366 
    367         // Remove the existing plugin.
    368         apply_filters('update_feedback', __('Removing the old version of the theme'));
    369         $deleted = $wp_filesystem->delete($themes_dir . $theme_directory, true);
    370 
    371         if ( ! $deleted ) {
    372                 $wp_filesystem->delete($working_dir, true);
    373                 return new WP_Error('delete_failed', __('Could not remove the old plugin'));
    374         }
    375 
    376         apply_filters('update_feedback', __('Installing the latest version'));
    377         // Copy new version of plugin into place.
    378         $result = copy_dir($working_dir, $themes_dir);
    379         if ( is_wp_error($result) ) {
    380                 $wp_filesystem->delete($working_dir, true);
    381                 return $result;
    382         }
    383 
    384         //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
    385         //$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
    386 
    387         // Remove working directory
    388         $wp_filesystem->delete($working_dir, true);
    389 
    390         // Force refresh of plugin update information
    391         delete_transient('update_themes');
    392 
    393         /*if( empty($filelist) )
    394                 return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
    395 
    396         $folder = $filelist[0];
    397         $plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
    398         $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
    399 
    400         return  $folder . '/' . $pluginfiles[0];*/
     184        include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     185        $upgrader = new Theme_Upgrader();
     186        return $upgrader->upgrade($theme);
    401187}
    402188
    403189
    404190function wp_update_core($current, $feedback = '') {
    405         global $wp_filesystem;
    406 
    407         @set_time_limit( 300 );
    408 
     191       
    409192        if ( !empty($feedback) )
    410193                add_filter('update_feedback', $feedback);
    411194
    412         // Is an update available?
    413         if ( !isset( $current->response ) || $current->response == 'latest' )
    414                 return new WP_Error('up_to_date', __('WordPress is at the latest version.'));
     195        include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     196        $upgrader = new Core_Upgrader();
     197        return $upgrader->upgrade($current);
    415198
    416         // Is a filesystem accessor setup?
    417         if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
    418                 WP_Filesystem();
    419 
    420         if ( ! is_object($wp_filesystem) )
    421                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    422 
    423         if ( $wp_filesystem->errors->get_error_code() )
    424                 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    425 
    426         // Get the base WP folder
    427         $wp_dir = $wp_filesystem->abspath();
    428         if ( empty($wp_dir) )
    429                 return new WP_Error('fs_no_wp_dir', __('Unable to locate WordPress directory.'));
    430 
    431         // And the same for the Content directory.
    432         $content_dir = $wp_filesystem->wp_content_dir();
    433         if( empty($content_dir) )
    434                 return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
    435 
    436         $wp_dir = trailingslashit( $wp_dir );
    437         $content_dir = trailingslashit( $content_dir );
    438 
    439         // Get the URL to the zip file
    440         $package = $current->package;
    441 
    442         // Download the package
    443         apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $package));
    444         $download_file = download_url($package);
    445 
    446         if ( is_wp_error($download_file) )
    447                 return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
    448 
    449         $working_dir = $content_dir . 'upgrade/core';
    450         // Clean up working directory
    451         if ( $wp_filesystem->is_dir($working_dir) ) {
    452                 $wp_filesystem->delete($working_dir, true);
    453         }
    454 
    455         apply_filters('update_feedback', __('Unpacking the core update'));
    456         // Unzip package to working directory
    457         $result = unzip_file($download_file, $working_dir);
    458         // Once extracted, delete the package
    459         unlink($download_file);
    460 
    461         if ( is_wp_error($result) ) {
    462                 $wp_filesystem->delete($working_dir, true);
    463                 return $result;
    464         }
    465 
    466         // Copy update-core.php from the new version into place.
    467         if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
    468                 $wp_filesystem->delete($working_dir, true);
    469                 return new WP_Error('copy_failed', __('Could not copy files'));
    470         }
    471         $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
    472 
    473         require(ABSPATH . 'wp-admin/includes/update-core.php');
    474 
    475         return update_core($working_dir, $wp_dir);
    476199}
    477200
    478201function maintenance_nag() {
  • wp-admin/plugin-install.php

     
    2424
    2525//These are the tabs which are shown on the page,
    2626$tabs = array();
    27 $tabs['dashboard'] = __('Search'); //TODO: Better name?
     27$tabs['dashboard'] = __('Search');
    2828if ( 'search' == $tab )
    2929        $tabs['search'] = __('Search Results');
    3030$tabs['upload'] = __('Upload');
     
    3333$tabs['new']      = __('Newest');
    3434$tabs['updated']  = __('Recently Updated');
    3535
    36 $nonmenu_tabs = array('install', 'plugin-information', 'do_upload'); //Valid actions to perform which do not have a Menu item.
     36$nonmenu_tabs = array('plugin-information'); //Valid actions to perform which do not have a Menu item.
    3737
    3838$tabs = apply_filters('install_plugins_tabs', $tabs );
    3939$nonmenu_tabs = apply_filters('install_plugins_nonmenu_tabs', $nonmenu_tabs);
     
    6262foreach ( (array)$tabs as $action => $text ) {
    6363        $sep = ( end($tabs) != $text ) ? ' | ' : '';
    6464        $class = ( $action == $tab ) ? ' class="current"' : '';
    65         $href = admin_url('plugin-install.php?tab='. $action);
     65        $href = admin_url('plugin-install.php?tab=' . $action);
    6666        echo "\t\t<li><a href='$href'$class>$text</a>$sep</li>\n";
    6767}
    6868?>
     
    7171        <?php do_action('install_plugins_' . $tab, $paged); ?>
    7272</div>
    7373<?php
    74 include('admin-footer.php');
    75 ?>
     74include('admin-footer.php');
     75 No newline at end of file
  • wp-admin/theme-install.php

     
    3535$tabs['new']      = __('Newest');
    3636$tabs['updated']  = __('Recently Updated');
    3737
    38 $nonmenu_tabs = array('install', 'theme-information', 'do_upload'); //Valid actions to perform which do not have a Menu item.
     38$nonmenu_tabs = array('theme-information'); //Valid actions to perform which do not have a Menu item.
    3939
    4040$tabs = apply_filters('install_themes_tabs', $tabs );
    4141$nonmenu_tabs = apply_filters('install_themes_nonmenu_tabs', $nonmenu_tabs);
  • wp-includes/update.php

     
    112112
    113113        $new_option = new stdClass;
    114114        $new_option->last_checked = time();
    115         $timeout = 'load-plugins.php' == current_filter() ? 360 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
     115        $timeout = 'load-plugins.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
    116116        $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
    117117
    118118        $plugin_changed = false;
     
    195195
    196196        $new_option = new stdClass;
    197197        $new_option->last_checked = time( );
    198         $timeout = 'load-themes.php' == current_filter() ? 360 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
     198        $timeout = 'load-themes.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
    199199        $time_not_changed = isset( $current_theme->last_checked ) && $timeout > ( time( ) - $current_theme->last_checked );
    200200
    201201        if( $time_not_changed )
  • wp-admin/includes/class-wp-upgrader.php

     
     1<?php
     2/**
     3 * This file is an attempt at an abstracted version of the plugin/theme/core installer/upgrader which can be used interchangably for all uses needed within WordPress.
     4 * It is designed to be as flexible as possible, but some logic may seem rather, crazy to say the least.
     5 * Yes, this header is designed to be replaced before commiting, Hopefully i'll get some proper documentation in here.
     6 *
     7 * This File obviously needs some new PHPDoc, However:
     8 * Tested:
     9 *   Theme/Plugin Upgrades/Installs
     10 *   Core Upgrade
     11 *   FTP Extension, FTP Sockets, Direct.
     12 * Untested:
     13 *   SSH2 Layer - Needs a good cleanup.
     14 *
     15 * TODO: Remove this commentblock and replace with some better docs.
     16 */
     17
     18class WP_Upgrader {
     19        var $strings = array();
     20        var $skin = null;
     21        var $result = array();
     22       
     23        function WP_Upgrader(&$skin = null) {
     24                return __construct($skin);
     25        }
     26        function __construct(&$skin = null) {
     27                if ( null == $skin )
     28                        $this->skin = new WP_Upgrader_Skin();
     29                else
     30                        $this->skin = $skin;
     31                $this->skin->set_upgrader($this);
     32        }
     33       
     34        function generic_strings() {
     35                $this->strings['bad_request'] = __('Invalid Data provided.');
     36                $this->strings['fs_unavailable'] = __('Could not access filesystem.');
     37                $this->strings['fs_error'] = __('Filesystem error');
     38                $this->strings['fs_no_root_dir'] = __('Unable to locate WordPress Root directory.');
     39                $this->strings['fs_no_content_dir'] = __('Unable to locate WordPress Content directory (wp-content).');
     40                $this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress Plugin directory.');
     41                $this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress Theme directory.');
     42                $this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).');
     43
     44                $this->strings['download_failed'] = __('Download failed.');
     45                $this->strings['installing_package'] = __('Installing the latest version.');
     46                $this->strings['folder_exists'] = __('Destination folder already exists.');
     47                $this->strings['mkdir_failed'] = __('Could not create directory.');
     48                $this->strings['bad_package'] = __('Incompatible Archive');
     49               
     50                $this->strings['maintenance_start'] = __('Enabling Maintenance mode.');
     51                $this->strings['maintenance_end'] = __('Disabling Maintenance mode.');
     52        }
     53       
     54        function fs_connect( $directories = array() ) {
     55                global $wp_filesystem;
     56       
     57                if ( false === ($credentials = $this->skin->request_filesystem_credentials()) ) //request_filesystem_credentials($url)) )
     58                        return false;
     59       
     60                if ( ! WP_Filesystem($credentials) ) {
     61                        $error = true;
     62                        if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() )
     63                                $error = $wp_filesystem->errors;
     64                        $this->skin->request_filesystem_credentials($error); //Failed to connect, Error and request again
     65                        return false;
     66                }
     67
     68                if ( ! is_object($wp_filesystem) )
     69                        return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] );
     70       
     71                if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
     72                        return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors);
     73
     74                foreach ( (array)$directories as $dir ) {
     75                        if ( ABSPATH == $dir && ! $wp_filesystem->abspath() )
     76                                return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']);
     77
     78                        elseif ( WP_CONTENT_DIR == $dir && ! $wp_filesystem->wp_content_dir() )
     79                                return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']);
     80
     81                        elseif ( WP_PLUGIN_DIR == $dir && ! $wp_filesystem->wp_plugins_dir() )
     82                                return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']);
     83
     84                        elseif ( WP_CONTENT_DIR . '/themes' == $dir && ! $wp_filesystem->find_folder(WP_CONTENT_DIR . '/themes') )
     85                                return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']);
     86
     87                        elseif ( ! $wp_filesystem->find_folder($dir) )
     88                                return new WP_Error('fs_no_folder', sprintf($strings['fs_no_folder'], $dir));
     89                }
     90                return true;
     91        } //end fs_connect();
     92
     93        function download_package($package) {
     94
     95                if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote?
     96                        return $package; //must be a local file..
     97               
     98                if ( empty($package) )
     99                        return new WP_Error('no_package', $this->strings['no_package']);
     100
     101                $this->skin->feedback('downloading_package', $package);
     102
     103                $download_file = download_url($package);
     104       
     105                if ( is_wp_error($download_file) )
     106                        return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
     107               
     108                return $download_file;
     109        }
     110       
     111        function unpack_package($package, $delete_package = true) {
     112                global $wp_filesystem;
     113               
     114                $this->skin->feedback('unpack_package');
     115
     116                $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
     117
     118                //Clean up contents of upgrade directory beforehand.
     119                $upgrade_files = $wp_filesystem->dirlist($upgrade_folder);
     120                if ( !empty($upgrade_files) ) {
     121                        foreach ( $upgrade_files as $file )
     122                                $wp_filesystem->delete($upgrade_folder . $file['name'], true);
     123                }
     124
     125                //We need a working directory
     126                $working_dir = $upgrade_folder . basename($package, '.zip');
     127
     128                // Clean up working directory
     129                if ( $wp_filesystem->is_dir($working_dir) )
     130                        $wp_filesystem->delete($working_dir, true);
     131
     132                // Unzip package to working directory
     133                $result = unzip_file($package, $working_dir); //TODO optimizations, Copy when Move/Rename would suffice?
     134
     135                // Once extracted, delete the package if required.
     136                if ( $delete_package )
     137                        unlink($package);
     138
     139                if ( is_wp_error($result) ) {
     140                        $wp_filesystem->delete($working_dir, true);
     141                        return $result;
     142                }
     143               
     144                return $working_dir;
     145        }
     146       
     147        function install_package($args = array()) {
     148                global $wp_filesystem;
     149                $defaults = array( 'source' => '', 'destination' => '', //Please always pass these
     150                                                'clear_destination' => false, 'clear_working' => false,
     151                                                'hook_extra' => array());
     152
     153                $args = wp_parse_args($args, $defaults);
     154                extract($args);
     155
     156                @set_time_limit( 300 );
     157
     158                if ( empty($source) || empty($destination) )
     159                        return new WP_Error('bad_request', $this->strings['bad_request']);
     160               
     161                $this->skin->feedback('installing_package');
     162
     163                $res = apply_filters('upgrader_pre_install', true, $hook_extra);
     164                if ( is_wp_error($res) )
     165                        return $res;
     166
     167                //Retain the Original source and destinations
     168                $remote_source = $source;
     169                $local_destination = $destination;
     170               
     171                $source_files = array_keys( $wp_filesystem->dirlist($remote_source) );
     172                $remote_destination = $wp_filesystem->find_folder($local_destination);
     173
     174                //Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
     175                if ( 1 == count($source_files) && $wp_filesystem->is_dir( trailingslashit($source) . $source_files[0] . '/') ) //Only one folder? Then we want its contents.
     176                        $source = trailingslashit($source) . trailingslashit($source_files[0]);
     177                elseif ( count($source_files) == 0 )
     178                        return new WP_Error('bad_package', $this->strings['bad_package']); //There are no files?
     179                //else //Its only a single file, The upgrader will use the foldername of this file as the destination folder. foldername is based on zip filename.
     180                                 
     181                //Hook ability to change the source file location..
     182                $source = apply_filters('upgrader_source_selection', $source, $remote_source, $this);
     183                if ( is_wp_error($source) )
     184                        return $source;
     185               
     186                //Has the source location changed? If so, we need a new source_files list.
     187                if ( $source !== $remote_source )
     188                        $source_files = array_keys( $wp_filesystem->dirlist($source) );
     189               
     190                //Protection against deleting files in any important base directories.
     191                if ( in_array( $destination, array(ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes') ) ) {
     192                        $remote_destination = trailingslashit($remote_destination) . trailingslashit(basename($source));
     193                        $destination = trailingslashit($destination) . trailingslashit(basename($source));
     194                }
     195
     196                //If we're not clearing the destination folder, and something exists there allready, Bail.
     197                if ( ! $clear_destination && $wp_filesystem->exists($remote_destination) ) {
     198                        $wp_filesystem->delete($remote_source, true); //Clear out the source files.
     199                        return new WP_Error('folder_exists', $this->strings['folder_exists'], $remote_destination );
     200                } else if ( $clear_destination ) {
     201                        //We're going to clear the destination if theres something there
     202                        $this->skin->feedback('remove_old');
     203
     204                        $removed = true;
     205                        if ( $wp_filesystem->exists($remote_destination) )
     206                                $removed = $wp_filesystem->delete($remote_destination, true);
     207
     208                        $removed = apply_filters('upgrader_clear_destination', $removed, $local_destination, $remote_destination, $hook_extra);
     209
     210                        if ( is_wp_error($removed) )
     211                                return $removed;
     212                        else if ( ! $removed )
     213                                return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']);
     214                }
     215               
     216                //Create destination if needed
     217                if ( !$wp_filesystem->exists($remote_destination) )
     218                        if ( !$wp_filesystem->mkdir($remote_destination) )
     219                                return new WP_Error('mkdir_failed', $this->strings['mkdir_failed'], $remote_destination);
     220               
     221                // Copy new version of item into place.
     222                $result = copy_dir($source, $remote_destination);
     223                if ( is_wp_error($result) ) {
     224                        if ( $clear_working )
     225                                $wp_filesystem->delete($remote_source, true);
     226                        return $result;
     227                }
     228               
     229                //Clear the Working folder?
     230                if ( $clear_working )
     231                        $wp_filesystem->delete($remote_source, true);
     232               
     233                $destination_name = basename( str_replace($local_destination, '', $destination) );
     234                if ( '.' == $destination_name )
     235                        $destination_name = '';
     236
     237                $this->result = compact('local_source', 'source', 'source_name', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination', 'delete_source_dir');
     238
     239                $res = apply_filters('upgrader_post_install', true, $hook_extra, $this->result);
     240                if ( is_wp_error($res) ) {
     241                        $this->result = $res;
     242                        return $res;
     243                }
     244
     245                //Bombard the calling function will all the info which we've just used.
     246                return $this->result;
     247        }
     248       
     249        function run($options) {
     250
     251                $defaults = array(      'package' => '', //Please always pass this.
     252                                                        'destination' => '', //And this
     253                                                        'clear_destination' => false,
     254                                                        'clear_working' => true,
     255                                                        'hook_extra' => array() //Pass any extra $hook_extra args here, this will be passed to any hooked filters.
     256                                                );
     257
     258                $options = wp_parse_args($options, $defaults);
     259                extract($options);
     260
     261                $this->skin->header();
     262                $this->skin->before();
     263               
     264                //Connect to the Filesystem first.
     265                $res = $this->fs_connect( array(WP_CONTENT_DIR, $destination) );
     266                if ( ! $res ) //Mainly for non-connected filesystem.
     267                        return false;
     268
     269                if ( is_wp_error($res) ) {
     270                        $this->skin->error($res);
     271                        return $res;
     272                }
     273               
     274                //Download the package (Note, This just returns the filename of the file if the package is a local file)
     275                $download = $this->download_package( $package );
     276                if ( is_wp_error($download) ) {
     277                        $this->skin->error($download);
     278                        return $download;
     279                }
     280               
     281                //Unzip's the file into a temporary directory
     282                $working_dir = $this->unpack_package( $download );
     283                if ( is_wp_error($working_dir) ) {
     284                        $this->skin->error($working_dir);
     285                        return $working_dir;
     286                }
     287
     288                //With the given options, this installs it to the destination directory.
     289                $result = $this->install_package( array(
     290                                                                                        'source' => $working_dir,
     291                                                                                        'destination' => $destination,
     292                                                                                        'clear_destination' => $clear_destination,
     293                                                                                        'clear_working' => $clear_working,
     294                                                                                        'hook_extra' => $hook_extra
     295                                                                                ) );
     296                $this->skin->set_result($result);
     297                if ( is_wp_error($result) ) {
     298                        $this->skin->error($result);
     299                        $this->skin->feedback('process_failed');
     300                } else {
     301                        //Install Suceeded
     302                        $this->skin->feedback('process_success');
     303                }
     304                $this->skin->after();
     305                $this->skin->footer();
     306                return $result;
     307        }
     308       
     309        function maintenance_mode($enable = false) {
     310                global $wp_filesystem;
     311                $file = $wp_filesystem->abspath() . '.maintenance';
     312                if ( $enable ) {
     313                        $this->skin->feedback('maintenance_start');
     314                        // Create maintenance file to signal that we are upgrading
     315                        $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
     316                        $wp_filesystem->delete($file);
     317                        $wp_filesystem->put_contents($file, $maintenance_string, FS_CHMOD_FILE);
     318                } else if ( !$enable && $wp_filesystem->exists($file) ) {
     319                        $this->skin->feedback('maintenance_end');
     320                        $wp_filesystem->delete($file);
     321                }
     322        }
     323       
     324}
     325
     326class Plugin_Upgrader extends WP_Upgrader {
     327
     328        var $result;
     329       
     330        function upgrade_strings() {
     331                $this->generic_strings();
     332                $this->strings['up_to_date'] = __('The plugin is at the latest version.');
     333                $this->strings['no_package'] = __('Upgrade package not available.');
     334                $this->strings['downloading_package'] = __('Downloading update from %s.');
     335                $this->strings['unpack_package'] = __('Unpacking the update.');
     336                $this->strings['deactivate_plugin'] = __('Deactivating the plugin.');
     337                $this->strings['remove_old'] = __('Removing the old version of the plugin.');
     338                $this->strings['remove_old_failed'] = __('Could not remove the old plugin.');
     339                $this->strings['process_failed'] = __('Plugin upgrade Failed.');
     340                $this->strings['process_success'] = __('Plugin upgraded successfully.');
     341        }
     342
     343        function install_strings() {
     344                $this->generic_strings();
     345                $this->strings['no_package'] = __('Install package not available.');
     346                $this->strings['downloading_package'] = __('Downloading install package from %s.');
     347                $this->strings['unpack_package'] = __('Unpacking the package.');
     348                $this->strings['installing_package'] = __('Installing the plugin.');
     349                $this->strings['process_failed'] = __('Plugin Install Failed.');
     350                $this->strings['process_success'] = __('Plugin Installed successfully.');
     351        }
     352
     353        function install($package) {
     354               
     355                $this->install_strings();
     356
     357                $this->run(array(
     358                                        'package' => $package,
     359                                        'destination' => WP_PLUGIN_DIR,
     360                                        'clear_destination' => false, //Do not overwrite files.
     361                                        'clear_working' => true,
     362                                        'hook_extra' => array()
     363                                        ));
     364       
     365                // Force refresh of plugin update information
     366                delete_transient('update_plugins');
     367
     368        }
     369
     370        function upgrade($plugin) {
     371               
     372                $this->upgrade_strings();
     373               
     374                $current = get_transient( 'update_plugins' );
     375                if ( !isset( $current->response[ $plugin ] ) ) {
     376                        $this->skin->error('up_to_date');
     377                        return false;
     378                        //return new WP_Error('up_to_date', $this->strings['up_to_date']);
     379                }
     380
     381                // Get the URL to the zip file
     382                $r = $current->response[ $plugin ];
     383               
     384                add_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'), 10, 2);
     385                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4);
     386                //'source_selection' => array(&$this, 'source_selection'), //theres a track ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins.
     387
     388                $this->run(array(
     389                                        'package' => $r->package,
     390                                        'destination' => WP_PLUGIN_DIR,
     391                                        'clear_destination' => true,
     392                                        'clear_working' => true,
     393                                        'hook_extra' => array(
     394                                                                'plugin' => $plugin
     395                                        )
     396                                ));
     397
     398                //Cleanup our hooks, incase something else does a upgrade on this connection.
     399                remove_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'));
     400                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'));
     401
     402                if ( ! $this->result || is_wp_error($this->result) )
     403                        return $this->result;
     404
     405                // Force refresh of plugin update information
     406                delete_transient('update_plugins');
     407        }
     408       
     409        //return plugin info.
     410        function plugin_info() {
     411                if ( ! is_array($this->result) )
     412                        return false;
     413                if ( empty($this->result['destination_name']) )
     414                        return false;
     415
     416                $plugin = get_plugins('/' . $this->result['destination_name']); //Ensure to pass with leading slash
     417                if ( empty($plugin) )
     418                        return false;
     419
     420                $pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
     421
     422                return $this->result['destination_name'] . '/' . $pluginfiles[0];       
     423        }
     424
     425        //Hooked to pre_install
     426        function deactivate_plugin_before_upgrade($return, $plugin) {
     427
     428                if ( is_wp_error($return) ) //Bypass.
     429                        return $return;
     430
     431                $plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
     432                if ( empty($plugin) )
     433                        return new WP_Error('bad_request', $this->strings['bad_request']);
     434
     435                if ( is_plugin_active($plugin) ) {
     436                        $this->skin->feedback('deactivate_plugin');
     437                        //Deactivate the plugin silently, Prevent deactivation hooks from running.
     438                        deactivate_plugins($plugin, true);
     439                }       
     440        }
     441
     442        //Hooked to upgrade_clear_destination
     443        function delete_old_plugin($removed, $local_destination, $remote_destination, $plugin) {
     444                global $wp_filesystem;
     445       
     446                if ( is_wp_error($removed) )
     447                        return $removed; //Pass errors through.
     448       
     449                $plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
     450                if ( empty($plugin) )
     451                        return new WP_Error('bad_request', $this->strings['bad_request']);
     452
     453                $plugins_dir = $wp_filesystem->wp_plugins_dir();
     454                $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) );
     455               
     456                if ( ! $wp_filesystem->exists($this_plugin_dir) ) //If its already vanished.
     457                        return $removed;
     458       
     459                // If plugin is in its own directory, recursively delete the directory.
     460                if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
     461                        $deleted = $wp_filesystem->delete($this_plugin_dir, true);
     462                else
     463                        $deleted = $wp_filesystem->delete($plugins_dir . $plugin);
     464
     465                if ( ! $deleted )
     466                        return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']);
     467               
     468                return $removed;
     469        }
     470}
     471
     472
     473class Theme_Upgrader extends WP_Upgrader {
     474
     475        var $result;
     476
     477        function upgrade_strings() {
     478                $this->generic_strings();
     479                $this->strings['up_to_date'] = __('The theme is at the latest version.');
     480                $this->strings['no_package'] = __('Upgrade package not available.');
     481                $this->strings['downloading_package'] = __('Downloading update from %s.');
     482                $this->strings['unpack_package'] = __('Unpacking the update.');
     483                $this->strings['remove_old'] = __('Removing the old version of the theme.');
     484                $this->strings['remove_old_failed'] = __('Could not remove the old theme.');
     485                $this->strings['process_failed'] = __('Theme upgrade Failed.');
     486                $this->strings['process_success'] = __('Theme upgraded successfully.');
     487        }
     488
     489        function install_strings() {
     490                $this->generic_strings();
     491                $this->strings['no_package'] = __('Install package not available.');
     492                $this->strings['downloading_package'] = __('Downloading install package from %s.');
     493                $this->strings['unpack_package'] = __('Unpacking the package.');
     494                $this->strings['installing_package'] = __('Installing the theme.');
     495                $this->strings['process_failed'] = __('Theme Install Failed.');
     496                $this->strings['process_success'] = __('Theme Installed successfully.');
     497        }
     498
     499        function install($package) {
     500               
     501                $this->install_strings();
     502
     503                $options = array(
     504                                                'package' => $package,
     505                                                'destination' => WP_CONTENT_DIR . '/themes',
     506                                                'clear_destination' => false, //Do not overwrite files.
     507                                                'clear_working' => true
     508                                                );
     509               
     510                $this->run($options);
     511       
     512                if ( ! $this->result || is_wp_error($this->result) )
     513                        return $this->result;
     514       
     515                // Force refresh of theme update information
     516                delete_transient('update_themes');
     517       
     518                if ( empty($result['destination_name']) )
     519                        return false;
     520                else
     521                        return $result['destination_name'];
     522        }
     523
     524        function upgrade($theme) {
     525               
     526                $this->upgrade_strings();
     527               
     528                // Is an update available?
     529                $current = get_transient( 'update_themes' );
     530                if ( !isset( $current->response[ $theme ] ) )
     531                        return new WP_Error('up_to_date', $this->strings['up_to_date']);
     532               
     533                $r = $current->response[ $theme ];
     534
     535                add_filter('upgrader_pre_install', array(&$this, 'current_before'), 10, 2);
     536                add_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2);
     537                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4);
     538
     539                $options = array(
     540                                                'package' => $r['package'],
     541                                                'destination' => WP_CONTENT_DIR . '/themes',
     542                                                'clear_destination' => true,
     543                                                'clear_working' => true,
     544                                                'hook_extra' => array(
     545                                                                                        'theme' => $theme
     546                                                                                        )
     547                                                );
     548               
     549                $this->run($options);
     550
     551                if ( ! $this->result || is_wp_error($this->result) )
     552                        return $this->result;
     553
     554                // Force refresh of theme update information
     555                delete_transient('update_themes');
     556
     557                return true;
     558        }
     559       
     560        function current_before($return, $theme) {
     561               
     562                if ( is_wp_error($return) )
     563                        return $return;
     564
     565                $theme = isset($theme['theme']) ? $theme['theme'] : '';
     566
     567                if ( $theme != get_stylesheet() ) //If not current
     568                        return $return;
     569                //Change to maintainence mode now.
     570                $this->maintenance_mode(true);
     571
     572                return $return;
     573        }
     574        function current_after($return, $theme) {
     575                if ( is_wp_error($return) )
     576                        return $return;
     577
     578                $theme = isset($theme['theme']) ? $theme['theme'] : '';
     579
     580                if ( $theme != get_stylesheet() ) //If not current
     581                        return $return;
     582
     583                //Ensure stylesheet name hasnt changed after the upgrade:
     584                if ( $theme == get_stylesheet() && $theme != $this->result['destination_name'] ) {
     585                        $theme_info = $this->theme_info();
     586                        $stylesheet = $this->result['destination_name'];
     587                        $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet;
     588                        switch_theme($template, $stylesheet, true);
     589                }
     590
     591                //Time to remove maintainence mode
     592                $this->maintenance_mode(false);
     593                return $return;
     594        }
     595       
     596        function delete_old_theme($removed, $local_destination, $remote_destination, $theme) {
     597                global $wp_filesystem;
     598       
     599                $theme = isset($theme['theme']) ? $theme['theme'] : '';
     600       
     601                if ( is_wp_error($removed) || empty($theme) )
     602                        return $removed; //Pass errors through.
     603               
     604                $themes_dir = $wp_filesystem->wp_themes_dir();
     605                if ( $wp_filesystem->exists( trailingslashit($themes_dir) . $theme ) )
     606                        if ( ! $wp_filesystem->delete( trailingslashit($themes_dir) . $theme, true ) )
     607                                return false;
     608                return true;
     609        }
     610       
     611        function theme_info() {
     612                if ( empty($this->result['destination_name']) )
     613                        return false;
     614                return get_theme_data(WP_CONTENT_DIR . '/themes/' . $this->result['destination_name'] . '/style.css');
     615        }
     616
     617}
     618
     619//Untested.
     620class Core_Upgrader extends WP_Upgrader {
     621
     622        function upgrade_strings() {
     623                $this->generic_strings();
     624                $this->strings['up_to_date'] = __('WordPress is at the latest version.');
     625                $this->strings['no_package'] = __('Upgrade package not available.');
     626                $this->strings['downloading_package'] = __('Downloading update from %s.');
     627                $this->strings['unpack_package'] = __('Unpacking the update.');
     628                $this->strings['copy_failed'] = __('Could not copy files.');
     629        }
     630
     631        function upgrade($current) {
     632                global $wp_filesystem;
     633                $this->upgrade_strings();
     634               
     635       
     636                if ( !empty($feedback) )
     637                        add_filter('update_feedback', $feedback);
     638       
     639                // Is an update available?
     640                if ( !isset( $current->response ) || $current->response == 'latest' )
     641                        return new WP_Error('up_to_date', $this->strings['up_to_date']);
     642
     643                $res = $this->fs_connect( array(ABSPATH, WP_CONTENT_DIR) );
     644                if ( is_wp_error($res) )
     645                        return $res;
     646               
     647                $wp_dir = trailingslashit($wp_filesystem->abspath());
     648               
     649                $download = $this->download_package( $current->package );
     650                if ( is_wp_error($download) )
     651                        return $download;
     652               
     653                $working_dir = $this->unpack_package( $download );
     654                if ( is_wp_error($working_dir) )
     655                        return $working_dir;
     656
     657                // Copy update-core.php from the new version into place.
     658                if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
     659                        $wp_filesystem->delete($working_dir, true);
     660                        return new WP_Error('copy_failed', $this->strings['copy_failed']);
     661                }
     662                $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
     663       
     664                require(ABSPATH . 'wp-admin/includes/update-core.php');
     665       
     666                return update_core($working_dir, $wp_dir);
     667        }
     668
     669}
     670
     671
     672/**
     673 * Skin stuff here.
     674 * ============================================
     675 * ============================================
     676 * ============================================
     677 */
     678
     679class WP_Upgrader_Skin {
     680       
     681        var $upgrader;
     682        var $done_header = false;
     683       
     684        function WP_Upgrader_Skin($args = array()) {
     685                return __construct($args);
     686        }
     687        function __construct($args = array()) {
     688                $defaults = array( 'url' => '', 'nonce' => '', 'title' => '' );
     689                $this->options = wp_parse_args($args, $defaults);
     690        }
     691       
     692        function set_upgrader(&$upgrader) {
     693                if ( is_object($upgrader) )
     694                        $this->upgrader =& $upgrader;
     695        }
     696        function set_result($result) {
     697                $this->result = $result;
     698        }
     699       
     700        function request_filesystem_credentials($error = false) {
     701                $url = $this->options['url'];
     702                if ( !empty($this->options['nonce']) )
     703                        $url = wp_nonce_url($url, $this->options['nonce']);
     704                return request_filesystem_credentials($url, '', $error); //Possible to bring inline, Leaving as0is for now.
     705        }
     706       
     707        function header() {
     708                if ( $this->done_header )
     709                        return;
     710                $this->done_header = true;
     711                echo '<div class="wrap">';
     712                echo screen_icon();
     713                echo '<h2>' . $this->options['title'] . '</h2>';       
     714        }
     715        function footer() {
     716                echo '</div>';
     717        }
     718       
     719        function error($errors) {
     720                if ( ! $this->done_header )
     721                        $this->header();
     722                if ( is_string($errors) ) {
     723                        $this->feedback($errors);
     724                } elseif ( is_wp_error($errors) && $errors->get_error_code() ) {
     725                        foreach ( $errors->get_error_messages() as $message )
     726                                $this->feedback($message);
     727                }
     728        }
     729
     730        function feedback($string) {
     731                if ( isset( $this->upgrader->strings[$string]) )
     732                        $string = $this->upgrader->strings[$string];
     733
     734                $args = func_get_args();
     735                $args = array_splice($args, 1);
     736                if ( !empty($args) )
     737                        $string = vsprintf($string, $args);
     738                if ( empty($string) )
     739                        return;
     740                show_message($string);
     741        }       
     742        function before() {}
     743        function after() {}
     744       
     745}
     746
     747class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
     748        var $plugin = '';
     749        var $plugin_active = false;
     750
     751        function Plugin_Upgrader_Skin($args = array()) {
     752                return __construct($args);
     753        }
     754
     755        function __construct($args = array()) {
     756                $defaults = array( 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => __('Upgrade Plugin') );
     757                $args = wp_parse_args($args, $defaults);
     758
     759                $this->plugin = $args['plugin'];
     760
     761                $this->plugin_active = is_plugin_active($this->plugin);
     762               
     763                parent::__construct($args);
     764        }
     765       
     766        function after() {
     767                $this->plugin = $this->upgrader->plugin_info();
     768                if( !empty($this->plugin) && !is_wp_error($this->result) && $this->plugin_active ){
     769                        show_message(__('Attempting reactivation of the plugin'));
     770                        echo '<iframe style="border:0;overflow:hidden" width="100%" height="170px" src="' . wp_nonce_url('update.php?action=activate-plugin&plugin=' . $this->plugin, 'activate-plugin_' . $this->plugin) .'"></iframe>';
     771                }
     772                $update_actions =  array(
     773                        'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $this->plugin, 'activate-plugin_' . $this->plugin) . '" title="' . attribute_escape(__('Activate this plugin')) . '" target="_parent">' . __('Activate Plugin') . '</a>',
     774                        'plugins_page' => '<a href="' . admin_url('plugins.php') . '" title="' . attribute_escape(__('Goto plugins page')) . '" target="_parent">' . __('Return to Plugins page') . '</a>'
     775                );
     776                if ( $this->plugin_active )
     777                        unset( $update_actions['activate_plugin'] );
     778                if ( ! $this->result || is_wp_error($this->result) )
     779                        unset( $update_actions['activate_plugin'] );
     780
     781                $update_actions = apply_filters('update_plugin_complete_actions', $update_actions, $this->plugin);
     782                if ( ! empty($update_actions) )
     783                        $this->feedback('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$update_actions));
     784        }
     785}
     786
     787
     788class Plugin_Installer_Skin extends WP_Upgrader_Skin {
     789        var $api;
     790        var $type;
     791
     792        function Plugin_Installer_Skin($args = array()) {
     793                return __construct($args);
     794        }
     795
     796        function __construct($args = array()) {
     797                $defaults = array( 'type' => 'web', 'url' => '', 'plugin' => '', 'nonce' => '', 'title' => '' );
     798                $args = wp_parse_args($args, $defaults);
     799               
     800                $this->type = $args['type'];
     801                $this->api = isset($args['api']) ? $args['api'] : array();
     802               
     803                parent::__construct($args);
     804        }
     805
     806        function before() {
     807                if ( !empty($this->api) )
     808                        $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the plugin <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
     809        }
     810       
     811        function after() {
     812
     813                $plugin_file = $this->upgrader->plugin_info();
     814
     815                $install_actions = array(
     816                        'activate_plugin' => '<a href="' . wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file, 'activate-plugin_' . $plugin_file) . '" title="' . attribute_escape(__('Activate this plugin')) . '" target="_parent">' . __('Activate Plugin') . '</a>',
     817                                                        );
     818
     819                if ( $this->type == 'web' )
     820                        $install_actions['plugins_page'] = '<a href="' . admin_url('plugin-install.php') . '" title="' . attribute_escape(__('Return to Plugin Installer')) . '" target="_parent">' . __('Return to Plugin Installer') . '</a>';
     821                else
     822                        $install_actions['plugins_page'] = '<a href="' . admin_url('plugins.php') . '" title="' . attribute_escape(__('Return to Plugins page')) . '" target="_parent">' . __('Return to Plugins page') . '</a>';
     823
     824
     825                if ( ! $this->result || is_wp_error($this->result) )
     826                        unset( $update_actions['activate_plugin'] );
     827
     828                $install_actions = apply_filters('install_plugin_complete_actions', $install_actions, $this->api, $plugin_file);
     829                if ( ! empty($install_actions) )
     830                        $this->feedback('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
     831        }
     832}
     833
     834class Theme_Installer_Skin extends WP_Upgrader_Skin {
     835        var $api;
     836        var $type;
     837
     838        function Theme_Installer_Skin($args = array()) {
     839                return __construct($args);
     840        }
     841
     842        function __construct($args = array()) {
     843                $defaults = array( 'type' => 'web', 'url' => '', 'theme' => '', 'nonce' => '', 'title' => '' );
     844                $args = wp_parse_args($args, $defaults);
     845               
     846                $this->type = $args['type'];
     847                $this->api = isset($args['api']) ? $args['api'] : array();
     848               
     849                parent::__construct($args);
     850        }
     851
     852        function before() {
     853                if ( !empty($this->api) )
     854                        $this->upgrader->strings['process_success'] = sprintf( __('Successfully installed the theme <strong>%s %s</strong>.'), $this->api->name, $this->api->version);
     855        }
     856       
     857        function after() {
     858                if ( empty($this->upgrader->result['destination_name']) )
     859                        return;
     860
     861                $theme_info = $this->upgrader->theme_info();
     862                if ( empty($theme_info) )
     863                        return;
     864                $name = $theme_info['Name'];
     865                $stylesheet = $this->upgrader->result['destination_name'];
     866                $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet;
     867               
     868                $preview_link = htmlspecialchars( add_query_arg( array('preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'TB_iframe' => 'true' ), trailingslashit(clean_url(get_option('home'))) ) );
     869                $activate_link = wp_nonce_url("themes.php?action=activate&amp;template=" . urlencode($template) . "&amp;stylesheet=" . urlencode($stylesheet), 'switch-theme_' . $template);
     870               
     871                $install_actions = array(
     872                        'preview' => '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' . attribute_escape(sprintf(__('Preview "%s"'), $name)) . '">' . __('Preview') . '</a>',
     873                        'activate' => '<a href="' . $activate_link .  '" class="activatelink" title="' . attribute_escape( sprintf( __('Activate "%s"'), $name ) ) . '">' . __('Activate') . '</a>'
     874                                                        );
     875
     876                if ( $this->type == 'web' )
     877                        $install_actions['themes_page'] = '<a href="' . admin_url('theme-install.php') . '" title="' . attribute_escape(__('Back to Theme Installer')) . '" target="_parent">' . __('Return to Theme Installer.') . '</a>';
     878                else
     879                        $install_actions['themes_page'] = '<a href="' . admin_url('themes.php') . '" title="' . attribute_escape(__('Themes page')) . '" target="_parent">' . __('Return to Themes page') . '</a>';
     880
     881                if ( ! $this->result || is_wp_error($this->result) )
     882                        unset( $update_actions['activate'], $update_actions['preview'] );
     883
     884                $install_actions = apply_filters('install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info);
     885                if ( ! empty($install_actions) )
     886                        $this->feedback('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$install_actions));
     887        }
     888}
     889
     890class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
     891        var $theme = '';
     892
     893        function Theme_Upgrader_Skin($args = array()) {
     894                return __construct($args);
     895        }
     896
     897        function __construct($args = array()) {
     898                $defaults = array( 'url' => '', 'theme' => '', 'nonce' => '', 'title' => __('Upgrade Theme') );
     899                $args = wp_parse_args($args, $defaults);
     900
     901                $this->theme = $args['theme'];
     902               
     903                parent::__construct($args);
     904        }
     905       
     906        function after() {
     907
     908                if ( empty($this->upgrader->result['destination_name']) )
     909                        return;
     910
     911                $theme_info = $this->upgrader->theme_info();
     912                if ( empty($theme_info) )
     913                        return;
     914                $name = $theme_info['Name'];
     915                $stylesheet = $this->upgrader->result['destination_name'];
     916                $template = !empty($theme_info['Template']) ? $theme_info['Template'] : $stylesheet;
     917               
     918                $preview_link = htmlspecialchars( add_query_arg( array('preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'TB_iframe' => 'true' ), trailingslashit(clean_url(get_option('home'))) ) );
     919                $activate_link = wp_nonce_url("themes.php?action=activate&amp;template=" . urlencode($template) . "&amp;stylesheet=" . urlencode($stylesheet), 'switch-theme_' . $template);
     920
     921                $update_actions =  array(
     922                        'preview' => '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' . attribute_escape(sprintf(__('Preview "%s"'), $name)) . '">' . __('Preview') . '</a>',
     923                        'activate' => '<a href="' . $activate_link .  '" class="activatelink" title="' . attribute_escape( sprintf( __('Activate "%s"'), $name ) ) . '">' . __('Activate') . '</a>',
     924                        'themes_page' => '<a href="' . admin_url('themes.php') . '" title="' . attribute_escape(__('Return to Themes page')) . '" target="_parent">' . __('Return to Themes page') . '</a>',
     925                );
     926                if ( ( ! $this->result || is_wp_error($this->result) ) || $stylesheet == get_stylesheet() )
     927                        unset($update_actions['preview'], $update_actions['activate']);
     928       
     929                $update_actions = apply_filters('update_theme_complete_actions', $update_actions, $this->theme);
     930                if ( ! empty($update_actions) )
     931                        $this->feedback('<strong>' . __('Actions:') . '</strong> ' . implode(' | ', (array)$update_actions));
     932        }
     933}
     934
     935class File_Upload_Upgrader {
     936        var $package;
     937        var $filename;
     938
     939        function File_Upload_Upgrader($form, $urlholder) {
     940                return __construct($form, $urlholder);
     941        }
     942        function __construct($form, $urlholder) {
     943                if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
     944                        wp_die($uploads['error']);
     945               
     946                if ( empty($_FILES[$form]['name']) && empty($_GET[$urlholder]) )
     947                        wp_die(__('Please select a file'));
     948       
     949                if ( !empty($_FILES) )
     950                        $this->filename = $_FILES[$form]['name'];
     951                else if ( isset($_GET[$urlholder]) )
     952                        $this->filename = $_GET[$urlholder];
     953
     954                //Handle a newly uploaded file, Else assume its already been uploaded
     955                if ( !empty($_FILES) ) {
     956                        $this->filename = wp_unique_filename( $uploads['basedir'], $this->filename );
     957                        $this->package = $uploads['basedir'] . '/' . $this->filename;
     958       
     959                        // Move the file to the uploads dir
     960                        if ( false === @ move_uploaded_file( $_FILES[$form]['tmp_name'], $this->package) )
     961                                wp_die( sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path']));
     962                } else {
     963                        $this->package = $uploads['basedir'] . '/' . $this->filename;
     964                }
     965        }
     966}