diff --git a/src/Config/ConfigServiceProvider.php b/src/Config/ConfigServiceProvider.php
index 01b648df..21cbbeb6 100644
--- a/src/Config/ConfigServiceProvider.php
+++ b/src/Config/ConfigServiceProvider.php
@@ -12,6 +12,7 @@ class ConfigServiceProvider extends ServiceProvider
$configFile = config_path('config.php');
$config = $this->app->make(Config::class);
+ $this->app->instance(Config::class, $config);
$this->app->instance('config', $config);
$config->set(require $defaultConfigFile);
diff --git a/src/Http/SessionServiceProvider.php b/src/Http/SessionServiceProvider.php
index 55e3f48b..59121a3b 100644
--- a/src/Http/SessionServiceProvider.php
+++ b/src/Http/SessionServiceProvider.php
@@ -17,6 +17,7 @@ class SessionServiceProvider extends ServiceProvider
$this->app->bind(SessionStorageInterface::class, 'session.storage');
$session = $this->app->make(Session::class);
+ $this->app->instance(Session::class, $session);
$this->app->instance('session', $session);
/** @var Request $request */
diff --git a/src/Http/UrlGeneratorServiceProvider.php b/src/Http/UrlGeneratorServiceProvider.php
index 37304076..9b9988aa 100644
--- a/src/Http/UrlGeneratorServiceProvider.php
+++ b/src/Http/UrlGeneratorServiceProvider.php
@@ -9,6 +9,7 @@ class UrlGeneratorServiceProvider extends ServiceProvider
public function register()
{
$urlGenerator = $this->app->make(UrlGenerator::class);
+ $this->app->instance(UrlGenerator::class, $urlGenerator);
$this->app->instance('http.urlGenerator', $urlGenerator);
}
}
diff --git a/src/Middleware/LegacyMiddleware.php b/src/Middleware/LegacyMiddleware.php
index 37ae9331..bf849611 100644
--- a/src/Middleware/LegacyMiddleware.php
+++ b/src/Middleware/LegacyMiddleware.php
@@ -284,21 +284,11 @@ class LegacyMiddleware implements MiddlewareInterface
}
return response(view('layouts/app', [
- 'theme' => isset($user) ? $user['color'] : config('theme'),
'title' => $title,
- 'atom_link' => ($page == 'news' || $page == 'user_meetings')
- ? ' '
- : '',
- 'start_page_url' => page_link_to('/'),
- 'credits_url' => page_link_to('credits'),
+ 'atom_feed' => ($page == 'news' || $page == 'user_meetings') ? $parameters : [],
'menu' => make_menu(),
'content' => msg() . $content,
'header_toolbar' => header_toolbar(),
- 'faq_url' => config('faq_url'),
- 'contact_email' => config('contact_email'),
- 'locale' => locale(),
'event_info' => EventConfig_info($event_config) . '
'
]), $status);
}
diff --git a/src/Renderer/Twig/Extensions/Config.php b/src/Renderer/Twig/Extensions/Config.php
new file mode 100644
index 00000000..dbbe93e7
--- /dev/null
+++ b/src/Renderer/Twig/Extensions/Config.php
@@ -0,0 +1,31 @@
+config = $config;
+ }
+
+ /**
+ * @return TwigFunction[]
+ */
+ public function getFunctions()
+ {
+ return [
+ new TwigFunction('config', [$this->config, 'get']),
+ ];
+ }
+}
diff --git a/src/Renderer/Twig/Extensions/Globals.php b/src/Renderer/Twig/Extensions/Globals.php
new file mode 100644
index 00000000..f9bffbc8
--- /dev/null
+++ b/src/Renderer/Twig/Extensions/Globals.php
@@ -0,0 +1,23 @@
+ isset($user) ? $user : [],
+ ];
+ }
+}
diff --git a/src/Renderer/Twig/Extensions/Session.php b/src/Renderer/Twig/Extensions/Session.php
new file mode 100644
index 00000000..4690f701
--- /dev/null
+++ b/src/Renderer/Twig/Extensions/Session.php
@@ -0,0 +1,31 @@
+session = $session;
+ }
+
+ /**
+ * @return TwigFunction[]
+ */
+ public function getFunctions()
+ {
+ return [
+ new TwigFunction('session_get', [$this->session, 'get']),
+ ];
+ }
+}
diff --git a/src/Renderer/Twig/Extensions/Url.php b/src/Renderer/Twig/Extensions/Url.php
new file mode 100644
index 00000000..62e59782
--- /dev/null
+++ b/src/Renderer/Twig/Extensions/Url.php
@@ -0,0 +1,43 @@
+urlGenerator = $urlGenerator;
+ }
+
+ /**
+ * @return TwigFunction[]
+ */
+ public function getFunctions()
+ {
+ return [
+ new TwigFunction('url', [$this, 'getUrl']),
+ ];
+ }
+
+ /**
+ * @param string $path
+ * @param array $parameters
+ * @return UrlGenerator|string
+ */
+ public function getUrl($path, $parameters = [])
+ {
+ $path = str_replace('_', '-', $path);
+
+ return $this->urlGenerator->to($path, $parameters);
+ }
+}
diff --git a/src/Renderer/TwigServiceProvider.php b/src/Renderer/TwigServiceProvider.php
index 23810863..4a5b1de3 100644
--- a/src/Renderer/TwigServiceProvider.php
+++ b/src/Renderer/TwigServiceProvider.php
@@ -3,14 +3,40 @@
namespace Engelsystem\Renderer;
use Engelsystem\Container\ServiceProvider;
+use Engelsystem\Renderer\Twig\Extensions\Config;
+use Engelsystem\Renderer\Twig\Extensions\Globals;
+use Engelsystem\Renderer\Twig\Extensions\Session;
+use Engelsystem\Renderer\Twig\Extensions\Url;
use Twig_Environment as Twig;
use Twig_LoaderInterface as TwigLoaderInterface;
class TwigServiceProvider extends ServiceProvider
{
+ /** @var array */
+ protected $extensions = [
+ 'config' => Config::class,
+ 'globals' => Globals::class,
+ 'session' => Session::class,
+ 'url' => Url::class,
+ ];
+
public function register()
{
$this->registerTwigEngine();
+
+ foreach ($this->extensions as $alias => $class) {
+ $this->registerTwigExtensions($class, $alias);
+ }
+ }
+
+ public function boot()
+ {
+ /** @var Twig $renderer */
+ $renderer = $this->app->get('twig.environment');
+
+ foreach ($this->app->tagged('twig.extension') as $extension) {
+ $renderer->addExtension($extension);
+ }
}
protected function registerTwigEngine()
@@ -20,12 +46,30 @@ class TwigServiceProvider extends ServiceProvider
$twigLoader = $this->app->make(TwigLoader::class, ['paths' => $viewsPath]);
$this->app->instance(TwigLoader::class, $twigLoader);
$this->app->instance(TwigLoaderInterface::class, $twigLoader);
+ $this->app->instance('twig.loader', $twigLoader);
$twig = $this->app->make(Twig::class);
$this->app->instance(Twig::class, $twig);
+ $this->app->instance('twig.environment', $twig);
$twigEngine = $this->app->make(TwigEngine::class);
$this->app->instance('renderer.twigEngine', $twigEngine);
$this->app->tag('renderer.twigEngine', ['renderer.engine']);
}
+
+ /**
+ * @param string $class
+ * @param string $alias
+ */
+ protected function registerTwigExtensions($class, $alias)
+ {
+ $alias = 'twig.extension.' . $alias;
+
+ $extension = $this->app->make($class);
+
+ $this->app->instance($class, $extension);
+ $this->app->instance($alias, $extension);
+
+ $this->app->tag($alias, ['twig.extension']);
+ }
}
diff --git a/templates/layouts/app.twig b/templates/layouts/app.twig
index 6b6bd16f..42d5610c 100644
--- a/templates/layouts/app.twig
+++ b/templates/layouts/app.twig
@@ -1,3 +1,4 @@
+{% set theme = user.color|default(config('theme')) %}
@@ -10,7 +11,9 @@
- {{ atom_link|raw }}
+ {% if atom_feed -%}
+
+ {% endif %}
{% endblock %}
@@ -27,14 +30,16 @@
-
+
ENGELSYSTEM
{% block navbar %}
- {{ menu|raw }} {{ header_toolbar|raw }}
+
+ {{ menu|raw }}
+ {{ header_toolbar|raw }}
+
{% endblock %}
{% endblock %}
@@ -50,11 +55,13 @@
{% block eventinfo %}
{{ event_info|raw }}
{% endblock %}
- FAQ
- · Contact
+ FAQ
+ ·
+ Contact
+
· Bugs / Features
· Development Platform
- · Credits
+ · Credits
{% endblock %}
@@ -69,7 +76,7 @@
diff --git a/tests/Unit/Config/ConfigServiceProviderTest.php b/tests/Unit/Config/ConfigServiceProviderTest.php
index c8be4b7d..2e37d0da 100644
--- a/tests/Unit/Config/ConfigServiceProviderTest.php
+++ b/tests/Unit/Config/ConfigServiceProviderTest.php
@@ -23,8 +23,13 @@ class ConfigServiceProviderTest extends ServiceProviderTest
Application::setInstance($app);
$this->setExpects($app, 'make', [Config::class], $config);
- $this->setExpects($app, 'instance', ['config', $config]);
$this->setExpects($app, 'get', ['path.config'], __DIR__ . '/../../../config', $this->atLeastOnce());
+ $app->expects($this->exactly(2))
+ ->method('instance')
+ ->withConsecutive(
+ [Config::class, $config],
+ ['config', $config]
+ );
$this->setExpects($config, 'set', null, null, $this->exactly(2));
$this->setExpects($config, 'get', [null], []);
diff --git a/tests/Unit/Http/SessionServiceProviderTest.php b/tests/Unit/Http/SessionServiceProviderTest.php
index a78b4f72..d0125bc2 100644
--- a/tests/Unit/Http/SessionServiceProviderTest.php
+++ b/tests/Unit/Http/SessionServiceProviderTest.php
@@ -54,6 +54,7 @@ class SessionServiceProviderTest extends ServiceProviderTest
->method('instance')
->withConsecutive(
['session.storage', $sessionStorage],
+ [Session::class, $session],
['session', $session]
);
@@ -88,10 +89,11 @@ class SessionServiceProviderTest extends ServiceProviderTest
$sessionStorage,
$session
);
- $app->expects($this->exactly(2))
+ $app->expects($this->exactly(3))
->method('instance')
->withConsecutive(
['session.storage', $sessionStorage],
+ [Session::class, $session],
['session', $session]
);
diff --git a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php
index f3d5e018..787789fe 100644
--- a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php
+++ b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php
@@ -21,7 +21,12 @@ class UrlGeneratorServiceProviderTest extends ServiceProviderTest
$app = $this->getApp();
$this->setExpects($app, 'make', [UrlGenerator::class], $urlGenerator);
- $this->setExpects($app, 'instance', ['http.urlGenerator', $urlGenerator]);
+ $app->expects($this->exactly(2))
+ ->method('instance')
+ ->withConsecutive(
+ [UrlGenerator::class, $urlGenerator],
+ ['http.urlGenerator', $urlGenerator]
+ );
$serviceProvider = new UrlGeneratorServiceProvider($app);
$serviceProvider->register();
diff --git a/tests/Unit/Renderer/Twig/Extensions/ConfigTest.php b/tests/Unit/Renderer/Twig/Extensions/ConfigTest.php
new file mode 100644
index 00000000..6a9cb78a
--- /dev/null
+++ b/tests/Unit/Renderer/Twig/Extensions/ConfigTest.php
@@ -0,0 +1,25 @@
+createMock(EngelsystemConfig::class);
+
+ $extension = new Config($config);
+ $functions = $extension->getFunctions();
+
+ $this->assertExtensionExists('config', [$config, 'get'], $functions);
+ }
+}
diff --git a/tests/Unit/Renderer/Twig/Extensions/ExtensionTest.php b/tests/Unit/Renderer/Twig/Extensions/ExtensionTest.php
new file mode 100644
index 00000000..10f2e69a
--- /dev/null
+++ b/tests/Unit/Renderer/Twig/Extensions/ExtensionTest.php
@@ -0,0 +1,48 @@
+getName() != $name) {
+ continue;
+ }
+
+ $this->assertEquals($callback, $function->getCallable());
+ return;
+ }
+
+ $this->fail(sprintf('Function %s not found', $name));
+ }
+
+ /**
+ * Assert that a global exists
+ *
+ * @param string $name
+ * @param mixed $value
+ * @param mixed[] $globals
+ */
+ protected function assertGlobalsExists($name, $value, $globals)
+ {
+ if (isset($globals[$name])) {
+ $this->assertArraySubset([$name => $value], $globals);
+
+ return;
+ }
+
+ $this->fail(sprintf('Global %s not found', $name));
+ }
+}
diff --git a/tests/Unit/Renderer/Twig/Extensions/GlobalsTest.php b/tests/Unit/Renderer/Twig/Extensions/GlobalsTest.php
new file mode 100644
index 00000000..6cc3a4da
--- /dev/null
+++ b/tests/Unit/Renderer/Twig/Extensions/GlobalsTest.php
@@ -0,0 +1,25 @@
+getGlobals();
+
+ $this->assertGlobalsExists('user', [], $globals);
+
+ global $user;
+ $user['foo'] = 'bar';
+
+ $globals = $extension->getGlobals();
+ $this->assertGlobalsExists('user', ['foo' => 'bar'], $globals);
+ }
+}
diff --git a/tests/Unit/Renderer/Twig/Extensions/SessionTest.php b/tests/Unit/Renderer/Twig/Extensions/SessionTest.php
new file mode 100644
index 00000000..7ce4dc3a
--- /dev/null
+++ b/tests/Unit/Renderer/Twig/Extensions/SessionTest.php
@@ -0,0 +1,25 @@
+createMock(SymfonySession::class);
+
+ $extension = new Session($session);
+ $functions = $extension->getFunctions();
+
+ $this->assertExtensionExists('session_get', [$session, 'get'], $functions);
+ }
+}
diff --git a/tests/Unit/Renderer/Twig/Extensions/UrlTest.php b/tests/Unit/Renderer/Twig/Extensions/UrlTest.php
new file mode 100644
index 00000000..c7e40bea
--- /dev/null
+++ b/tests/Unit/Renderer/Twig/Extensions/UrlTest.php
@@ -0,0 +1,64 @@
+createMock(UrlGenerator::class);
+
+ $extension = new Url($urlGenerator);
+ $functions = $extension->getFunctions();
+
+ $this->assertExtensionExists('url', [$extension, 'getUrl'], $functions);
+ }
+
+ /**
+ * @return string[][]
+ */
+ public function getUrls()
+ {
+ return [
+ ['/', '/', 'http://foo.bar/'],
+ ['/foo', '/foo', 'http://foo.bar/foo'],
+ ['foo_bar', 'foo-bar', 'http://foo.bar/foo-bar'],
+ ['dolor', 'dolor', 'http://foo.bar/dolor?lorem_ipsum=dolor', ['lorem_ipsum' => 'dolor']],
+ ];
+ }
+
+ /**
+ * @dataProvider getUrls
+ *
+ * @param string $url
+ * @param string $return
+ * @param string $urlTo
+ * @param array $parameters
+ *
+ * @covers \Engelsystem\Renderer\Twig\Extensions\Url::getUrl
+ */
+ public function testGetUrl($url, $urlTo, $return, $parameters = [])
+ {
+ /** @var UrlGenerator|MockObject $urlGenerator */
+ $urlGenerator = $this->createMock(UrlGenerator::class);
+
+ $urlGenerator->expects($this->once())
+ ->method('to')
+ ->with($urlTo, $parameters)
+ ->willReturn($return);
+
+ $extension = new Url($urlGenerator);
+ $generatedUrl = $extension->getUrl($url, $parameters);
+
+ $this->assertEquals($return, $generatedUrl);
+ }
+}
diff --git a/tests/Unit/Renderer/TwigServiceProviderTest.php b/tests/Unit/Renderer/TwigServiceProviderTest.php
index ede6fae4..3cd0da4d 100644
--- a/tests/Unit/Renderer/TwigServiceProviderTest.php
+++ b/tests/Unit/Renderer/TwigServiceProviderTest.php
@@ -7,16 +7,89 @@ use Engelsystem\Renderer\TwigLoader;
use Engelsystem\Renderer\TwigServiceProvider;
use Engelsystem\Test\Unit\ServiceProviderTest;
use PHPUnit\Framework\MockObject\MockObject;
+use ReflectionClass as Reflection;
+use stdClass;
use Twig_Environment as Twig;
+use Twig_ExtensionInterface as ExtensionInterface;
use Twig_LoaderInterface as TwigLoaderInterface;
class TwigServiceProviderTest extends ServiceProviderTest
{
/**
* @covers \Engelsystem\Renderer\TwigServiceProvider::register
- * @covers \Engelsystem\Renderer\TwigServiceProvider::registerTwigEngine
+ * @covers \Engelsystem\Renderer\TwigServiceProvider::registerTwigExtensions
*/
public function testRegister()
+ {
+ $app = $this->getApp(['make', 'instance', 'tag']);
+ $class = $this->createMock(stdClass::class);
+
+ $className = 'Foo\Bar\Class';
+ $classAlias = 'twig.extension.foo';
+
+ $app->expects($this->once())
+ ->method('make')
+ ->with('Foo\Bar\Class')
+ ->willReturn($class);
+
+ $app->expects($this->exactly(2))
+ ->method('instance')
+ ->withConsecutive(
+ [$className, $class],
+ [$classAlias, $class]
+ );
+
+ $app->expects($this->once())
+ ->method('tag')
+ ->with($classAlias, ['twig.extension']);
+
+ /** @var TwigServiceProvider|MockObject $serviceProvider */
+ $serviceProvider = $this->getMockBuilder(TwigServiceProvider::class)
+ ->setConstructorArgs([$app])
+ ->setMethods(['registerTwigEngine'])
+ ->getMock();
+ $serviceProvider->expects($this->once())
+ ->method('registerTwigEngine');
+ $this->setExtensionsTo($serviceProvider, ['foo' => 'Foo\Bar\Class']);
+
+ $serviceProvider->register();
+ }
+
+ /**
+ * @covers \Engelsystem\Renderer\TwigServiceProvider::boot
+ */
+ public function testBoot()
+ {
+ /** @var Twig|MockObject $twig */
+ $twig = $this->createMock(Twig::class);
+ /** @var ExtensionInterface|MockObject $firsExtension */
+ $firsExtension = $this->getMockForAbstractClass(ExtensionInterface::class);
+ /** @var ExtensionInterface|MockObject $secondExtension */
+ $secondExtension = $this->getMockForAbstractClass(ExtensionInterface::class);
+
+ $app = $this->getApp(['get', 'tagged']);
+
+ $app->expects($this->once())
+ ->method('get')
+ ->with('twig.environment')
+ ->willReturn($twig);
+ $app->expects($this->once())
+ ->method('tagged')
+ ->with('twig.extension')
+ ->willReturn([$firsExtension, $secondExtension]);
+
+ $twig->expects($this->exactly(2))
+ ->method('addExtension')
+ ->withConsecutive($firsExtension, $secondExtension);
+
+ $serviceProvider = new TwigServiceProvider($app);
+ $serviceProvider->boot();
+ }
+
+ /**
+ * @covers \Engelsystem\Renderer\TwigServiceProvider::registerTwigEngine
+ */
+ public function testRegisterTWigEngine()
{
/** @var TwigEngine|MockObject $htmlEngine */
$twigEngine = $this->createMock(TwigEngine::class);
@@ -41,12 +114,14 @@ class TwigServiceProviderTest extends ServiceProviderTest
$twigEngine
);
- $app->expects($this->exactly(4))
+ $app->expects($this->exactly(6))
->method('instance')
->withConsecutive(
[TwigLoader::class, $twigLoader],
[TwigLoaderInterface::class, $twigLoader],
+ ['twig.loader', $twigLoader],
[Twig::class, $twig],
+ ['twig.environment', $twig],
['renderer.twigEngine', $twigEngine]
);
@@ -58,6 +133,23 @@ class TwigServiceProviderTest extends ServiceProviderTest
$this->setExpects($app, 'tag', ['renderer.twigEngine', ['renderer.engine']]);
$serviceProvider = new TwigServiceProvider($app);
+ $this->setExtensionsTo($serviceProvider, []);
+
$serviceProvider->register();
}
+
+ /**
+ * @param TwigServiceProvider $serviceProvider
+ * @param array $extensions
+ * @throws \ReflectionException
+ */
+ protected function setExtensionsTo($serviceProvider, $extensions)
+ {
+ $reflection = new Reflection(get_class($serviceProvider));
+
+ $property = $reflection->getProperty('extensions');
+ $property->setAccessible(true);
+
+ $property->setValue($serviceProvider, $extensions);
+ }
}