/** * Test service config parser - should not throw any errors. * * @return void */ public function testParser() { $config = new ServiceConfig($this->id, $this->data); $tags = $config->getTags(); $this->assertEquals($this->id, $config->getId()); $this->assertEquals('Minion\\Tests\\Service\\ServiceProvider', $config->getProviderClass()); $this->assertEquals('hello world', $config->getOption('test_service.option')); $this->assertArrayHasKey(0, $tags); $this->assertEquals('test.tag', $tags[0]); }
/** * Application constructor. * * @param string $appNamespace Application and/or vendor namespace, e.g. 'namespace', 'vendor\\namespace' * @param array $values Custom configuration * @param array $fixPaths Fix paths used to bootstrap files and directories * * @return Application * * @throws \InvalidArgumentException Missing propel configuration file * @throws \InvalidArgumentException Can not resolve project namespace * @throws InvalidConfigurationException Twig engine is not enabled, but extension configured in config.yml file * @throws \RuntimeException File parameters.yml does not exist * @throws \Exception Throws raw exceptions in test environment */ public function __construct($appNamespace = '', array $values = [], array $fixPaths = []) { // big error catch for nice debug try { $defaultValues = ['environment' => 'prod', 'minion.usePropel' => true, 'minion.useTwig' => true]; // default configuration parent::__construct(\array_replace_recursive($defaultValues, $values)); // error handler $this->error(function (\Exception $ex, $code) { return $this->minionError($ex, $code); }); // calculate directories and paths $this->resolvePaths($fixPaths); // determine project namespace, if not defined $realNamespace = $appNamespace; $jsonPath = Utils::fixPath($this->getRootDir() . '/composer.json'); if (!$appNamespace && \file_exists($jsonPath)) { $json = \json_decode(\file_get_contents($jsonPath), true); if (isset($json['autoload']) && \is_array($json['autoload'])) { foreach ($json['autoload'] as $psr) { if (\is_array($psr)) { foreach ($psr as $namespace => $path) { if (\preg_match('/^[\\/\\\\]?src[\\/\\\\]?/', $path)) { $realNamespace = $namespace; } } } } } } if (!$realNamespace) { throw new \InvalidArgumentException('Cannot resolve project namespace.'); } $this->appNamespace = $realNamespace; // register services $this->register(new MonologServiceProvider(), ['monolog.logfile' => $this->getRootDir() . Utils::fixPath('/var/log/') . ($this['debug'] ? 'dev.log' : 'prod.log'), 'monolog.name' => $this->getAppNamespace()]); if ($this['minion.useTwig']) { $this->register(new TwigServiceProvider(), ['twig.path' => $this->getRootDir() . Utils::fixPath('/src/Resources/views'), 'twig.options' => ['cache' => $this->getRootDir() . Utils::fixPath('/var/cache/twig')]]); // load Twig Extensions $this['twig']->addExtension(new AssetExtension($this)); $this['twig']->addExtension(new UrlExtension($this)); $this['twig']->addExtension(new MiscExtension($this)); } $this->register(new UrlGeneratorServiceProvider()); if ($this['minion.usePropel']) { $propelConfig = (include Utils::fixPath($this->getPropelConfigPath())); if (isset($propelConfig['propel']['paths']['phpConfDir']) && \file_exists($propelCompiledCfg = Utils::fixPath($propelConfig['propel']['paths']['phpConfDir'] . '/config.php'))) { $this->register(new PropelServiceProvider(), ['propel.config_file' => $propelCompiledCfg]); } else { throw new InvalidArgumentException('Missing Propel compiled configuration file. Use "console propel:config:convert" in console'); } } $this->register(new ConsoleServiceProvider(), ['console.name' => $this->getAppNamespace(), 'console.version' => self::VERSION, 'console.project_directory' => $this->getRootDir()]); // load configuration $loader = new YamlFileLoader(new FileLocator($this->getRootDir() . $this->getConfigPath())); /** @var RouteCollection $routes */ $routes = $loader->load('routing.yml'); // fix controller namespaces if (\count($routes) > 0) { foreach ($routes as $route) { /** @var Route $route */ if ($route->hasDefault('_controller')) { $route->setDefault('_controller', $this->getAppNamespace() . '\\Controller\\' . $route->getDefault('_controller')); } } } $this['routes']->addCollection($routes); $parametersFile = $this->getRootDir() . $this->getConfigPath() . 'parameters.yml'; if (!\file_exists($parametersFile)) { throw new \RuntimeException('File parameters.yml does not exist or is not accessible'); } /** @var array $parameters */ $parameters = Yaml::parse(\file_get_contents($parametersFile)) ?: []; $this['parameters'] = new ParameterBag($parameters); // load user-defined configuration and services $userConfigFile = $this->getRootDir() . $this->getConfigPath() . 'config.yml'; if (\file_exists($userConfigFile)) { /** @var array $userConfig */ $userConfig = Yaml::parse(\file_get_contents($userConfigFile) ?: '') ?: []; if (isset($userConfig['config'])) { $this['config'] = $userConfig['config']; } if (isset($userConfig['services'])) { /** * @var string $id * @var array $def */ foreach ($userConfig['services'] as $id => $def) { $serviceConfig = new ServiceConfig($id, $def); $class = $serviceConfig->getProviderClass(); if (\count($serviceConfig->getTags()) === 0) { /** @var SilexServiceProviderInterface|ServiceProviderInterface $provider */ $provider = new $class(); if ($provider instanceof ServiceProviderInterface) { $provider->setServiceConfig($serviceConfig); } $this->register($provider, $serviceConfig->getOptions()); } else { $calledTags = []; foreach ($serviceConfig->getTags() as $tag) { if (\in_array($tag, $calledTags)) { continue; } switch ($tag) { case 'twig.extension': $calledTags[] = $tag; if (!$this['minion.useTwig']) { throw new InvalidConfigurationException("Service '{$id}' uses 'twig.extension' tag when Twig Environment is not enabled"); } $provider = new TwigExtensionTagServiceProvider(); $provider->setServiceConfig($serviceConfig); $this->register($provider, $serviceConfig->getOptions()); break; } } } } } } // register events // inject self to the controller automatically $this['dispatcher']->addListener(KernelEvents::CONTROLLER, function (FilterControllerEvent $event) { /** @var Controller $controller */ $controller = $event->getController()[0]; $controller->setContainer($this); }); } catch (\Exception $ex) { if ($this['environment'] == 'test') { throw $ex; } else { $this->fastAbort($ex); } } }