From cc01c906ba63b3797bf2b9ef92a6854fe2ddbefb Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Tue, 29 Aug 2017 16:21:25 +0200 Subject: #336: Integration of symfony/http-foundation request --- src/Routing/UrlGenerator.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/Routing/UrlGenerator.php (limited to 'src/Routing/UrlGenerator.php') diff --git a/src/Routing/UrlGenerator.php b/src/Routing/UrlGenerator.php new file mode 100644 index 00000000..8dc464c6 --- /dev/null +++ b/src/Routing/UrlGenerator.php @@ -0,0 +1,27 @@ +getUriForPath($path); + + if (!empty($parameters) && is_array($parameters)) { + $parameters = http_build_query($parameters); + $uri .= '?' . $parameters; + } + + return $uri; + } +} -- cgit v1.2.3-70-g09d2 From 8c81adc8e83969e90b4c54daf4a396b1094134ff Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Thu, 31 Aug 2017 17:30:54 +0200 Subject: Implemented container --- .gitignore | 3 +- composer.json | 3 +- includes/engelsystem_provider.php | 20 ++++- includes/helper/internationalization_helper.php | 4 +- includes/pages/user_atom.php | 3 +- public/index.php | 3 - src/Config/Config.php | 28 ------- src/Container/Container.php | 105 ++++++++++++++++++++++++ src/Container/ContainerException.php | 11 +++ src/Container/NotFoundException.php | 10 +++ src/Http/Request.php | 25 ------ src/Renderer/Renderer.php | 24 +----- src/Routing/UrlGenerator.php | 4 +- src/helpers.php | 29 +++++-- 14 files changed, 175 insertions(+), 97 deletions(-) create mode 100644 src/Container/Container.php create mode 100644 src/Container/ContainerException.php create mode 100644 src/Container/NotFoundException.php (limited to 'src/Routing/UrlGenerator.php') diff --git a/.gitignore b/.gitignore index d712148b..eb3f8939 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,9 @@ Thumbs.db _vimrc_local.vim .sass-cache -# PHPstorm config +# PHPstorm files /.idea/ +/.phpstorm.meta.php # Project files /config/config.php diff --git a/composer.json b/composer.json index 45dce626..0769a6b6 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ "php": ">=7.0.0", "erusev/parsedown": "1.6.*", "twbs/bootstrap": "^3.3", - "symfony/http-foundation": "^3.3" + "symfony/http-foundation": "^3.3", + "psr/container": "^1.0" }, "require-dev": { "phpunit/phpunit": "^6.3" diff --git a/includes/engelsystem_provider.php b/includes/engelsystem_provider.php index aed331d4..f3c161a6 100644 --- a/includes/engelsystem_provider.php +++ b/includes/engelsystem_provider.php @@ -1,11 +1,13 @@ instance('container', $container); +$container->instance(ContainerInterface::class, $container); + + /** * Load configuration */ $config = new Config(); -Config::setInstance($config); +$container->instance('config', $config); $config->set(require __DIR__ . '/../config/config.default.php'); if (file_exists(__DIR__ . '/../config/config.php')) { @@ -37,7 +48,8 @@ date_default_timezone_set($config->get('timezone')); * @var Request $request */ $request = Request::createFromGlobals(); -$request::setInstance($request); +$container->instance('request', $request); + /** * Check for maintenance @@ -52,14 +64,15 @@ if ($config->get('maintenance')) { * Initialize renderer */ $renderer = new Renderer(); +$container->instance('renderer', $renderer); $renderer->addRenderer(new HtmlEngine()); -Renderer::setInstance($renderer); /** * Register error handler */ $errorHandler = new ExceptionHandler(); +$container->instance('error.handler', $errorHandler); if (config('environment') == 'development') { $errorHandler->setEnvironment(ExceptionHandler::ENV_DEVELOPMENT); ini_set('display_errors', true); @@ -171,6 +184,7 @@ foreach ($includeFiles as $file) { * Init application */ $session = new Session(); +$container->instance('session', $session); $session->start(); $request->setSession($session); diff --git a/includes/helper/internationalization_helper.php b/includes/helper/internationalization_helper.php index 131941e9..efbe5db5 100644 --- a/includes/helper/internationalization_helper.php +++ b/includes/helper/internationalization_helper.php @@ -1,7 +1,5 @@ $name) { diff --git a/includes/pages/user_atom.php b/includes/pages/user_atom.php index 2991bdbf..c9d9398e 100644 --- a/includes/pages/user_atom.php +++ b/includes/pages/user_atom.php @@ -1,7 +1,6 @@ Engelsystem diff --git a/public/index.php b/public/index.php index b44e1491..c65dbdf8 100644 --- a/public/index.php +++ b/public/index.php @@ -1,7 +1,5 @@ query->get('p'); if (empty($page)) { $page = $request->path(); diff --git a/src/Config/Config.php b/src/Config/Config.php index 02080de4..34c21a78 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -2,15 +2,8 @@ namespace Engelsystem\Config; -use ErrorException; - class Config { - /** - * @var self - */ - protected static $instance; - /** * The config values * @@ -104,25 +97,4 @@ class Config { $this->remove($key); } - - /** - * @return Config - * @throws ErrorException - */ - public static function getInstance() - { - if (!self::$instance instanceof self) { - throw new ErrorException('Config not initialized'); - } - - return self::$instance; - } - - /** - * @param self $instance - */ - public static function setInstance($instance) - { - self::$instance = $instance; - } } diff --git a/src/Container/Container.php b/src/Container/Container.php new file mode 100644 index 00000000..df2f92fe --- /dev/null +++ b/src/Container/Container.php @@ -0,0 +1,105 @@ +has($id)) { + return $this->resolve($id); + } + + throw new NotFoundException(sprintf('The entry with the id "%s" could not be found')); + } + + /** + * Register a shared entry in the container + * + * @param string $abstract Identifier of the entry to set + * @param mixed $instance Entry + */ + public function instance($abstract, $instance) + { + $this->instances[$abstract] = $instance; + } + + /** + * Returns true if the container can return an entry for the given identifier + * Returns false otherwise + * + * `has($id)` returning true does not mean that `get($id)` will not throw an exception + * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface` + * + * @param string $id Identifier of the entry to look for + * + * @return bool + */ + public function has($id) + { + return isset($this->instances[$id]); + } + + /** + * Get the globally available instance of the container + * + * @return Container + */ + public static function getInstance() + { + if (is_null(static::$instance)) { + static::$instance = new static; + } + + return static::$instance; + } + + /** + * Set the globally available instance of the container + * + * @param Container $container + */ + public static function setInstance(Container $container) + { + static::$instance = $container; + } + + /** + * Resolve the requested object + * + * @param string $abstract + * @return mixed + */ + protected function resolve($abstract) + { + return $this->instances[$abstract]; + } +} diff --git a/src/Container/ContainerException.php b/src/Container/ContainerException.php new file mode 100644 index 00000000..3cdde506 --- /dev/null +++ b/src/Container/ContainerException.php @@ -0,0 +1,11 @@ +getUri()), '/'); } - - /** - * @return self - * @throws ErrorException - */ - public static function getInstance() - { - if (!self::$instance instanceof self) { - throw new ErrorException('Request not initialized'); - } - - return self::$instance; - } - - /** - * @param self $instance - */ - public static function setInstance($instance) - { - self::$instance = $instance; - } } diff --git a/src/Renderer/Renderer.php b/src/Renderer/Renderer.php index bf3d5609..5ed7cf31 100644 --- a/src/Renderer/Renderer.php +++ b/src/Renderer/Renderer.php @@ -2,13 +2,8 @@ namespace Engelsystem\Renderer; -use ErrorException; - class Renderer { - /** @var self */ - protected static $instance; - /** @var EngineInterface[] */ protected $renderer = []; @@ -29,7 +24,7 @@ class Renderer return $renderer->get($template, $data); } - engelsystem_error('Unable to find a renderer for template file «' . $template . '».'); + engelsystem_error('Unable to find a renderer for template file "' . $template . '".'); return ''; } @@ -42,21 +37,4 @@ class Renderer { $this->renderer[] = $renderer; } - - /** - * @return self - * @throws ErrorException - */ - public static function getInstance() - { - return self::$instance; - } - - /** - * @param self $instance - */ - public static function setInstance($instance) - { - self::$instance = $instance; - } } diff --git a/src/Routing/UrlGenerator.php b/src/Routing/UrlGenerator.php index 8dc464c6..33eef7b0 100644 --- a/src/Routing/UrlGenerator.php +++ b/src/Routing/UrlGenerator.php @@ -2,8 +2,6 @@ namespace Engelsystem\Routing; -use Engelsystem\Http\Request; - class UrlGenerator { /** @@ -14,7 +12,7 @@ class UrlGenerator public static function to($path, $parameters = []) { $path = '/' . ltrim($path, '/'); - $request = Request::getInstance(); + $request = app('request'); $uri = $request->getUriForPath($path); if (!empty($parameters) && is_array($parameters)) { diff --git a/src/helpers.php b/src/helpers.php index 24f93f2c..733b902d 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -2,11 +2,27 @@ // Some useful functions use Engelsystem\Config\Config; +use Engelsystem\Container\Container; use Engelsystem\Http\Request; use Engelsystem\Renderer\Renderer; use Engelsystem\Routing\UrlGenerator; use Symfony\Component\HttpFoundation\Session\SessionInterface; +/** + * Get the global container instance + * + * @param string $id + * @return mixed + */ +function app($id = null) +{ + if (is_null($id)) { + return Container::getInstance(); + } + + return Container::getInstance()->get($id); +} + /** * Get or set config values * @@ -16,15 +32,18 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface; */ function config($key = null, $default = null) { + $config = app('config'); + if (empty($key)) { - return Config::getInstance(); + return $config; } if (is_array($key)) { - Config::getInstance()->set($key); + $config->set($key); + return true; } - return Config::getInstance()->get($key, $default); + return $config->get($key, $default); } /** @@ -34,7 +53,7 @@ function config($key = null, $default = null) */ function request($key = null, $default = null) { - $request = Request::getInstance(); + $request = app('request'); if (is_null($key)) { return $request; @@ -66,7 +85,7 @@ function session($key = null, $default = null) */ function view($template = null, $data = null) { - $renderer = Renderer::getInstance(); + $renderer = app('renderer'); if (is_null($template)) { return $renderer; -- cgit v1.2.3-70-g09d2 From 86c0713baa2f616bf1dff6d9dbe0ea68b1c00e91 Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Wed, 20 Sep 2017 01:09:11 +0200 Subject: Added helpers unit test --- includes/engelsystem_provider.php | 8 ++ src/Routing/UrlGenerator.php | 2 +- src/helpers.php | 14 ++- tests/Unit/HelpersTest.php | 152 ++++++++++++++++++++++++++++++++ tests/Unit/Routing/UrlGeneratorTest.php | 3 +- 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 tests/Unit/HelpersTest.php (limited to 'src/Routing/UrlGenerator.php') diff --git a/includes/engelsystem_provider.php b/includes/engelsystem_provider.php index a9305df5..cd22f6a7 100644 --- a/includes/engelsystem_provider.php +++ b/includes/engelsystem_provider.php @@ -8,6 +8,7 @@ use Engelsystem\Http\Request; use Engelsystem\Logger\EngelsystemLogger; use Engelsystem\Renderer\HtmlEngine; use Engelsystem\Renderer\Renderer; +use Engelsystem\Routing\UrlGenerator; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; @@ -59,6 +60,13 @@ if ($config->get('maintenance')) { } +/** + * Register UrlGenerator + */ +$urlGenerator = new UrlGenerator(); +$app->instance('routing.urlGenerator', $urlGenerator); + + /** * Initialize renderer */ diff --git a/src/Routing/UrlGenerator.php b/src/Routing/UrlGenerator.php index 33eef7b0..6df52425 100644 --- a/src/Routing/UrlGenerator.php +++ b/src/Routing/UrlGenerator.php @@ -9,7 +9,7 @@ class UrlGenerator * @param array $parameters * @return string */ - public static function to($path, $parameters = []) + public function to($path, $parameters = []) { $path = '/' . ltrim($path, '/'); $request = app('request'); diff --git a/src/helpers.php b/src/helpers.php index b942068f..de303963 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -69,7 +69,7 @@ function request($key = null, $default = null) */ function session($key = null, $default = null) { - $session = request()->getSession(); + $session = app('session'); if (is_null($key)) { return $session; @@ -97,9 +97,15 @@ function view($template = null, $data = null) /** * @param string $path * @param array $parameters - * @return string + * @return UrlGenerator|string */ -function url($path, $parameters = []) +function url($path = null, $parameters = []) { - return UrlGenerator::to($path, $parameters); + $urlGenerator = app('routing.urlGenerator'); + + if (is_null($path)) { + return $urlGenerator; + } + + return $urlGenerator->to($path, $parameters); } diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php new file mode 100644 index 00000000..d9782888 --- /dev/null +++ b/tests/Unit/HelpersTest.php @@ -0,0 +1,152 @@ +getAppMock('some.name', $class); + + $this->assertEquals($appMock, app()); + $this->assertEquals($class, app('some.name')); + } + + /** + * @covers \config + */ + public function testConfig() + { + $configMock = $this->getMockBuilder(Config::class) + ->getMock(); + + $this->getAppMock('config', $configMock); + $this->assertEquals($configMock, config()); + + $configMock->expects($this->once()) + ->method('set') + ->with(['foo' => 'bar']); + + $this->assertTrue(config(['foo' => 'bar'])); + + $configMock->expects($this->once()) + ->method('get') + ->with('mail') + ->willReturn(['user' => 'FooBar']); + + $this->assertEquals(['user' => 'FooBar'], config('mail')); + } + + /** + * @covers \request + */ + public function testRequest() + { + $requestMock = $this->getMockBuilder(Request::class) + ->getMock(); + + $this->getAppMock('request', $requestMock); + $this->assertEquals($requestMock, request()); + + $requestMock->expects($this->once()) + ->method('input') + ->with('requestKey') + ->willReturn('requestValue'); + + $this->assertEquals('requestValue', request('requestKey')); + } + + /** + * @covers \session + */ + public function testSession() + { + $sessionMock = $this->getMockBuilder(Session::class) + ->getMock(); + + $this->getAppMock('session', $sessionMock); + $this->assertEquals($sessionMock, session()); + + $sessionMock->expects($this->once()) + ->method('get') + ->with('someKey') + ->willReturn('someValue'); + + $this->assertEquals('someValue', session('someKey')); + } + + /** + * @covers \view + */ + public function testView() + { + $rendererMock = $this->getMockBuilder(Renderer::class) + ->getMock(); + + $this->getAppMock('renderer', $rendererMock); + $this->assertEquals($rendererMock, view()); + + $rendererMock->expects($this->once()) + ->method('render') + ->with('template.name', ['template' => 'data']) + ->willReturn('rendered template'); + + $this->assertEquals('rendered template', view('template.name', ['template' => 'data'])); + } + + /** + * @covers \url + */ + public function testUrl() + { + $urlGeneratorMock = $this->getMockBuilder(UrlGenerator::class) + ->getMock(); + + $this->getAppMock('routing.urlGenerator', $urlGeneratorMock); + $this->assertEquals($urlGeneratorMock, url()); + + $urlGeneratorMock->expects($this->once()) + ->method('to') + ->with('foo/bar', ['param' => 'value']) + ->willReturn('http://lorem.ipsum/foo/bar?param=value'); + + $this->assertEquals('http://lorem.ipsum/foo/bar?param=value', url('foo/bar', ['param' => 'value'])); + } + + /** + * @param string $alias + * @param object $object + * @return Application|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getAppMock($alias, $object) + { + $appMock = $this->getMockBuilder(Container::class) + ->getMock(); + + $appMock->expects($this->atLeastOnce()) + ->method('get') + ->with($alias) + ->willReturn($object); + + /** @var $appMock Application */ + Application::setInstance($appMock); + + return $appMock; + } +} diff --git a/tests/Unit/Routing/UrlGeneratorTest.php b/tests/Unit/Routing/UrlGeneratorTest.php index 5b53a04e..fc23520a 100644 --- a/tests/Unit/Routing/UrlGeneratorTest.php +++ b/tests/Unit/Routing/UrlGeneratorTest.php @@ -32,6 +32,7 @@ class UrlGeneratorTest extends TestCase public function testTo($urlToPath, $path, $willReturn, $arguments, $expectedUrl) { $app = new Container(); + $urlGenerator = new UrlGenerator(); Application::setInstance($app); $request = $this->getMockBuilder(Request::class) @@ -44,7 +45,7 @@ class UrlGeneratorTest extends TestCase $app->instance('request', $request); - $url = UrlGenerator::to($urlToPath, $arguments); + $url = $urlGenerator->to($urlToPath, $arguments); $this->assertEquals($expectedUrl, $url); } } -- cgit v1.2.3-70-g09d2