Make WordPress Core

Changeset 6779


Ignore:
Timestamp:
02/11/2008 05:45:54 AM (19 years ago)
Author:
ryan
Message:

First cut at plugin update. Props DD32 for the filesystem abstraction. see #5586

Location:
trunk/wp-admin
Files:
6 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/file.php

    r6551 r6779  
    172172}
    173173
     174/**
     175* Downloads a url to a local file using the Snoopy HTTP Class
     176*
     177* @param string $url the URL of the file to download
     178* @return mixed false on failure, string Filename on success.
     179*/
     180function download_url( $url ) {
     181        //WARNING: The file is not automatically deleted, The script must unlink() the file.
     182        if( ! $url )
     183                return false;
     184
     185        $tmpfname = tempnam('/tmp', 'wpupdate');
     186        if( ! $tmpfname )
     187                return false;
     188
     189        $handle = fopen($tmpfname, 'w');
     190        if( ! $handle )
     191                return false;
     192
     193        require_once( ABSPATH . 'wp-includes/class-snoopy.php' );
     194        $snoopy = new Snoopy();
     195        $snoopy->fetch($url);
     196       
     197        fwrite($handle, $snoopy->results);
     198        fclose($handle);
     199
     200        return $tmpfname;
     201}
     202
     203function unzip_file($file, $to) {
     204        global $wp_filesystem;
     205
     206        if ( ! $wp_filesystem || !is_object($wp_filesystem) )
     207                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
     208                       
     209        $fs =& $wp_filesystem;
     210
     211        require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
     212
     213        $archive = new PclZip($file);
     214
     215        // Is the archive valid?
     216        if ( false == ($archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) )
     217                return new WP_Error('incompatible_archive', __('Incompatible archive'), $archive->error_string);
     218
     219        if ( 0 == count($archive_files) )
     220                return new WP_Error('empty_archive', __('Empty archive'));
     221
     222        $to = trailingslashit($to);
     223        $path = explode('/', $to);
     224        $tmppath = '';
     225        for ( $j = 0; $j < count($path) - 1; $j++ ) {
     226                $tmppath .= $path[$j] . '/';
     227                if ( ! $fs->is_dir($tmppath) ) {
     228                        $fs->mkdir($tmppath);
     229                } else {
     230                        $fs->setDefaultPermissions( $fs->getchmod($tmppath) );
     231                }
     232        }
     233
     234        foreach ($archive_files as $file) {
     235                $path = explode('/', $file['filename']);
     236                $tmppath = '';
     237
     238                // Loop through each of the items and check that the folder exists.
     239                for ( $j = 0; $j < count($path) - 1; $j++ ) {
     240                        $tmppath .= $path[$j] . '/';
     241                        if ( ! $fs->is_dir($to . $tmppath) )
     242                                $fs->mkdir($to . $tmppath);
     243                }
     244
     245                // We've made sure the folders are there, so let's extract the file now:
     246                if ( ! $file['folder'] )
     247                        $fs->put_contents( $to . $file['filename'], $file['content']);
     248        }
     249}
     250
     251function copy_dir($from, $to) {
     252        global $wp_filesystem;
     253
     254        $dirlist = $wp_filesystem->dirlist($from);
     255
     256        $from = trailingslashit($from);
     257        $to = trailingslashit($to);
     258
     259        foreach ( (array) $dirlist as $filename => $fileinfo ) {
     260                if ( 'file' == $fileinfo['type'] ) {
     261                        $wp_filesystem->copy($from . $filename, $to . $filename, true);
     262                } elseif ( 'folder' == $fileinfo['type'] ) {
     263                        $wp_filesystem->mkdir($to . $filename);
     264                        copy_dir($from . $filename, $to . $filename);
     265                }
     266        }
     267}
     268
     269function WP_Filesystem( $args = false, $preference = false ) {
     270        global $wp_filesystem;
     271
     272        $method = get_filesystem_method($preference);
     273        if ( ! $method )
     274                return false;
     275
     276        require_once('class-wp-filesystem-'.$method.'.php');
     277        $method = "WP_Filesystem_$method";
     278
     279        $wp_filesystem = new $method($args);
     280
     281        if ( $wp_filesystem->errors->get_error_code() )
     282                return false;
     283
     284        if ( !$wp_filesystem->connect() )
     285                return false; //There was an erorr connecting to the server.
     286
     287        return true;
     288}
     289
     290function get_filesystem_method() {
     291        $tempFile = tempnam('/tmp', 'WPU');
     292
     293        if ( getmyuid() == fileowner($tempFile) ) {
     294                unlink($tempFile);
     295                //return 'direct';
     296        } else {
     297                unlink($tempFile);
     298        }
     299
     300        if ( extension_loaded('ftp') ) return 'ftpext';
     301        if ( extension_loaded('sockets') ) return 'ftpsockets';
     302        return false;
     303}
     304
    174305?>
  • trunk/wp-admin/includes/update.php

    r6551 r6779  
    115115
    116116        echo "<tr><td colspan='5' class='plugin-update'>";
    117         printf( __('There is a new version of %s available. <a href="%s">Download version %s here</a>.'), $plugin_data['Name'], $r->url, $r->new_version );
     117        printf( __('There is a new version of %1$s available. <a href="%2$s">Download version %3$s here</a> or <a href="%4$s">upgrade automatically</a>.'), $plugin_data['Name'], $r->url, $r->new_version, "update.php?action=upgrade-plugin&amp;plugin=$file" );
    118118        echo "</td></tr>";
    119119}
    120120add_action( 'after_plugin_row', 'wp_plugin_update_row' );
    121121
     122function wp_update_plugin($plugin, $feedback = '') {
     123        global $wp_filesystem;
     124
     125        if ( !empty($feedback) )
     126                add_filter('update_feedback', $feedback);
     127
     128        // Is an update available?
     129        $current = get_option( 'update_plugins' );
     130        if ( !isset( $current->response[ $plugin ] ) )
     131                return new WP_Error('up_to_date', __('The plugin is at the latest version.'));
     132
     133        // Is a filesystem accessor setup?
     134        if ( ! $wp_filesystem || !is_object($wp_filesystem) )
     135                WP_Filesystem();
     136
     137        if ( ! is_object($wp_filesystem) )
     138                return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
     139
     140        if ( $wp_filesystem->errors->get_error_code() )
     141                return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
     142
     143        // Get the URL to the zip file
     144        $r = $current->response[ $plugin ];
     145
     146        if ( empty($r->package) )
     147                return new WP_Error('no_package', __('Upgrade package not available.'));
     148
     149        // Download the package
     150        $package = $r->package;
     151        apply_filters('update_feedback', __("Downloading update from $package"));
     152        $file = download_url($package);
     153
     154        if ( !$file )
     155                return new WP_Error('download_failed', __('Download failed.'));
     156
     157        $name = basename($plugin, '.php');
     158        $working_dir = ABSPATH . 'wp-content/upgrade/' . $name;
     159
     160        // Clean up working directory
     161        $wp_filesystem->delete($working_dir, true);
     162
     163        apply_filters('update_feedback', __("Unpacking the update"));
     164        // Unzip package to working directory
     165        $result = unzip_file($file, $working_dir);
     166        if ( is_wp_error($result) ) {
     167                unlink($file);
     168                $wp_filesystem->delete($working_dir, true);
     169                return $result;
     170        }
     171
     172        // Once installed, delete the package
     173        unlink($file);
     174       
     175        // Remove the existing plugin.
     176        apply_filters('update_feedback', __("Removing the old version of the plugin"));
     177        $wp_filesystem->delete(ABSPATH . PLUGINDIR . "/$plugin");
     178        $plugin_dir = dirname(ABSPATH . PLUGINDIR . "/$plugin");
     179
     180        // If plugin is in its own directory, recursively delete the directory.
     181        if ( '.' != $plugin_dir )
     182                $wp_filesystem->delete($plugin_dir, true);
     183
     184        apply_filters('update_feedback', __("Installing the latest version"));
     185        // Copy new version of plugin into place.
     186        copy_dir($working_dir, ABSPATH . PLUGINDIR);
     187
     188        // Remove working directory
     189        $wp_filesystem->delete($working_dir, true);
     190
     191        // Force refresh of plugin update information
     192        delete_option('update_plugins');
     193}
     194
    122195?>
Note: See TracChangeset for help on using the changeset viewer.