setDescription('Ensure production settings'); return $this; } public function execute(InputInterface $input, OutputInterface $output) { $output->writeln(""); $output->writeln(sprintf("Checking for PROD settings")); $output->writeln("============================="); $output->writeln(""); $this->initTests($output); $this->prepareTests($output); $this->runTests($output); return 0; } private function initTests(OutputInterface $output) { $spec = new Core\Configuration\Application(); $parser = new Core\Configuration\Parser\Yaml(); $handler = new Core\Configuration\Handler($spec, $parser); $this->configuration = new Core\Configuration($handler); if (!$this->configuration->isInstalled()) { $output->writeln(sprintf("\nPhraseanet is not installed\n")); return 1; } } private function prepareTests(OutputInterface $output) { try { $this->checkParse($output); $this->checkGetSelectedEnvironement($output); $this->checkGetSelectedEnvironementFromFile($output); } catch (\Exception $e) { $previous = $e->getPrevious(); $output->writeln(sprintf( "%s FATAL error : %s" , $e->getMessage() , $previous instanceof \Exception ? $previous->getMessage() : 'Unknown.' ) ); $output->writeln(sprintf("\nCheck test suite can not continue please correct FATAL error and relaunch.\n")); return 1; } } private function runTests(OutputInterface $output) { $nbErrors = 0; foreach ($this->testSuite as $test) { $display = ""; switch ($test) { case 'checkPhraseanetScope' : $display = "Phraseanet Scope Configuration"; break; case 'checkDatabaseScope' : $display = "Database configuration & connexion"; break; case 'checkTeamplateEngineService' : $display = "Template Engine Service"; break; case 'checkOrmService' : $display = "ORM Service"; break; } $output->writeln(sprintf("=== CHECKING %s ===", $display)); $output->writeln(""); try { call_user_func(array($this, $test), $output); $output->writeln(""); $output->writeln("Test successfull"); $output->writeln(""); } catch (\Exception $e) { $nbErrors++; $previous = $e->getPrevious(); $output->writeln(sprintf( "%s FAILED : %s" , $e->getMessage() , $previous instanceof \Exception ? $previous->getMessage() : 'Unknow' ) ); $output->writeln(""); } } if (!$nbErrors) { $output->writeln("Your production settings are setted correctly ! Enjoy"); } else { $output->writeln("Please correct errors and relaunch"); } $output->writeln(""); return (int) ($nbErrors > 0); } private function checkParse(OutputInterface $output) { $parser = $this ->configuration ->getConfigurationHandler() ->getParser(); $fileConfig = $this ->configuration ->getConfigurationHandler() ->getSpecification() ->getConfigurationFile(); $fileService = $this ->configuration ->getConfigurationHandler() ->getSpecification() ->getServiceFile(); $fileConnexion = $this ->configuration ->getConfigurationHandler() ->getSpecification() ->getConnexionFile(); try { $parser->parse($fileConfig); $parser->parse($fileService); $parser->parse($fileConnexion); } catch (\Exception $e) { $message = str_replace("\\", "", $e->getMessage()); $e = new \Exception($message); throw new \Exception(sprintf("CHECK parsing file\n"), null, $e); } return; } private function checkGetSelectedEnvironement(OutputInterface $output) { try { $this->configuration->getConfiguration(); } catch (\Exception $e) { throw new \Exception(sprintf("CHECK get selected environment\n"), null, $e); } return; } private function checkGetSelectedEnvironementFromFile(OutputInterface $output) { $spec = new Core\Configuration\Application(); $parser = new Core\Configuration\Parser\Yaml(); $handler = new Core\Configuration\Handler($spec, $parser); $configuration = new Core\Configuration($handler); try { $configuration->getConfiguration(); } catch (\Exception $e) { throw new \Exception(sprintf("CHECK get selected environment from file\n"), null, $e); } return; } private function checkPhraseanetScope(OutputInterface $output) { try { $phraseanet = $this->configuration->getPhraseanet(); $url = $phraseanet->get("servername"); if (empty($url)) { throw new \Exception("phraseanet:servername connot be empty"); } if (!filter_var($url, FILTER_VALIDATE_URL)) { throw new \Exception(sprintf("%s url is not valid", $url)); } $parseUrl = parse_url($url); if ($parseUrl["scheme"] !== "https") { $output->writeln(sprintf(" /!\ %s url scheme should be https", $url)); } $output->writeln("CHECK servername OK"); if ($phraseanet->get("debug") !== false) { throw new \Exception("phraseanet:debug must be initialized to false"); } if ($phraseanet->get("display_errors") !== false) { throw new \Exception("phraseanet:debug must be initialized to false"); } if ($phraseanet->get("maintenance") === true) { throw new \Exception("phraseanet:warning maintenance is set to false"); } $output->writeln("CHECK Phraseanet modes OK"); } catch (\Exception $e) { throw new \Exception(sprintf("Check Phraseanet Scope\n"), null, $e); } return; } private function checkDatabaseScope(OutputInterface $output) { try { $connexionName = $this->configuration->getPhraseanet()->get('database'); $connexion = $this->configuration->getConnexion($connexionName); if ($connexion->get("driver") === "pdo_sqlite") { throw new \Exception("A sqlite database is not recommanded for production environment"); } $output->writeln("CHECK database driver OK"); try { $config = new \Doctrine\DBAL\Configuration(); $conn = \Doctrine\DBAL\DriverManager::getConnection( $connexion->all() , $config ); unset($conn); $this->connexionOk = true; } catch (\Exception $e) { throw new \Exception(sprintf( "Unable to connect to database declared in connexion '%s' for the following reason %s" , $connexionName , $e->getMessage() ) ); } $output->writeln("CHECK database connexion OK"); } catch (\Exception $e) { throw new \Exception(sprintf("CHECK Database Scope\n"), null, $e); } return; } private function checkTeamplateEngineService(OutputInterface $output) { try { $templateEngineName = $this->configuration->getTemplating(); try { $configuration = $this->configuration->getService($templateEngineName); } catch (\Exception $e) { $message = sprintf( "%s called from %s in %s:template_engine scope" , $e->getMessage() , $this->configuration->getFile()->getFilename() , "PROD" , $templateEngineName ); $e = new \Exception($message); throw $e; } $serviceBuilder = new Core\ServiceBuilder\TemplateEngine( $templateEngineName , $configuration ); $service = $serviceBuilder->buildService(); $output->writeln("CHECK build service OK"); if ($service->getType() === 'twig') { $twig = $service->getService(); if ($twig->isDebug()) { throw new \Exception(sprintf("%s service should not be in debug mode", $service->getName())); } if ($twig->isStrictVariables()) { throw new \Exception(sprintf("%s service should not be set in strict variables mode", $service->getName())); } $output->writeln("CHECK service configuration OK"); } } catch (\Exception $e) { if ($e instanceof \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException) { if ($e->getKey() === 'template_engine') { $e = new \Exception(sprintf( "Missing parameter %s " , $e->getKey() ) ); } else { $e = new \Exception(sprintf( "Missing parameter %s for %s service" , $e->getKey() , $templateEngineName ) ); } } throw new \Exception(sprintf("Check Template Service\n"), null, $e); } return; } private function checkOrmService(OutputInterface $output) { if (!$this->connexionOk) { $output->writeln("As ORM service test depends on database test success, it is not executed"); return; } try { $ormName = $this->configuration->getOrm(); try { $configuration = $this->configuration->getService($ormName); } catch (\Exception $e) { $message = sprintf( "%s called from %s in %s scope" , $e->getMessage() , $this->configuration->getFile()->getFilename() , $ormName ); $e = new \Exception($message); throw $e; } $registry = \registry::get_instance(); $serviceBuilder = new Core\ServiceBuilder\Orm( $ormName , $configuration , array('registry' => $registry) ); $service = $serviceBuilder->buildService(); $output->writeln("CHECK build service OK"); if ($service->getType() === 'doctrine') { $caches = $service->getCacheServices(); if ($service->isDebug()) { throw new \Exception(sprintf( "%s service should not be in debug mode" , $service->getName() ) ); } $caches = $caches->all(); if (empty($caches)) { $cache = $install = ""; $services = $this->configuration->getServices()->all(); if (extension_loaded("memcache")) { $cache = 'memcache'; } elseif (extension_loaded("apc")) { $cache = 'apc'; } elseif (extension_loaded("xcache")) { $cache = 'xcache'; } else { $install = "cache extension such as APC or memcache or xcache"; } $selected = null; if (!empty($cache)) { foreach ($services as $name => $service) { if ($service["type"] == $cache) { $selected = $name; } } } throw new \Exception(sprintf( "%s:doctrine:orm:cache must not be empty as in production environment the cache is highly recommanded. We suggest you to %s %s" , $service->getName() , (empty($cache) ? "install " . $install : "use " . $cache) , ($selected ? "you can use " . $selected . " service which is already defined as a " . $cache . " one" : "") ) ); } foreach ($caches as $key => $cache) { if ($cache->getType() === 'array') { throw new \Exception(sprintf( "%s:doctrine:orm:%s %s service should not be an array cache type" , $service->getName() , $key , $cache->getName() ) ); } elseif ($cache->getType() === 'memcache') { if (!memcache_connect($cache->getHost(), $cache->getPort())) { throw new \Exception(sprintf("Unable to connect to memcache service %s with host '%s' and port '%s'", $cache->getName(), $cache->getHost(), $cache->getPort())); } $output->writeln("CHECK connexion memcache OK"); } } $output->writeln("CHECK service cache configuration OK"); } $output->writeln("CHECK service configuration OK"); } catch (\Exception $e) { if ($e instanceof \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException) { if ($e->getKey() === 'orm') { $e = new \Exception(sprintf( "Missing parameter %s for service %s" , $e->getKey() , $service->getName() ) ); } else { $e = new \Exception(sprintf( "Missing parameter %s for %s service declared" , $e->getKey() , $service->getName() ) ); } } throw new \Exception(sprintf("Check ORM Service\n"), null, $e); } return; } }