Expand use of WP_Upgrader Class

  1. kynatro

    I've recently written a plugin that has the ability to render its output through a skinning system. While writing functionality that would allow the user to add new skins to their collection via an upload functionality (mimicking WordPress' plugin and theme upload experience) I encountered a part of the WP_Upgrader class that could use some improvement.

    Example Setup:

    • We have a custom destination directory housing all uploaded skin asset files in sub-directories. This skin directory is created upon plugin activation.
    • Uploads are handled by submitting to the /wp-admin/update.php file with a custom $_GET['action'] value specified.
    • Upload processing is achieved by hooking into the "update-custom_" . $action action at the end of the /wp-admin/update.php file
    • We have created custom child classes for WP_Upgrader and WP_Upgrader_Skin in order to utilize the same upload, validation and processing functionality used by the WordPress core for plugin and theme installation and upload handling.

    The problem that revealed the need to make the WP_Upgrader class more flexible
    When we modeled our structure for the WP_Upgrader and WP_Upgrader_Skin child classes off of the existing Plugin_Upgrader and Plugin_Installer_Skin child classes we ran into some problems when the ZIP files we were uploading for our skins were being copied to the skin directory we had created. When the WP_Upgrader class processed the files with the install_package() method it couldn't create a sub-directory with the mkdir() command. After extensive debugging it was discovered that the destination directories did not include sub-directories named after the uploaded ZIP file or after the sub-directory included in the ZIP file as would normally be expected when uploading a plugin or theme. For example:

    • A file name my-skin.zip is uploaded.
    • The my-skin.zip file contains a directory named my-skin which contains all assets for the skin.
    • When uploaded, the desired result is that a sub-directory called my-skin would be created in the skins directory, but instead the destination directory according to the install_package() method is still just the skins directory - no my-skin sub-directory, unfortunately resulting in an error.

    Upon further investigation I found that the reason themes and plugins can be uploaded with the destination directory merely specified as /wp-content/plugins or /wp-content/themes is because the install_package() method is hard-coded, statically accommodating for those specific folders (see line 210-213 of /wp-admin/class-wp-upgrader.php since version 3.3 of WordPress).

    Unfortunately we cannot just specify the destination directory for the newly uploaded skin including the skin's expected sub-directory when calling the WP_Upgrader->run() command as it causes an error when WP_Upgrader->fs_connect() is called since the sub-directory does not exist yet.

    Our solution:
    To circumvent this we merely overloaded the install_package() method in our WP_Upgrader child class and extended custom filters to allow us to re-define the $remote_destination and $destinationvalues to include our skin's sub-directory. The filter we wrote merely mimics the exact path modification being done to$remote_destinationand$destinationon lines 211-212 of/wp-admin/class-wp-upgrader.php` for plugins and themes.

    <strong>Suggested Solution:</strong>
    Instead of forcing plugin developers to fork the install_package() method by overloading it in a sub-class, add an apply_filters() command for $remote_destination and $destination for easy hooking in to modify those values.

    Posted: 6 years ago #

RSS feed for this topic


You must log in to post.

  • Rating

    2 Votes
  • Status

    This idea is under consideration