4 * @file PluginManagementHandler.inc.php
6 * Copyright (c) 2003-2009 John Willinsky
7 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
9 * @class PluginManagementHandler
10 * @ingroup pages_manager
12 * @brief Handle requests for installing/upgrading/deleting plugins.
15 // $Id: PluginManagementHandler.inc.php,v 1.3 2009/07/22 23:09:51 mcrider Exp $
17 define('VERSION_FILE', '/version.xml');
18 define('INSTALL_FILE', '/install.xml');
19 define('UPGRADE_FILE', '/upgrade.xml');
21 import('site.Version');
22 import('site.VersionCheck');
23 import('file.FileManager');
24 import('install.Install');
25 import('pages.manager.ManagerHandler');
27 class PluginManagementHandler
extends ManagerHandler
{
31 function PluginManagementHandler() {
32 parent
::ManagerHandler();
36 * Display a list of plugins along with management options.
38 function managePlugins($args) {
39 $path = isset($args[0])?
$args[0]:null;
40 $plugin = isset($args[1])?
$args[1]:null;
44 $this->showInstallForm();
47 $this->uploadPlugin('install');
50 $this->showUpgradeForm($plugin);
53 $this->uploadPlugin('upgrade');
56 $this->showDeleteForm($plugin);
59 $this->deletePlugin($plugin);
62 Request
::redirect(null, 'manager', 'plugins');
65 $this->setupTemplate(true);
69 * Show plugin installation form.
71 function showInstallForm() {
72 $templateMgr =& TemplateManager
::getManager();
73 $this->setupTemplate(true);
75 $templateMgr->assign('path', 'install');
76 $templateMgr->assign('uploaded', false);
77 $templateMgr->assign('error', false);
79 $category = $this->getPluginCategory($plugin);
80 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true, $category));
82 $templateMgr->display('manager/plugins/managePlugins.tpl');
86 * Show form to select plugin for upgrade.
87 * @param plugin string
89 function showUpgradeForm($plugin) {
90 $templateMgr =& TemplateManager
::getManager();
91 $this->setupTemplate(true);
93 $templateMgr->assign('path', 'upgrade');
94 $templateMgr->assign('plugin', $plugin);
95 $templateMgr->assign('uploaded', false);
97 $category = $this->getPluginCategory($plugin);
98 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true, $category));
100 $templateMgr->display('manager/plugins/managePlugins.tpl');
104 * Confirm deletion of plugin.
105 * @param plugin string
107 function showDeleteForm($plugin) {
108 $templateMgr =& TemplateManager
::getManager();
109 $this->setupTemplate(true);
111 $templateMgr->assign('path', 'delete');
112 $templateMgr->assign('plugin', $plugin);
113 $templateMgr->assign('deleted', false);
114 $templateMgr->assign('error', false);
116 $category = $this->getPluginCategory($plugin);
117 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true, $category));
119 $templateMgr->display('manager/plugins/managePlugins.tpl');
124 * Decompress uploaded plugin and install in the correct plugin directory.
125 * $param function string type of operation to perform after upload ('upgrade' or 'install')
127 function uploadPlugin($function) {
128 $templateMgr =& TemplateManager
::getManager();
129 $this->setupTemplate(true);
131 $templateMgr->assign('error', false);
132 $templateMgr->assign('uploaded', false);
133 $templateMgr->assign('path', $function);
134 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true));
136 if (Request
::getUserVar('uploadPlugin')) {
137 import('file.TemporaryFileManager');
138 $temporaryFileManager = new TemporaryFileManager();
139 $user =& Request
::getUser();
141 if ($temporaryFile = $temporaryFileManager->handleUpload('newPlugin', $user->getId())) {
142 // tar archive basename must equal plugin directory name, and plugin files must be in root directory
143 $pluginName = basename($temporaryFile->getOriginalFileName(), '.tar.gz');
144 $pluginDir = dirname($temporaryFile->getFilePath());
145 exec('tar -xzf ' . escapeshellarg($temporaryFile->getFilePath()) . ' -C ' . escapeshellarg($pluginDir));
147 if ($function == 'install') {
148 $this->installPlugin($pluginDir . DIRECTORY_SEPARATOR
. $pluginName, $templateMgr);
149 } else if ($function == 'upgrade') {
150 $this->upgradePlugin($pluginDir . DIRECTORY_SEPARATOR
. $pluginName, $templateMgr);
153 $templateMgr->assign('error', true);
154 $templateMgr->assign('message', 'manager.plugins.uploadError');
156 } else if (Request
::getUserVar('installPlugin')) {
157 if(Request
::getUserVar('pluginUploadLocation') == '') {
158 $templateMgr->assign('error', true);
159 $templateMgr->assign('message', 'manager.plugins.fileSelectError');
163 $templateMgr->display('manager/plugins/managePlugins.tpl');
167 * Installs the uploaded plugin
168 * @param $path string path to plugin Directory
169 * @param $templateMgr reference to template manager
172 function installPlugin($path, &$templateMgr) {
173 $versionFile = $path . VERSION_FILE
;
174 $templateMgr->assign('error', true);
175 $templateMgr->assign('path', 'install');
177 if (FileManager
::fileExists($versionFile)) {
178 $versionInfo =& VersionCheck
::parseVersionXML($versionFile);
180 $templateMgr->assign('message', 'manager.plugins.versionFileNotFound');
184 $pluginVersion = $versionInfo['version'];
185 $pluginName = $pluginVersion->getProduct();
186 $category = $this->getPluginCategory($plugin);
188 $versionDao =& DAORegistry
::getDAO('VersionDAO');
189 $installedPlugin = $versionDao->getCurrentVersion($pluginName);
191 if(!$installedPlugin) {
192 $pluginDest = Core
::getBaseDir() . DIRECTORY_SEPARATOR
. 'plugins' . DIRECTORY_SEPARATOR
. $category . DIRECTORY_SEPARATOR
. $pluginName;
194 if(!FileManager
::copyDir($path, $pluginDest)) {
195 $templateMgr->assign('message', 'manager.plugins.copyError');
199 // If plugin has an install.xml file, update database with it
200 $installFile = $pluginDest . DIRECTORY_SEPARATOR
. INSTALL_FILE
;
201 if(FileManager
::fileExists($installFile)) {
202 $params = $this->setConnectionParams();
203 $installer = new Install($params, $installFile, true);
205 if ($installer->execute()) {
206 $newVersion =& $installer->getNewVersion();
208 // Roll back the copy
209 FileManager
::rmtree($pluginDest);
210 $templateMgr->assign('message', array('manager.plugins.installFailed', $installer->getErrorString()));
214 $newVersion = $pluginVersion;
217 $message = array('manager.plugins.installSuccessful', $newVersion->getVersionString());
218 $templateMgr->assign('message', $message);
219 $templateMgr->assign('uploaded', true);
220 $templateMgr->assign('error', false);
222 $newVersion->setCurrent(1);
223 $versionDao->insertVersion($newVersion);
226 if ($this->checkIfNewer($pluginName, $pluginVersion)) {
227 $templateMgr->assign('message', 'manager.plugins.pleaseUpgrade');
230 if (!$this->checkIfNewer($pluginName, $pluginVersion)) {
231 $templateMgr->assign('message', 'manager.plugins.installedVersionOlder');
238 * Upgrade a plugin to a newer version from the user's filesystem
239 * @param $path string path to plugin Directory
240 * @param $templateMgr reference to template manager
243 function upgradePlugin($path, &$templateMgr) {
244 $versionFile = $path . VERSION_FILE
;
245 $templateMgr->assign('error', true);
246 $templateMgr->assign('path', 'upgrade');
248 if (FileManager
::fileExists($versionFile)) {
249 $versionInfo =& VersionCheck
::parseVersionXML($versionFile);
251 $templateMgr->assign('message', 'manager.plugins.versionFileNotFound');
255 $pluginVersion = $versionInfo['version'];
256 $pluginName = $versionInfo['application'];
257 $pluginType = explode(".", $pluginVersion->getProductType());
259 $versionDao =& DAORegistry
::getDAO('VersionDAO');
260 $installedPlugin = $versionDao->getCurrentVersion($pluginName);
261 if(!$installedPlugin) {
262 $templateMgr->assign('message', 'manager.plugins.pleaseInstall');
266 if ($this->checkIfNewer($pluginName, $pluginVersion)) {
267 $templateMgr->assign('message', 'manager.plugins.installedVersionNewer');
270 $pluginDest = Core
::getBaseDir() . DIRECTORY_SEPARATOR
. 'plugins' . DIRECTORY_SEPARATOR
. $pluginType[1] . DIRECTORY_SEPARATOR
. $pluginName;
272 FileManager
::rmtree($pluginDest);
273 if(FileManager
::fileExists($pluginDest, 'dir')) {
274 $templateMgr->assign('message', 'manager.plugins.deleteError');
277 if(!FileManager
::copyDir($path, $pluginDest)) {
278 $templateMgr->assign('message', 'manager.plugins.copyError');
282 $upgradeFile = $pluginDest . DIRECTORY_SEPARATOR
. UPGRADE_FILE
;
283 if(FileManager
::fileExists($upgradeFile)) {
284 $params = $this->setConnectionParams();
285 $installer = new Upgrade($params, $upgradeFile, true);
287 if (!$installer->execute()) {
288 $templateMgr->assign('message', array('manager.plugins.upgradeFailed', $installer->getErrorString()));
293 $installedPlugin->setCurrent(0);
294 $pluginVersion->setCurrent(1);
295 $versionDao->insertVersion($pluginVersion);
297 $templateMgr->assign('message', array('manager.plugins.upgradeSuccessful', $pluginVersion->getVersionString()));
298 $templateMgr->assign('uploaded', true);
299 $templateMgr->assign('error', false);
306 * Delete a plugin from the system
307 * @param plugin string
309 function deletePlugin($plugin) {
310 $templateMgr =& TemplateManager
::getManager();
311 $this->setupTemplate(true);
313 $templateMgr->assign('path', 'delete');
314 $templateMgr->assign('deleted', false);
315 $templateMgr->assign('error', false);
316 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true));
318 $versionDao =& DAORegistry
::getDAO('VersionDAO');
319 $installedPlugin = $versionDao->getCurrentVersion($plugin);
320 $category = $this->getPluginCategory($plugin);
322 if ($installedPlugin) {
323 $pluginDest = Core
::getBaseDir() . DIRECTORY_SEPARATOR
. 'plugins' . DIRECTORY_SEPARATOR
. $category . DIRECTORY_SEPARATOR
. $plugin;
325 //make sure plugin type is valid and then delete the files
326 if (in_array($category, PluginRegistry
::getCategories())) {
327 FileManager
::rmtree($pluginDest);
330 if(FileManager
::fileExists($pluginDest, 'dir')) {
331 $templateMgr->assign('error', true);
332 $templateMgr->assign('message', 'manager.plugins.deleteError');
334 $versionDao->disableVersion($plugin);
335 $templateMgr->assign('deleted', true);
339 $templateMgr->assign('error', true);
340 $templateMgr->assign('message', 'manager.plugins.doesNotExist');
343 $templateMgr->assign('pageHierarchy', $this->setBreadcrumbs(true, $category));
345 $templateMgr->display('manager/plugins/managePlugins.tpl');
349 * Checks to see if local version of plugin is newer than installed version
350 * @param $pluginName string Product name of plugin
351 * @param $newVersion Version Version object of plugin to check against database
354 function checkIfNewer($pluginName, $newVersion) {
355 $versionDao =& DAORegistry
::getDAO('VersionDAO');
356 $installedPlugin = $versionDao->getCurrentVersion($pluginName);
358 if (!$installedPlugin) return false;
359 if ($installedPlugin->compare($newVersion) > 0) return true;
364 * Set the page's breadcrumbs
365 * @param $subclass boolean
366 * @param $category string
368 function setBreadcrumbs($subclass = false, $category = null) {
369 $templateMgr =& TemplateManager
::getManager();
372 Request
::url(null, 'user'),
377 Request
::url(null, 'manager'),
378 'manager.pressManagement',
384 $pageCrumbs[] = array(
385 Request
::url(null, 'manager', 'plugins'),
386 'manager.plugins.pluginManagement',
392 $pageCrumbs[] = array(
393 Request
::url(null, 'manager', 'plugins', $category),
394 "plugins.categories.$category",
403 * Get the plugin category from the version.
407 function getPluginCategory($plugin) {
408 $versionDao =& DAORegistry
::getDAO('VersionDAO');
409 $installedPlugin = $versionDao->getCurrentVersion($plugin);
411 $pluginType = explode(".", $installedPlugin->getProductType());
413 return $pluginType[1];
417 * Load database connection parameters into an array (needed for upgrade).
420 function setConnectionParams() {
422 'clientCharset' => Config
::getVar('i18n', 'client_charset'),
423 'connectionCharset' => Config
::getVar('i18n', 'connection_charset'),
424 'databaseCharset' => Config
::getVar('i18n', 'database_charset'),
425 'databaseDriver' => Config
::getVar('database', 'driver'),
426 'databaseHost' => Config
::getVar('database', 'host'),
427 'databaseUsername' => Config
::getVar('database', 'username'),
428 'databasePassword' => Config
::getVar('database', 'password'),
429 'databaseName' => Config
::getVar('database', 'name')