• Main Page
  • Modules
  • Classes
  • Files
  • File List

controllers/grid/plugins/form/UploadPluginForm.inc.php

00001 <?php
00002 
00016 define('VERSION_FILE', '/version.xml');
00017 define('INSTALL_FILE', '/install.xml');
00018 define('UPGRADE_FILE', '/upgrade.xml');
00019 
00020 // Import the base Form.
00021 import('lib.pkp.classes.form.Form');
00022 
00023 import('lib.pkp.classes.site.Version');
00024 import('lib.pkp.classes.site.VersionCheck');
00025 import('lib.pkp.classes.file.FileManager');
00026 import('classes.install.Install');
00027 import('classes.install.Upgrade');
00028 
00029 class UploadPluginForm extends Form {
00030 
00032    var $_function;
00033 
00034 
00038    function UploadPluginForm($function) {
00039       parent::Form('controllers/grid/plugins/form/uploadPluginForm.tpl');
00040 
00041       $this->_function = $function;
00042 
00043       $this->addCheck(new FormValidator($this, 'temporaryFileId', 'required', 'Please select a file first'));
00044    }
00045 
00046    //
00047    // Implement template methods from Form.
00048    //
00052    function readInputData() {
00053       $this->readUserVars(array('temporaryFileId'));
00054    }
00055 
00059    function fetch(&$request) {
00060       $templateMgr =& TemplateManager::getManager();
00061       $templateMgr->assign('function', $this->_function);
00062 
00063       return parent::fetch($request);
00064    }
00065 
00069    function execute(&$request) {
00070       parent::execute($request);
00071 
00072       // Retrieve the temporary file.
00073       $user =& $request->getUser();
00074       $temporaryFileId = $this->getData('temporaryFileId');
00075       $temporaryFileDao =& DAORegistry::getDAO('TemporaryFileDAO');
00076       $temporaryFile =& $temporaryFileDao->getTemporaryFile($temporaryFileId, $user->getId());
00077 
00078       // tar archive basename (less potential version number) must equal plugin directory name
00079       // and plugin files must be in a directory named after the plug-in.
00080       $matches = array();
00081       String::regexp_match_get('/^[a-zA-Z0-9]+/', basename($temporaryFile->getOriginalFileName(), '.tar.gz'), $matches);
00082       $pluginName = array_pop($matches);
00083 
00084       // Create random dirname to avoid symlink attacks.
00085       $pluginDir = dirname($temporaryFile->getFilePath()) . DIRECTORY_SEPARATOR . $pluginName . substr(md5(mt_rand()), 0, 10);
00086       mkdir($pluginDir);
00087 
00088       $errorMsg = null;
00089 
00090       // Test whether the tar binary is available for the export to work
00091       $tarBinary = Config::getVar('cli', 'tar');
00092       if (!empty($tarBinary) && file_exists($tarBinary)) {
00093          exec($tarBinary.' -xzf ' . escapeshellarg($temporaryFile->getFilePath()) . ' -C ' . escapeshellarg($pluginDir));
00094       } else {
00095          $errorMsg = __('manager.plugins.tarCommandNotFound');
00096       }
00097 
00098       if (empty($errorMsg)) {
00099          // We should now find a directory named after the
00100          // plug-in within the extracted archive.
00101          $pluginDir .= DIRECTORY_SEPARATOR . $pluginName;
00102          if (is_dir($pluginDir)) {
00103             $result = null;
00104             if ($this->_function == 'install') {
00105                $result = $this->_installPlugin($request, $pluginDir);
00106             } else if ($this->_function == 'upgrade') {
00107                $result = $this->_upgradePlugin($request, $pluginDir);
00108             }
00109 
00110             if(!is_null($result) && $result !== true) {
00111                $errorMsg = $result;
00112             }
00113          } else {
00114             $errorMsg = __('manager.plugins.invalidPluginArchive');
00115          }
00116       }
00117 
00118       if(!is_null($errorMsg) ) {
00119          $notificationMgr = new NotificationManager();
00120          $notificationMgr->createTrivialNotification($user->getId(), NOTIFICATION_TYPE_ERROR, array('contents' => $errorMsg));
00121          return false;
00122       }
00123 
00124       return true;
00125    }
00126 
00127 
00128    //
00129    // Private helper methods.
00130    //
00137    function _installPlugin($request, $path) {
00138       $versionFile = $path . VERSION_FILE;
00139 
00140       $checkResult =& VersionCheck::getValidPluginVersionInfo($versionFile, true);
00141       if (is_string($checkResult)) return __($checkResult);
00142       if (is_a($checkResult, 'Version')) {
00143          $pluginVersion = $checkResult;
00144       } else {
00145          assert(false);
00146       }
00147 
00148       $versionDao =& DAORegistry::getDAO('VersionDAO'); /* @var $versionDao VersionDAO */
00149       $installedPlugin = $versionDao->getCurrentVersion($pluginVersion->getProductType(), $pluginVersion->getProduct(), true);
00150 
00151       if(!$installedPlugin) {
00152          $pluginLibDest = Core::getBaseDir() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'pkp' . DIRECTORY_SEPARATOR . strtr($pluginVersion->getProductType(), '.', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $pluginVersion->getProduct();
00153          $pluginDest = Core::getBaseDir() . DIRECTORY_SEPARATOR . strtr($pluginVersion->getProductType(), '.', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $pluginVersion->getProduct();
00154 
00155          // Copy the plug-in from the temporary folder to the
00156          // target folder.
00157          // Start with the library part (if any).
00158          $libPath = $path . DIRECTORY_SEPARATOR . 'lib';
00159          $fileManager = new FileManager();
00160          if (is_dir($libPath)) {
00161             if(!$fileManager->copyDir($libPath, $pluginLibDest)) {
00162                return __('manager.plugins.copyError');
00163             }
00164             // Remove the library part of the temporary folder.
00165             $fileManager->rmtree($libPath);
00166          }
00167 
00168          // Continue with the application-specific part (mandatory).
00169          if(!$fileManager->copyDir($path, $pluginDest)) {
00170             return __('manager.plugins.copyError');
00171          }
00172 
00173          // Remove the temporary folder.
00174          $fileManager->rmtree(dirname($path));
00175 
00176          // Upgrade the database with the new plug-in.
00177          $installFile = $pluginDest . INSTALL_FILE;
00178          if(!is_file($installFile)) $installFile = Core::getBaseDir() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'pkp' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'defaultPluginInstall.xml';
00179          assert(is_file($installFile));
00180          $params = $this->_setConnectionParams();
00181          $installer = new Install($params, $installFile, true);
00182          $installer->setCurrentVersion($pluginVersion);
00183          if (!$installer->execute()) {
00184             // Roll back the copy
00185             if (is_dir($pluginLibDest)) $fileManager->rmtree($pluginLibDest);
00186             if (is_dir($pluginDest)) $fileManager->rmtree($pluginDest);
00187             return __('manager.plugins.installFailed', array('errorString' => $installer->getErrorString()));
00188          }
00189 
00190          $notificationMgr = new NotificationManager();
00191          $user =& $request->getUser();
00192          $notificationMgr->createTrivialNotification(
00193             $user->getId(),
00194             NOTIFICATION_TYPE_SUCCESS,
00195             array('contents' =>
00196                __('manager.plugins.installSuccessful', array('versionNumber' => $pluginVersion->getVersionString(false)))));
00197 
00198          $versionDao->insertVersion($pluginVersion, true);
00199          return true;
00200       } else {
00201          if ($this->_checkIfNewer($pluginVersion->getProductType(), $pluginVersion->getProduct(), $pluginVersion)) {
00202             return __('manager.plugins.pleaseUpgrade');
00203          } else {
00204             return __('manager.plugins.installedVersionOlder');
00205          }
00206       }
00207    }
00208 
00216    function _checkIfNewer($productType, $productName, $newVersion) {
00217       $versionDao =& DAORegistry::getDAO('VersionDAO');
00218       $installedPlugin = $versionDao->getCurrentVersion($productType, $productName, true);
00219 
00220       if (!$installedPlugin) return false;
00221       if ($installedPlugin->compare($newVersion) > 0) return true;
00222       else return false;
00223    }
00224 
00229    function _setConnectionParams() {
00230       return array(
00231             'clientCharset' => Config::getVar('i18n', 'client_charset'),
00232             'connectionCharset' => Config::getVar('i18n', 'connection_charset'),
00233             'databaseCharset' => Config::getVar('i18n', 'database_charset'),
00234             'databaseDriver' => Config::getVar('database', 'driver'),
00235             'databaseHost' => Config::getVar('database', 'host'),
00236             'databaseUsername' => Config::getVar('database', 'username'),
00237             'databasePassword' => Config::getVar('database', 'password'),
00238             'databaseName' => Config::getVar('database', 'name')
00239       );
00240    }
00241 
00251    function _upgradePlugin($request, $path, &$templateMgr) {
00252       $category = $request->getUserVar('category');
00253       $plugin = $request->getUserVar('plugin');
00254 
00255       $versionFile = $path . VERSION_FILE;
00256       $templateMgr->assign('error', true);
00257 
00258       $pluginVersion =& VersionCheck::getValidPluginVersionInfo($versionFile, $templateMgr);
00259       if (is_null($pluginVersion)) return false;
00260       assert(is_a($pluginVersion, 'Version'));
00261 
00262       // Check whether the uploaded plug-in fits the original plug-in.
00263       if ('plugins.'.$category != $pluginVersion->getProductType()) {
00264          return __('manager.plugins.wrongCategory');
00265       }
00266 
00267       if ($plugin != $pluginVersion->getProduct()) {
00268          return __('manager.plugins.wrongName');
00269       }
00270 
00271       $versionDao =& DAORegistry::getDAO('VersionDAO');
00272       $installedPlugin = $versionDao->getCurrentVersion($pluginVersion->getProductType(), $pluginVersion->getProduct(), true);
00273       if(!$installedPlugin) {
00274          return __('manager.plugins.pleaseInstall');
00275       }
00276 
00277       if ($this->_checkIfNewer($pluginVersion->getProductType(), $pluginVersion->getProduct(), $pluginVersion)) {
00278          return __('manager.plugins.installedVersionNewer');
00279       } else {
00280          $pluginDest = Core::getBaseDir() . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $category . DIRECTORY_SEPARATOR . $plugin;
00281          $pluginLibDest = Core::getBaseDir() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'pkp' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $category . DIRECTORY_SEPARATOR . $plugin;
00282 
00283          // Delete existing files.
00284          $fileManager = new FileManager();
00285          if (is_dir($pluginDest)) $fileManager->rmtree($pluginDest);
00286          if (is_dir($pluginLibDest)) $fileManager->rmtree($pluginLibDest);
00287 
00288          // Check whether deleting has worked.
00289          if(is_dir($pluginDest) || is_dir($pluginLibDest)) {
00290             return __('message', 'manager.plugins.deleteError');
00291          }
00292 
00293          // Copy the plug-in from the temporary folder to the
00294          // target folder.
00295          // Start with the library part (if any).
00296          $libPath = $path . DIRECTORY_SEPARATOR . 'lib';
00297          if (is_dir($libPath)) {
00298             if(!$fileManager->copyDir($libPath, $pluginLibDest)) {
00299                return __('manager.plugins.copyError');
00300             }
00301             // Remove the library part of the temporary folder.
00302             $fileManager->rmtree($libPath);
00303          }
00304 
00305          // Continue with the application-specific part (mandatory).
00306          if(!$fileManager->copyDir($path, $pluginDest)) {
00307             return __('manager.plugins.copyError');
00308          }
00309 
00310          // Remove the temporary folder.
00311          $fileManager->rmtree(dirname($path));
00312 
00313          $upgradeFile = $pluginDest . UPGRADE_FILE;
00314          if($fileManager->fileExists($upgradeFile)) {
00315             $params = $this->_setConnectionParams();
00316             $installer = new Upgrade($params, $upgradeFile, true);
00317 
00318             if (!$installer->execute()) {
00319                return __('manager.plugins.upgradeFailed', array('errorString' => $installer->getErrorString()));
00320             }
00321          }
00322 
00323          $installedPlugin->setCurrent(0);
00324          $pluginVersion->setCurrent(1);
00325          $versionDao->insertVersion($pluginVersion, true);
00326 
00327          $notificationMgr = new NotificationManager();
00328          $notificationMgr->createTrivialNotification(
00329             $user->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => __('manager.plugins.upgradeSuccessful', array('versionString' => $pluginVersion->getVersionString(false)))));
00330 
00331          return true;
00332       }
00333    }
00334 }
00335 
00336 ?>

Generated on Mon Sep 17 2012 13:58:56 for Open Monograph Press by  doxygen 1.7.1