diff --git a/plugin-update-checker.php b/plugin-update-checker.php index 979dc84..9ad8f4f 100644 --- a/plugin-update-checker.php +++ b/plugin-update-checker.php @@ -1,6 +1,6 @@ skin, $wp_filesystem) ) { + return $source; + } + + //Figure out which plugin is being upgraded. + $pluginFile = null; + $skin = $upgrader->skin; + if ( $skin instanceof Plugin_Upgrader_Skin ) { + if ( isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '') ) { + $pluginFile = $skin->plugin; + } + } elseif ( $upgrader->skin instanceof Bulk_Plugin_Upgrader_Skin ) { + //This case is tricky because Bulk_Plugin_Upgrader_Skin doesn't actually store the plugin + //filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can + //do is compare those headers to the headers of installed plugins. + if ( isset($skin->plugin_info) && is_array($skin->plugin_info) ) { + if ( !function_exists('get_plugins') ){ + require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); + } + + $installedPlugins = get_plugins(); + $matches = array(); + foreach($installedPlugins as $pluginBasename => $headers) { + $diff1 = array_diff_assoc($headers, $skin->plugin_info); + $diff2 = array_diff_assoc($skin->plugin_info, $headers); + if ( empty($diff1) && empty($diff2) ) { + $matches[] = $pluginBasename; + } + } + + //It's possible (though very unlikely) that there could be two plugins with identical + //headers. In that case, we can't unambiguously identify the plugin that's being upgraded. + if ( count($matches) !== 1 ) { + return $source; + } + + $pluginFile = reset($matches); + } + } + + //If WordPress is upgrading anything other than our plugin, leave the directory name unchanged. + if ( empty($pluginFile) || ($pluginFile !== $this->pluginFile) ) { + return $source; + } + + //Rename the source to match the existing plugin directory. + $pluginDirectoryName = dirname($this->pluginFile); + if ( ($pluginDirectoryName === '.') || ($pluginDirectoryName === '/') ) { + return $source; + } + $correctedSource = trailingslashit($remoteSource) . $pluginDirectoryName . '/'; + if ( $source !== $correctedSource ) { + $upgrader->skin->feedback(sprintf( + 'Renaming %s to %s…', + '' . basename($source) . '', + '' . $pluginDirectoryName . '' + )); + + if ( $wp_filesystem->move($source, $correctedSource, true) ) { + $upgrader->skin->feedback('Plugin directory successfully renamed.'); + return $correctedSource; + } else { + return new WP_Error( + 'puc-rename-failed', + 'Unable to rename the update to match the existing plugin directory.' + ); + } + } + + return $source; + } + + /** * Get the details of the currently available update, if any. *