Esempio n. 1
0
 /**
  * Regenerate modules list.
  *
  * @param array[] $args {
  *      @type array $filemodules An array of modules in the filesystem, as would be returned by
  *                                  {@link getfilemodules()}; optional, defaults to the results of $this->getfilemodules()
  *                       }
  *
  * @return boolean True on success, false on failure
  *
  * @throws \InvalidArgumentException Thrown if the filemodules parameter is either not set or not an array
  * @throws AccessDeniedException Thrown if the user doesn't have admin permissions over the module
  * @throws \RuntimeException Thrown if module information cannot be obtained from the database
  */
 public function regenerate($args)
 {
     // Security check
     if (!System::isInstalling()) {
         if (!SecurityUtil::checkPermission('ZikulaExtensionsModule::', '::', ACCESS_ADMIN)) {
             throw new AccessDeniedException();
         }
     }
     $boot = new \Zikula\Bundle\CoreBundle\Bundle\Bootstrap();
     $helper = new \Zikula\Bundle\CoreBundle\Bundle\Helper\BootstrapHelper($boot->getConnection($this->getContainer()->get('kernel')));
     // sync the filesystem and the bundles table
     $helper->load();
     // Argument check
     if (!isset($args['filemodules']) || !is_array($args['filemodules'])) {
         throw new \InvalidArgumentException(__('Invalid arguments array received'));
     }
     // default action
     $filemodules = $args['filemodules'];
     $defaults = isset($args['defaults']) ? $args['defaults'] : false;
     // Get all modules in DB
     $allmodules = $this->entityManager->getRepository(self::EXTENSION_ENTITY)->findAll();
     if (!$allmodules) {
         throw new \RuntimeException($this->__('Error! Could not load data.'));
     }
     // index modules by name
     $dbmodules = array();
     /* @var ExtensionEntity $module */
     foreach ($allmodules as $module) {
         $dbmodules[$module['name']] = $module->toArray();
     }
     // build a list of found modules and dependencies
     $fileModuleNames = array();
     $moddependencies = array();
     foreach ($filemodules as $modinfo) {
         $fileModuleNames[] = $modinfo['name'];
         if (isset($modinfo['dependencies']) && !empty($modinfo['dependencies'])) {
             $moddependencies[$modinfo['name']] = unserialize($modinfo['dependencies']);
         }
     }
     // see if any modules have changed name since last regeneration
     foreach ($filemodules as $name => $modinfo) {
         if (isset($modinfo['oldnames']) && !empty($modinfo['oldnames'])) {
             foreach ($dbmodules as $dbname => $dbmodinfo) {
                 if (isset($dbmodinfo['name']) && in_array($dbmodinfo['name'], (array) $modinfo['oldnames'])) {
                     // migrate its modvars
                     $query = $this->entityManager->createQueryBuilder()->update('Zikula\\Core\\Doctrine\\Entity\\ExtensionVarEntity', 'v')->set('v.modname', ':modname')->setParameter('modname', $modinfo['name'])->where('v.modname = :dbname')->setParameter('dbname', $dbname)->getQuery();
                     $query->execute();
                     // rename the module register
                     $query = $this->entityManager->createQueryBuilder()->update(self::EXTENSION_ENTITY, 'e')->set('e.name', ':modname')->setParameter('modname', $modinfo['name'])->where('e.id = :dbname')->setParameter('dbname', $dbmodules[$dbname]['id'])->getQuery();
                     $query->execute();
                     // replace the old module with the new one in the dbmodules array
                     $newmodule = $dbmodules[$dbname];
                     $newmodule['name'] = $modinfo['name'];
                     unset($dbmodules[$dbname]);
                     $dbname = $modinfo['name'];
                     $dbmodules[$dbname] = $newmodule;
                 }
             }
         }
         // If module was previously determined to be incompatible with the core. return to original state
         if (isset($dbmodules[$name]) && $dbmodules[$name]['state'] > 10) {
             $dbmodules[$name]['state'] = $dbmodules[$name]['state'] - ModUtil::INCOMPATIBLE_CORE_SHIFT;
             $this->setState(array('id' => $dbmodules[$name]['id'], 'state' => $dbmodules[$name]['state']));
         }
         // update the DB information for this module to reflect user settings (e.g. url)
         if (isset($dbmodules[$name]['id'])) {
             $modinfo['id'] = $dbmodules[$name]['id'];
             if ($dbmodules[$name]['state'] != ModUtil::STATE_UNINITIALISED && $dbmodules[$name]['state'] != ModUtil::STATE_INVALID) {
                 unset($modinfo['version']);
             }
             if (!$defaults) {
                 unset($modinfo['displayname']);
                 unset($modinfo['description']);
                 unset($modinfo['url']);
             }
             unset($modinfo['oldnames']);
             unset($modinfo['dependencies']);
             $modinfo['capabilities'] = unserialize($modinfo['capabilities']);
             $modinfo['securityschema'] = unserialize($modinfo['securityschema']);
             $module = $this->entityManager->getRepository(self::EXTENSION_ENTITY)->find($modinfo['id']);
             $module->merge($modinfo);
             $this->entityManager->flush();
         }
         // check core version is compatible with current
         $isCompatible = $this->isCoreCompatible($filemodules[$name]['core_min'], $filemodules[$name]['core_max']);
         if (isset($dbmodules[$name])) {
             if (!$isCompatible) {
                 // module is incompatible with current core
                 $dbmodules[$name]['state'] = $dbmodules[$name]['state'] + ModUtil::INCOMPATIBLE_CORE_SHIFT;
                 $this->setState(array('id' => $dbmodules[$name]['id'], 'state' => $dbmodules[$name]['state']));
             }
             if (isset($dbmodules[$name]['state'])) {
                 $filemodules[$name]['state'] = $dbmodules[$name]['state'];
             }
         }
     }
     // See if we have lost any modules since last regeneration
     foreach ($dbmodules as $name => $modinfo) {
         if (!in_array($name, $fileModuleNames)) {
             $lostModule = $this->entityManager->getRepository(self::EXTENSION_ENTITY)->findOneBy(array('name' => $name));
             if (!$lostModule) {
                 throw new \RuntimeException($this->__f('Error! Could not load data for module %s.', array($name)));
             }
             $lostModuleState = $lostModule->getState();
             if ($lostModuleState == ModUtil::STATE_INVALID || $lostModuleState == ModUtil::STATE_INVALID + ModUtil::INCOMPATIBLE_CORE_SHIFT) {
                 // module was invalid and subsequently removed from file system,
                 // or module was incompatible with core and subsequently removed, delete it
                 $this->entityManager->remove($lostModule);
                 $this->entityManager->flush();
             } elseif ($lostModuleState == ModUtil::STATE_UNINITIALISED || $lostModuleState == ModUtil::STATE_UNINITIALISED + ModUtil::INCOMPATIBLE_CORE_SHIFT) {
                 // module was uninitialised and subsequently removed from file system, delete it
                 $this->entityManager->remove($lostModule);
                 $this->entityManager->flush();
             } else {
                 // Set state of module to 'missing'
                 $this->setState(array('id' => $lostModule->getId(), 'state' => ModUtil::STATE_MISSING));
             }
             unset($dbmodules[$name]);
         }
     }
     // See if we have gained any modules since last generation,
     // or if any current modules have been upgraded
     foreach ($filemodules as $name => $modinfo) {
         if (empty($dbmodules[$name])) {
             // set state to invalid if we can't determine an ID
             $modinfo['state'] = ModUtil::STATE_UNINITIALISED;
             if (!$modinfo['version']) {
                 $modinfo['state'] = ModUtil::STATE_INVALID;
             } else {
                 // shift state if module is incompatible with core version
                 $modinfo['state'] = $this->isCoreCompatible($modinfo['core_min'], $modinfo['core_max']) ? $modinfo['state'] : $modinfo['state'] + ModUtil::INCOMPATIBLE_CORE_SHIFT;
             }
             // unset some vars
             unset($modinfo['oldnames']);
             unset($modinfo['dependencies']);
             // unserialze some vars
             $modinfo['capabilities'] = unserialize($modinfo['capabilities']);
             $modinfo['securityschema'] = unserialize($modinfo['securityschema']);
             // insert new module to db
             if ($this->serviceManager['multisites.enabled'] == 1) {
                 // only the main site can regenerate the modules list
                 if ($this->serviceManager['multisites.mainsiteurl'] == $this->request->query->get('sitedns', null) && $this->serviceManager['multisites.based_on_domains'] == 0 || $this->serviceManager['multisites.mainsiteurl'] == $_SERVER['HTTP_HOST'] && $this->serviceManager['multisites.based_on_domains'] == 1) {
                     $item = new ExtensionEntity();
                     $item->merge($modinfo);
                     $this->entityManager->persist($item);
                 }
             } else {
                 $item = new ExtensionEntity();
                 $item->merge($modinfo);
                 $this->entityManager->persist($item);
             }
             $this->entityManager->flush();
         } else {
             // module is in the db already
             if ($dbmodules[$name]['state'] == ModUtil::STATE_MISSING || $dbmodules[$name]['state'] == ModUtil::STATE_MISSING + ModUtil::INCOMPATIBLE_CORE_SHIFT) {
                 // module was lost, now it is here again
                 $this->setState(array('id' => $dbmodules[$name]['id'], 'state' => ModUtil::STATE_INACTIVE));
             } elseif (($dbmodules[$name]['state'] == ModUtil::STATE_INVALID || $dbmodules[$name]['state'] == ModUtil::STATE_INVALID + ModUtil::INCOMPATIBLE_CORE_SHIFT) && $modinfo['version']) {
                 $isCompatible = $this->isCoreCompatible($modinfo['core_min'], $modinfo['core_max']);
                 if ($isCompatible) {
                     // module was invalid, now it is valid
                     $item = $this->entityManager->getRepository(self::EXTENSION_ENTITY)->find($dbmodules[$name]['id']);
                     $item->setState(ModUtil::STATE_UNINITIALISED);
                     $this->entityManager->flush();
                 }
             }
             if ($dbmodules[$name]['version'] != $modinfo['version']) {
                 if ($dbmodules[$name]['state'] != ModUtil::STATE_UNINITIALISED && $dbmodules[$name]['state'] != ModUtil::STATE_INVALID) {
                     $this->setState(array('id' => $dbmodules[$name]['id'], 'state' => ModUtil::STATE_UPGRADED));
                 }
             }
         }
     }
     // now clear re-load the dependencies table with all current dependencies
     $connection = $this->entityManager->getConnection();
     $platform = $connection->getDatabasePlatform();
     $connection->executeUpdate($platform->getTruncateTableSQL('module_deps', true));
     // loop round dependencies adding the module id - we do this now rather than
     // earlier since we won't have the id's for new modules at that stage
     ModUtil::flushCache();
     foreach ($moddependencies as $modname => $moddependency) {
         $modid = ModUtil::getIdFromName($modname);
         // each module may have multiple dependencies
         foreach ($moddependency as $dependency) {
             $dependency['modid'] = $modid;
             $item = new ExtensionDependencyEntity();
             $item->merge($dependency);
             $this->entityManager->persist($item);
         }
     }
     $this->entityManager->flush();
     return true;
 }
 /**
  * Create the default data for the Extensions module.
  *
  * @return void
  */
 public function defaultdata()
 {
     $version = new ExtensionsModuleVersion(new ZikulaExtensionsModule());
     $meta = $version->toArray();
     $meta['state'] = \ModUtil::STATE_ACTIVE;
     unset($meta['dependencies']);
     unset($meta['oldnames']);
     $item = new ExtensionEntity();
     $item->merge($meta);
     $this->entityManager->persist($item);
     $this->entityManager->flush();
 }