diff --git a/src/Container/ApplicationFactory.php b/src/Container/ApplicationFactory.php index 4a294129..db25a9b9 100644 --- a/src/Container/ApplicationFactory.php +++ b/src/Container/ApplicationFactory.php @@ -13,6 +13,7 @@ use Zend\Diactoros\Response\EmitterInterface; use Zend\Expressive\Application; use Zend\Expressive\Exception; +use Zend\Expressive\Container\Exception\PhpSettingsFailureException; use Zend\Expressive\Router\FastRouteRouter; use Zend\Expressive\Router\Route; use Zend\Expressive\Router\RouterInterface; @@ -136,6 +137,7 @@ public function __invoke(ContainerInterface $container) $app = new Application($router, $container, $finalHandler, $emitter); + $this->setPhpSettings($container); $this->injectPreMiddleware($app, $container); $this->injectRoutes($app, $container); $this->injectPostMiddleware($app, $container); @@ -143,6 +145,32 @@ public function __invoke(ContainerInterface $container) return $app; } + /** + * Sets provided PHP settings, if any. + * + * @param ContainerInterface $container + * @throws Exception\InvalidArgumentException for invalid PHP settings. + * @throws PhpSettingsFailureException if setting of PHP configuration fails. + */ + private function setPhpSettings(ContainerInterface $container) + { + $config = $container->has('config') ? $container->get('config') : []; + + if (!isset($config['php_settings'])) { + return; + } + + if (!is_array($config['php_settings'])) { + throw new Exception\InvalidArgumentException('Invalid PHP settings configuration; must be an array'); + } + + foreach ($config['php_settings'] as $name => $value) { + if (false === ini_set($name, $value)) { + throw PhpSettingsFailureException::forOption($name, $value); + } + } + } + /** * Inject routes from configuration, if any. * diff --git a/src/Container/Exception/PhpSettingsFailureException.php b/src/Container/Exception/PhpSettingsFailureException.php new file mode 100644 index 00000000..e3dd60b3 --- /dev/null +++ b/src/Container/Exception/PhpSettingsFailureException.php @@ -0,0 +1,23 @@ +factory = new ApplicationFactory(); } + protected function getContainer($config = null, $router = null, $finalHandler = null, $emitter = null) + { + if (null !== $config) { + $this->container + ->has('config') + ->willReturn(true); + + $this->container + ->get('config') + ->willReturn($config); + } else { + $this->container + ->has('config') + ->willReturn(false); + } + + if (null !== $router) { + $this->container + ->has('Zend\Expressive\Router\RouterInterface') + ->willReturn(true); + $this->container + ->get('Zend\Expressive\Router\RouterInterface') + ->will(function () use ($router) { + return $router->reveal(); + }); + } else { + $this->container + ->has('Zend\Expressive\Router\RouterInterface') + ->willReturn(false); + } + + if (null !== $finalHandler) { + $this->container + ->has('Zend\Expressive\FinalHandler') + ->willReturn(true); + $this->container + ->get('Zend\Expressive\FinalHandler') + ->willReturn($finalHandler); + } else { + $this->container + ->has('Zend\Expressive\FinalHandler') + ->willReturn(false); + } + + if (null !== $emitter) { + $this->container + ->has('Zend\Diactoros\Response\EmitterInterface') + ->willReturn(true); + $this->container + ->get('Zend\Diactoros\Response\EmitterInterface') + ->will(function () use ($emitter) { + return $emitter->reveal(); + }); + } else { + $this->container + ->has('Zend\Diactoros\Response\EmitterInterface') + ->willReturn(false); + } + + return $this->container; + } + public function assertRoute($spec, array $routes) { $this->assertTrue(array_reduce($routes, function ($found, $route) use ($spec) { @@ -65,6 +127,49 @@ public function getRouterFromApplication(Application $app) return $r->getValue($app); } + /** + * @expectedException \Zend\Expressive\Exception\InvalidArgumentException + */ + public function testInvalidPhpSettingsRaisesException() + { + $config = ['php_settings' => 'invalid']; + + $this->factory->__invoke($this->getContainer($config)->reveal()); + } + + /** + * @expectedException \Zend\Expressive\Container\Exception\PhpSettingsFailureException + */ + public function testWhenSettingPhpConfigurationFailsExceptionIsRaised() + { + $config = [ + 'php_settings' => [ + 'invalid_option' => 1, + ], + ]; + + $this->factory->__invoke($this->getContainer($config)->reveal()); + } + + public function testFactorySetsPhpSettingsFromConfig() + { + $config = [ + 'php_settings' => [ + 'display_errors' => 1, + 'date.timezone' => 'Europe/Belgrade', + ], + ]; + + $this->iniSet('display_errors', 0); + $this->iniSet('date.timezone', 'UTC'); + + $this->factory->__invoke($this->getContainer($config)->reveal()); + + foreach ($config['php_settings'] as $name => $value) { + $this->assertEquals($value, ini_get($name)); + } + } + public function testFactoryWillPullAllReplaceableDependenciesFromContainerWhenPresent() { $router = $this->prophesize('Zend\Expressive\Router\RouterInterface');