/**
  * Initialise a module.
  *
  * @param int 'id' module id
  * @return bool true
  */
 public function initialiseAction()
 {
     $csrftoken = $this->request->get('csrftoken');
     $this->checkCsrfToken($csrftoken);
     // Get parameters from whatever input we need
     $id = (int) $this->request->get('id', 0);
     $objectid = (int) $this->request->get('objectid', 0);
     $confirmation = (bool) $this->request->get('confirmation', false);
     $startnum = (int) $this->request->get('startnum');
     $letter = $this->request->get('letter');
     $state = (int) $this->request->get('state');
     if ($objectid) {
         $id = $objectid;
     }
     // assign any dependencies - filtering out non-active module dependents
     // when getting here without a valid id we are in interactive init mode and then
     // the dependencies checks have been done before already
     $fataldependency = false;
     if ($id != 0) {
         $dependencies = ModUtil::apiFunc('ExtensionsModule', 'admin', 'getdependencies', array('modid' => $id));
         $modulenotfound = false;
         if (!$confirmation && $dependencies) {
             foreach ($dependencies as $key => $dependency) {
                 $dependencies[$key] = $dependency->toArray();
                 $dependencies[$key]['insystem'] = true;
                 $modinfo = ModUtil::getInfoFromName($dependency['modname']);
                 $base = $modinfo['type'] == ModUtil::TYPE_MODULE ? 'modules' : 'system';
                 if (is_dir("{$base}/{$dependency['modname']}")) {
                     $minok = 0;
                     $maxok = 0;
                     $modversion = ExtensionsUtil::getVersionMeta($dependency['modname'], $base);
                     if (!empty($dependency['minversion'])) {
                         $minok = version_compare($modversion['version'], $dependency['minversion']);
                     }
                     if (!empty($dependency['maxversion'])) {
                         $maxok = version_compare($dependency['maxversion'], $modversion['version']);
                     }
                     if ($minok == -1 || $maxok == -1) {
                         if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
                             $fataldependency = true;
                         } else {
                             unset($dependencies[$key]);
                         }
                     } else {
                         $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
                         // if this module is already installed, don't display it in the list of dependencies.
                         if (isset($dependencies[$key]['state']) && ($dependencies[$key]['state'] > ModUtil::STATE_UNINITIALISED && $dependencies[$key]['state'] < ModUtil::STATE_NOTALLOWED)) {
                             unset($dependencies[$key]);
                         }
                     }
                 } elseif (!empty($modinfo)) {
                     $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
                 } else {
                     $dependencies[$key]['insystem'] = false;
                     $modulenotfound = true;
                     if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
                         $fataldependency = true;
                     }
                 }
             }
             $this->view->assign('fataldependency', $fataldependency);
             // we have some dependencies so let's warn the user about these
             if (!empty($dependencies)) {
                 return $this->response($this->view->assign('id', $id)->assign('dependencies', $dependencies)->assign('modulenotfound', $modulenotfound)->fetch('extensions_admin_initialise.tpl'));
             }
         } else {
             $dependencies = (array) $this->request->request->get('dependencies', array());
         }
     }
     $session = $this->request->getSession();
     $interactive_init = $session->get('interactive_init');
     $interactive_init = empty($interactive_init) ? false : true;
     if ($interactive_init == false) {
         $session->set('modules_id', $id);
         $session->set('modules_startnum', $startnum);
         $session->set('modules_letter', $letter);
         $session->set('modules_state', $state);
         $activate = false;
     } else {
         $id = $session->get('modules_id');
         $startnum = $session->get('modules_startnum');
         $letter = $session->get('modules_letter');
         $state = $session->get('modules_state');
         $activate = (bool) $this->request->get('activate');
     }
     if (empty($id) || !is_numeric($id)) {
         return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
     }
     // initialise and activate any dependencies
     if (isset($dependencies) && is_array($dependencies)) {
         foreach ($dependencies as $dependency) {
             if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'initialise', array('id' => $dependency))) {
                 return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array('startnum' => $startnum, 'letter' => $letter, 'state' => $state)));
             }
             if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate', array('id' => $dependency, 'state' => ModUtil::STATE_ACTIVE))) {
                 return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array('startnum' => $startnum, 'letter' => $letter, 'state' => $state)));
             }
         }
     }
     // Now we've initialised the dependencies initialise the main module
     $res = ModUtil::apiFunc('ExtensionsModule', 'admin', 'initialise', array('id' => $id, 'interactive_init' => $interactive_init));
     if (is_bool($res) && $res == true) {
         // Success
         $session->remove('modules_id');
         $session->remove('modules_startnum');
         $session->remove('modules_letter');
         $session->remove('modules_state');
         $session->remove('interactive_init');
         LogUtil::registerStatus($this->__('Done! Installed module.'));
         if ($activate == true) {
             if (ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate', array('id' => $id, 'state' => ModUtil::STATE_ACTIVE))) {
                 // Success
                 LogUtil::registerStatus($this->__('Done! Activated module.'));
             }
         }
         return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array('startnum' => $startnum, 'letter' => $letter, 'state' => $state)));
     } elseif (is_bool($res)) {
         return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array('startnum' => $startnum, 'letter' => $letter, 'state' => $state)));
     } else {
         return $res;
     }
 }
