WordPress.org

Make WordPress Core

Ticket #11915: upload_upgrade.diff

File upload_upgrade.diff, 5.3 KB (added by cyberhobo, 8 years ago)

First draft of a solution

  • wp-admin/includes/plugin-install.php

     
    215215                <?php wp_nonce_field( 'plugin-upload') ?>
    216216                <label class="screen-reader-text" for="pluginzip"><?php _e('Plugin zip file'); ?></label>
    217217                <input type="file" id="pluginzip" name="pluginzip" />
     218                <input type="checkbox" id="upgrade_checked" name="upgrade_checked" />
     219                <label for="upgrade_checked"><?php _e('Replace current plugin'); ?></label>
    218220                <input type="submit" class="button" value="<?php esc_attr_e('Install Now') ?>" />
    219221        </form>
    220222<?php
  • wp-admin/includes/class-wp-upgrader.php

     
    265265                return $this->result;
    266266        }
    267267
     268        /**
     269         * Find out which plugin is in the working dir.
     270         *
     271         * Similar to get_plugins(), but in the working directory
     272         * Should that function be adapted to this purpose?
     273         *
     274         * @param string $working_dir Mystery plugin directory.
     275         * @return string|WP_Error The plugin in the directory or an error.
     276         */
     277        function get_working_plugin( $working_dir ) {
     278                global $wp_filesystem;
     279
     280                $working_files = $wp_filesystem->dirlist( $working_dir );
     281                $working_subdir = '.';
     282                $plugin_dir = basename( $working_dir );
     283                $plugins = array();
     284                if ( 1 == count( $working_files ) ) {
     285                        // Check for a subdirectory
     286                        $dir_names = array_keys( $working_files );
     287                        if ( 'd' == $working_files[$dir_names[0]]['type'] ) {
     288                                $working_subdir = $plugin_dir = $dir_names[0];
     289                                $working_files = $wp_filesystem->dirlist( trailingslashit( $working_dir ) . $working_subdir );
     290                        }
     291                }
     292                if ( ! empty( $working_files ) ) {
     293                        foreach( $working_files as $file => $properties ) {
     294                                if ( substr( $file, -4 ) == '.php' ) {
     295                                        $plugin_data = get_plugin_data( trailingslashit( $working_dir ) . $working_subdir . '/' . $file, false, false );
     296
     297                                        if ( empty( $plugin_data['Name'] ) )
     298                                                continue;
     299
     300                                        $plugins[] = $plugin_dir . '/' . $file;
     301                                }
     302                        }
     303                }
     304
     305                if ( count( $plugins ) != 1 ) {
     306                        // More trouble than it's worth handling multple plugins in a package?
     307                        return new WP_Error('bad_package', $this->strings['bad_package']);
     308                }
     309
     310                return $plugins[0];
     311        }
     312
    268313        function run($options) {
    269314
    270315                $defaults = array(      'package' => '', //Please always pass this.
     
    272317                                                        'clear_destination' => false,
    273318                                                        'clear_working' => true,
    274319                                                        'is_multi' => false,
    275                                                         'hook_extra' => array() //Pass any extra $hook_extra args here, this will be passed to any hooked filters.
     320                                                        'hook_extra' => array(), //Pass any extra $hook_extra args here, this will be passed to any hooked filters.
     321                                                  'is_upload_upgrade' => false 
    276322                                                );
    277323
    278324                $options = wp_parse_args($options, $defaults);
     
    307353                        return $working_dir;
    308354                }
    309355
     356                if ( $is_upload_upgrade and empty( $hook_extra ) ) {
     357                        // Doesn't work on plugins without their own subdirectory?
     358                        $plugin = $this->get_working_plugin( $working_dir );
     359
     360                        if ( is_wp_error($plugin) ) {
     361                                $this->skin->error($plugin);
     362                                return $plugin;
     363                        }
     364
     365                        // This upgrade method depends on this identification of the plugin for hooks
     366                        $hook_extra = array( 'plugin' => $plugin );
     367                }
     368
    310369                //With the given options, this installs it to the destination directory.
    311370                $result = $this->install_package( array(
    312371                                                                                        'source' => $working_dir,
     
    402461
    403462        }
    404463
     464        function upload_upgrade($package) {
     465
     466                $this->init();
     467                $this->upgrade_strings();
     468
     469                add_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'), 10, 2);
     470                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4);
     471
     472                $this->run(array(
     473                                        'package' => $package,
     474                                        'destination' => WP_PLUGIN_DIR,
     475                                        'clear_destination' => true,
     476                                        'clear_working' => true,
     477                                        'hook_extra' => array(), // run must supply this after looking in the package
     478                                        'is_upload_upgrade' => true
     479                                ));
     480
     481                // Cleanup our hooks, incase something else does a upgrade on this connection.
     482                remove_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'));
     483                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'));
     484
     485                if ( ! $this->result || is_wp_error($this->result) )
     486                        return $this->result;
     487
     488                // Force refresh of plugin update information
     489                delete_site_transient('update_plugins');
     490        }
     491
    405492        function upgrade($plugin) {
    406493
    407494                $this->init();
  • wp-admin/update.php

     
    110110                $type = 'upload'; //Install plugin type, From Web or an Upload.
    111111
    112112                $upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( compact('type', 'title', 'nonce', 'url') ) );
    113                 $upgrader->install( $file_upload->package );
     113                if ( isset( $_REQUEST['upgrade_checked'] ) )
     114                        $upgrader->upload_upgrade( $file_upload->package );
     115                else
     116                        $upgrader->install( $file_upload->package );
    114117
    115118                include('admin-footer.php');
    116119
     
    195198        } else {
    196199                do_action('update-custom_' . $action);
    197200        }
    198 }
    199  No newline at end of file
     201}