Is it possible to create a WordPress plugin zip file from an installed plugin?

I have a WordPress installation and some plugins installed and activated. But I have lost the original plugins .zip files. I would like to install some of the plugins into a new WordPress.

I do not want to migrate/move/backup-restore the whole current WP installation. I just want to re-create the original plugin .zip files for some of the plugins that are installed. I do have access to the whole file tree as well as the database. Is there any method for doing that?

Related posts

Leave a Reply

3 comments

  1. Yes, first add a download link to the plugin action links:

    /**
     * Add action links to each plugin
     * @author brasofilo
     */
    add_filter( 'plugin_action_links', function ( $plugin_meta, $plugin_file, $plugin_data, $status ) 
    {
        $plugin_dir = dirname( $plugin_file );
        if( !empty( $plugin_dir ) && '.' !== $plugin_dir )
            $plugin_meta[] = sprintf( 
                "<a href='#' class='down-zip down-icon' data-file='%s' title='%s'></a>",
                $plugin_dir,
                'Download zip file for ' . $plugin_data['Name']
            );
        else
            $plugin_meta[] = "Root plugin, cannot zip";
    
        return $plugin_meta;
    }, 10, 4 );
    

    Then style and attach JS actions:

    /**
     * Style and actions for wp-admin/plugins.php
     * @author brasofilo
     */
    add_action( 'admin_footer-plugins.php', function() {
        ?>
        <style>
        .down-icon:before { /* http://melchoyce.github.io/dashicons/ */
            content: "f316";
            display: inline-block;
            -webkit-font-smoothing: antialiased;
            font: normal 20px/1 'dashicons';
            vertical-align: top;
        }
        </style>
        <script>
        root_wp = '<?php echo WP_PLUGIN_DIR; ?>' + '/';
    
        /**
         * Virtual $_POST
         * creates form, appends and submits
         *
         * @author https://stackoverflow.com/a/9815335/1287812
         */
        function b5f_submit_form_post( path, params, method ) 
        {
            $ = jQuery;
            method = method || "post"; // Set method to post by default, if not specified.
    
            var form = $(document.createElement( "form" ))
                .attr( {"method": method, "action": path} );
    
            $.each( params, function(key,value)
            {
                $.each( value instanceof Array? value : [value], function(i,val)
                {
                    $(document.createElement("input"))
                        .attr({ "type": "hidden", "name": key, "value": val })
                        .appendTo( form );
                }); 
            }); 
    
            form.appendTo( document.body ).submit();
        }
    
        jQuery(document).ready(function($) 
        {   
            /**
             * Fire a plugin download
             */
            $("a.down-zip").click(function() 
            {  
                event.preventDefault();
    
                b5f_submit_form_post( '', { 
                    action: 'zip_a_plugin',
                    plugin_to_zip: root_wp + $(this).data('file'), 
                    plugin_name: $(this).data('file')
                });
            });
        });            
        </script>
        <?php
    });
    

    Capture the custom $_POSTed data and process the plugin directory to zip:

    /**
     * Dispatch $_POST['action']=>'zip_a_plugin' custom action
     * @author brasofilo https://stackoverflow.com/a/23546276/1287812
     */ 
    add_action('admin_action_zip_a_plugin', function() 
    {
        if( empty( $_REQUEST['plugin_to_zip'] ) )
            return;
    
        zipFile( $_REQUEST['plugin_to_zip'], $_REQUEST['plugin_name'], false );
    });
    

    And finally, using a zipping function found here on the Stack

    /**
     * Makes zip from folder
     * @author https://stackoverflow.com/a/17585672/1287812
     */
    function zipFile($source, $destination, $flag = '')
    {
        if ( !extension_loaded('zip') ) {
            return false;
        }
    
        $zip = new ZipArchive();
        $tmp_file = tempnam(WP_CONTENT_DIR,'');
        if (!$zip->open($tmp_file, ZIPARCHIVE::CREATE)) {
            return false;
        }
    
        $source = str_replace('', '/', realpath($source));
        if($flag)
        {
            $flag = basename($source) . '/';
            //$zip->addEmptyDir(basename($source) . '/');
        }
    
        if (is_dir($source) === true)
        {
            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
            foreach ($files as $file)
            {
                $file = str_replace('', '/', realpath($file));
    
                if (is_dir($file) === true)
                {
                    $src = str_replace($source . '/', '', $flag.$file . '/');
                    if( WP_PLUGIN_DIR.'/' !== $src ) # Workaround, as it was creating a strange empty folder like /www_dev/dev.plugins/wp-content/plugins/
                        $zip->addEmptyDir( $src );
                }
                else if (is_file($file) === true)
                {
                    $src = str_replace($source . '/', '', $flag.$file);
                    $zip->addFromString( $src, file_get_contents($file));
                }
            }
        }
        else if (is_file($source) === true)
        {
            $zip->addFromString($flag.basename($source), file_get_contents($source));
        }
    
        $tt = $zip->close();
        if(file_exists($tmp_file))
        {
            // push to download the zip
            header('Content-type: application/zip');
            header('Content-Disposition: attachment; filename="'.$destination.'"');
            readfile($tmp_file);
            // remove zip file is exists in temp path
            exit();
        } 
        else {
            echo $tt;
            die();
        }
    }
    
  2. Funnily enough, it’s actually trivial to create a zip file from an existing plugin.

    Simply create a zip file containing the plugin folder. The unix commands to do that are:

    $ cd wp-content/plugins
    $ zip -r my-plugin.zip my-plugin
    

    You can then download the resulting my-plugin.zip file which can then be used in WordPress plugin install via upload on new sites (ie: WP Admin -> Plugins -> Add New -> Upload).

    Obviously the zip file won’t contain any database tables/mods, but most plugins test for this on install and perform any needed database upgrades at install time. Unfortunately there’s no way to know whether this will be a problem without testing or checking the plugin source code, or both.