Exemple #2
0
 /**
  * Upgrade a module.
  *
  * @param array $args All parameters passed to this function.
  *                      numeric $args['id']                  The module ID.
  *                      boolean $args['interactive_upgrade'] Whether or not to upgrade in interactive mode.
  *
  * @return boolean True on success, false on failure.
  */
 public function upgrade($args)
 {
     // Argument check
     if (!isset($args['id']) || !is_numeric($args['id'])) {
         throw new \InvalidArgumentException('Missing or invalid arguments');
     }
     $entity = 'Zikula\\Core\\Doctrine\\Entity\\Extension';
     // Get module information
     $modinfo = ModUtil::getInfo($args['id']);
     if (empty($modinfo)) {
         return LogUtil::registerError($this->__('Error! No such module ID exists.'));
     }
     switch ($modinfo['state']) {
         case ModUtil::STATE_NOTALLOWED:
             return LogUtil::registerError($this->__f('Error! No permission to upgrade %s.', $modinfo['name']));
             break;
         default:
             if ($modinfo['state'] > 10) {
                 return LogUtil::registerError($this->__f('Error! %s is not compatible with this version of Zikula.', $modinfo['name']));
             }
     }
     $osdir = DataUtil::formatForOS($modinfo['directory']);
     ModUtil::dbInfoLoad($modinfo['name'], $osdir);
     $modpath = $modinfo['type'] == ModUtil::TYPE_SYSTEM ? 'system' : 'modules';
     // load module maintainence functions
     ZLoader::addModule($osdir, $modpath);
     $bootstrap = "{$modpath}/{$osdir}/bootstrap.php";
     if (file_exists($bootstrap)) {
         include_once $bootstrap;
     }
     if ($modinfo['type'] == ModUtil::TYPE_MODULE) {
         if (is_dir("modules/{$osdir}/Resources/locale")) {
             ZLanguage::bindModuleDomain($modinfo['name']);
         }
     }
     $className = ucwords($modinfo['name']) . '\\Installer';
     $reflectionInstaller = new \ReflectionClass($className);
     if (!$reflectionInstaller->isSubclassOf('Zikula\\Framework\\AbstractInstaller')) {
         LogUtil::registerError($this->__f("%s must be an instance of Zikula\\Framework\\AbstractInstaller", $className));
     }
     $installer = $reflectionInstaller->newInstanceArgs(array($this->container));
     $interactiveClass = ucwords($modinfo['name']) . '\\Controller\\Interactiveinstaller';
     $interactiveController = null;
     if (class_exists($interactiveClass)) {
         $reflectionInteractive = new \ReflectionClass($interactiveClass);
         if (!$reflectionInteractive->isSubclassOf('Zikula\\Framework\\Controller\\AbstractInteractiveInstaller')) {
             LogUtil::registerError($this->__f("%s must be an instance of\n                Zikula\\Framework\\Controller\\AbstractInteractiveInstaller", $className));
         }
         $interactiveController = $reflectionInteractive->newInstance($this->container);
     }
     // perform the actual upgrade of the module
     $func = array($installer, 'upgrade');
     $interactive_func = array($interactiveController, 'upgrade');
     // allow bypass of interactive upgrade during a new installation only.
     if (System::isInstalling() && is_callable($interactive_func) && !is_callable($func)) {
         return;
         // return void here
     }
     if (isset($args['interactive_upgrade']) && $args['interactive_upgrade'] == false && is_callable($interactive_func)) {
         // Because interactive installers extend the Zikula_AbstractController, is_callable will always return true because of the __call()
         // so we must check if the method actually exists by reflection - drak
         if ($reflectionInteractive->hasMethod('upgrade')) {
             $this->request->getSession()->set('interactive_upgrade', true);
             return call_user_func($interactive_func, array('oldversion' => $modinfo['version']));
         }
     }
     // non-interactive
     if (is_callable($func)) {
         $result = call_user_func($func, $modinfo['version']);
         if (is_string($result)) {
             if ($result != $modinfo['version']) {
                 // update the last successful updated version
                 $item = $this->entityManager->getRepository($entity)->find($modinfo['id']);
                 $item['version'] = $result;
                 $this->entityManager->flush();
             }
             return false;
         } elseif ($result != true) {
             return false;
         }
     }
     $modversion['version'] = '0';
     $modversion = Util::getVersionMeta($osdir, $modpath);
     $version = $modversion['version'];
     // Update state of module
     $result = $this->setState(array('id' => $args['id'], 'state' => ModUtil::STATE_ACTIVE));
     if ($result) {
         LogUtil::registerStatus($this->__("Done! Module has been upgraded. Its status is now 'Active'."));
     } else {
         return false;
     }
     // update the module with the new version
     $item = $this->entityManager->getRepository($entity)->find($args['id']);
     $item['version'] = $version;
     $this->entityManager->flush();
     // Upgrade succeeded, issue event.
     $event = new GenericEvent(null, $modinfo);
     $this->dispatcher->dispatch('installer.module.upgraded', $event);
     // Success
     return true;
 }