/**
  * Gets an instance of a local Module object.
  *
  * This static method retrieves a Module located in local context, without
  * using the Module server. Module authentication is needed anyway.
  *
  * The method also builds the configuration for the Module.
  *
  * @since 5.1
  * @param ModuleLocator $locator Module locator object.
  * @return ModuleObject The Module object.
  */
 public static function getLocalModule(ModuleLocator $locator)
 {
     $location = $locator->getLocation();
     // Authenticates
     $authenticator = ModuleServerAuthenticator::instance('ModuleServerAuthenticator');
     if (!$authenticator->authenticate($locator->getUsername(), $locator->getPassword())) {
         throw new ModuleException('Not authorized');
     }
     $context = ModuleServerContext::instance('\\Innomatic\\Module\\Server\\ModuleServerContext');
     // Checks if Module exists
     $classes_dir = $context->getHome() . 'core/modules/' . $location . '/classes/';
     if (!is_dir($classes_dir)) {
         throw new ModuleException('Module does not exists');
     }
     // Checks if configuration file exists
     $moduleXml = $context->getHome() . 'core/modules/' . $location . '/setup/module.xml';
     if (!file_exists($moduleXml)) {
         throw new ModuleException('Missing module.xml configuration file');
     }
     $cfg = \Innomatic\Module\Util\ModuleXmlConfig::getInstance($moduleXml);
     $fqcn = $cfg->getFQCN();
     // Builds Module Data Access Source Name
     $dasn_string = $authenticator->getDASN($locator->getUsername(), $locator->getLocation());
     if (strpos($dasn_string, 'context:')) {
         $module_context = new ModuleContext($location);
         $dasn_string = str_replace('context:', $module_context->getHome(), $dasn_string);
     }
     $cfg->setDASN(new DataAccessSourceName($dasn_string));
     // Adds Module classes directory to classpath
     // TODO: Should add include path only if not already available
     set_include_path($classes_dir . PATH_SEPARATOR . get_include_path());
     require_once $fqcn . '.php';
     // Retrieves class name from Fully Qualified Class Name
     $class = strpos($fqcn, '/') ? substr($fqcn, strrpos($fqcn, '/') + 1) : $fqcn;
     // Instantiates the new class and returns it
     return new $class($cfg);
 }
 /**
  * Redeploys a Module in the Module server.
  *
  * @param string $module Full path of the Module archive.
  * @return boolean
  * @since 5.1
  */
 public function redeploy($module)
 {
     $module = realpath($module);
     if (!file_exists($module)) {
         throw new \Innomatic\Module\ModuleException('Unable to find Module');
     }
     $context = \Innomatic\Module\Server\ModuleServerContext::instance('\\Innomatic\\Module\\Server\\ModuleServerContext');
     $tmp_dir = $context->getHome() . 'core/temp/appinst/deploy_' . rand() . DIRECTORY_SEPARATOR;
     mkdir($tmp_dir, 0755, true);
     if (is_dir($module)) {
         // Copies the Module directory
         \Innomatic\Io\Filesystem\DirectoryUtils::dirCopy($module . '/', $tmp_dir);
     } else {
         // Unpacks the Module archive.
         $arc = new \Innomatic\Io\Archive\Archive($module, \Innomatic\Io\Archive\Archive::FORMAT_TAR);
         if (!$arc->extract($tmp_dir)) {
             \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
             throw new \Innomatic\Module\ModuleException('Unable to extract Module');
         }
     }
     // Checks if cmb.xml file exists.
     if (!file_exists($tmp_dir . 'setup/module.xml')) {
         \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
         throw new \Innomatic\Module\ModuleException('Missing module.xml configuration file');
     }
     // Parses Module configuration.
     $cfg = \Innomatic\Module\Util\ModuleXmlConfig::getInstance($tmp_dir . 'setup/module.xml');
     if (!strlen($cfg->getName())) {
         \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
         throw new \Innomatic\Module\ModuleException('Missing Module name in module.xml');
     }
     // Checks if the Module to be redeployed exists in modules directory.
     if (!is_dir($context->getHome() . 'core/modules' . DIRECTORY_SEPARATOR . $cfg->getName())) {
         \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
         throw new \Innomatic\Module\ModuleException('Module to be redeployed does not exists');
     }
     // Checks Module code.
     $code_checker = new \Innomatic\Php\PHPCodeChecker();
     if (!$code_checker->checkDirectory($tmp_dir)) {
         \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
         throw new \Innomatic\Module\ModuleException('Module contains errors in code');
     }
     // Removes old Module.
     if (is_dir($context->getHome() . 'core/modules' . DIRECTORY_SEPARATOR . $cfg->getName())) {
         \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($context->getHome() . 'core/modules' . DIRECTORY_SEPARATOR . $cfg->getName());
     }
     // Deploys new Module.
     $module_dir = $context->getHome() . 'core/modules' . DIRECTORY_SEPARATOR . $cfg->getName() . DIRECTORY_SEPARATOR;
     mkdir($module_dir, 0755, true);
     \Innomatic\Io\Filesystem\DirectoryUtils::dirCopy($tmp_dir . '/', $module_dir);
     \Innomatic\Io\Filesystem\DirectoryUtils::unlinkTree($tmp_dir);
     // Executes Module redeploy hooked actions.
     //$auth = \Innomatic\Module\Server\ModuleServerAuthenticator::instance('ModuleServerAuthenticator');
     //$module = \Innomatic\Module\ModuleFactory::getModule(new ModuleLocator('module://*****:*****@/'.$cfg->getName()));
     //$module->redeploy();
     // Logs redeployment.
     if ($context->getConfig()->getKey('log_deployer_events') == 1 or $context->getConfig()->useDefaults()) {
         $logger = new \Innomatic\Module\Server\ModuleServerLogger($context->getHome() . 'core/log/module-deployer.log');
         $logger->logEvent($cfg->getName() . ' redeployed');
     }
     return true;
 }