Make WordPress Core

Changeset 6779


Ignore:
Timestamp:
02/11/2008 05:45:54 AM (17 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.