Merge remote-tracking branch 'MyIgel/templating'
This commit is contained in:
commit
222c9fed7d
|
@ -29,6 +29,8 @@
|
||||||
"symfony/http-foundation": "^3.3",
|
"symfony/http-foundation": "^3.3",
|
||||||
"symfony/psr-http-message-bridge": "^1.0",
|
"symfony/psr-http-message-bridge": "^1.0",
|
||||||
"twbs/bootstrap": "^3.3",
|
"twbs/bootstrap": "^3.3",
|
||||||
|
"twig/extensions": "^1.5",
|
||||||
|
"twig/twig": "^2.5",
|
||||||
"zendframework/zend-diactoros": "^1.7"
|
"zendframework/zend-diactoros": "^1.7"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|
|
@ -13,8 +13,10 @@ return [
|
||||||
\Engelsystem\Database\DatabaseServiceProvider::class,
|
\Engelsystem\Database\DatabaseServiceProvider::class,
|
||||||
\Engelsystem\Http\RequestServiceProvider::class,
|
\Engelsystem\Http\RequestServiceProvider::class,
|
||||||
\Engelsystem\Http\SessionServiceProvider::class,
|
\Engelsystem\Http\SessionServiceProvider::class,
|
||||||
|
\Engelsystem\Helpers\TranslationServiceProvider::class,
|
||||||
\Engelsystem\Http\ResponseServiceProvider::class,
|
\Engelsystem\Http\ResponseServiceProvider::class,
|
||||||
\Engelsystem\Http\Psr7ServiceProvider::class,
|
\Engelsystem\Http\Psr7ServiceProvider::class,
|
||||||
|
\Engelsystem\Renderer\TwigServiceProvider::class,
|
||||||
\Engelsystem\Middleware\RouteDispatcherServiceProvider::class,
|
\Engelsystem\Middleware\RouteDispatcherServiceProvider::class,
|
||||||
\Engelsystem\Middleware\RequestHandlerServiceProvider::class,
|
\Engelsystem\Middleware\RequestHandlerServiceProvider::class,
|
||||||
],
|
],
|
||||||
|
@ -23,6 +25,8 @@ return [
|
||||||
'middleware' => [
|
'middleware' => [
|
||||||
\Engelsystem\Middleware\SendResponseHandler::class,
|
\Engelsystem\Middleware\SendResponseHandler::class,
|
||||||
\Engelsystem\Middleware\ExceptionHandler::class,
|
\Engelsystem\Middleware\ExceptionHandler::class,
|
||||||
|
\Engelsystem\Middleware\SetLocale::class,
|
||||||
|
\Engelsystem\Middleware\ErrorHandler::class,
|
||||||
\Engelsystem\Middleware\RouteDispatcher::class,
|
\Engelsystem\Middleware\RouteDispatcher::class,
|
||||||
\Engelsystem\Middleware\RequestHandler::class,
|
\Engelsystem\Middleware\RequestHandler::class,
|
||||||
],
|
],
|
||||||
|
|
|
@ -16,17 +16,11 @@ require __DIR__ . '/includes.php';
|
||||||
* Check for maintenance
|
* Check for maintenance
|
||||||
*/
|
*/
|
||||||
if ($app->get('config')->get('maintenance')) {
|
if ($app->get('config')->get('maintenance')) {
|
||||||
echo file_get_contents(__DIR__ . '/../templates/maintenance.html');
|
echo file_get_contents(__DIR__ . '/../templates/layouts/maintenance.html');
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init translations
|
|
||||||
*/
|
|
||||||
gettext_init();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init authorization
|
* Init authorization
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,14 +15,16 @@ function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_it
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gettext_locale($recipient_user['Sprache']);
|
/** @var \Engelsystem\Helpers\Translator $translator */
|
||||||
|
$translator = app()->get('translator');
|
||||||
|
$locale = $translator->getLocale();
|
||||||
|
|
||||||
|
$translator->setLocale($recipient_user['Sprache']);
|
||||||
$message = sprintf(_('Hi %s,'), $recipient_user['Nick']) . "\n\n"
|
$message = sprintf(_('Hi %s,'), $recipient_user['Nick']) . "\n\n"
|
||||||
. _('here is a message for you from the engelsystem:') . "\n\n"
|
. _('here is a message for you from the engelsystem:') . "\n\n"
|
||||||
. $message . "\n\n"
|
. $message . "\n\n"
|
||||||
. _('This email is autogenerated and has not been signed. You got this email because you are registered in the engelsystem.');
|
. _('This email is autogenerated and has not been signed. You got this email because you are registered in the engelsystem.');
|
||||||
|
$translator->setLocale($locale);
|
||||||
gettext_locale();
|
|
||||||
|
|
||||||
return engelsystem_email($recipient_user['email'], $title, $message);
|
return engelsystem_email($recipient_user['email'], $title, $message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return currently active locale
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function locale()
|
|
||||||
{
|
|
||||||
return session()->get('locale');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns two letter language code from currently active locale
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function locale_short()
|
|
||||||
{
|
|
||||||
return substr(locale(), 0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes gettext for internationalization and updates the sessions locale to use for translation.
|
|
||||||
*/
|
|
||||||
function gettext_init()
|
|
||||||
{
|
|
||||||
$locales = config('locales');
|
|
||||||
$request = request();
|
|
||||||
$session = session();
|
|
||||||
|
|
||||||
if ($request->has('set_locale') && isset($locales[$request->input('set_locale')])) {
|
|
||||||
$session->set('locale', $request->input('set_locale'));
|
|
||||||
} elseif (!$session->has('locale')) {
|
|
||||||
$session->set('locale', config('default_locale'));
|
|
||||||
}
|
|
||||||
|
|
||||||
gettext_locale();
|
|
||||||
bindtextdomain('default', app('path.lang'));
|
|
||||||
bind_textdomain_codeset('default', 'UTF-8');
|
|
||||||
textdomain('default');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swich gettext locale.
|
|
||||||
*
|
|
||||||
* @param string $locale
|
|
||||||
*/
|
|
||||||
function gettext_locale($locale = null)
|
|
||||||
{
|
|
||||||
if (empty($locale)) {
|
|
||||||
$locale = session()->get('locale');
|
|
||||||
}
|
|
||||||
|
|
||||||
putenv('LC_ALL=' . $locale);
|
|
||||||
setlocale(LC_ALL, $locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders language selection.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function make_langselect()
|
|
||||||
{
|
|
||||||
$request = app('request');
|
|
||||||
|
|
||||||
$items = [];
|
|
||||||
foreach (config('locales') as $locale => $name) {
|
|
||||||
$url = url($request->getPathInfo(), ['set_locale' => $locale]);
|
|
||||||
|
|
||||||
$items[] = toolbar_item_link(
|
|
||||||
htmlspecialchars($url),
|
|
||||||
'',
|
|
||||||
$name,
|
|
||||||
$locale == locale()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return $items;
|
|
||||||
}
|
|
|
@ -61,7 +61,6 @@ $includeFiles = [
|
||||||
__DIR__ . '/../includes/controller/user_worklog_controller.php',
|
__DIR__ . '/../includes/controller/user_worklog_controller.php',
|
||||||
|
|
||||||
__DIR__ . '/../includes/helper/graph_helper.php',
|
__DIR__ . '/../includes/helper/graph_helper.php',
|
||||||
__DIR__ . '/../includes/helper/internationalization_helper.php',
|
|
||||||
__DIR__ . '/../includes/helper/message_helper.php',
|
__DIR__ . '/../includes/helper/message_helper.php',
|
||||||
__DIR__ . '/../includes/helper/error_helper.php',
|
__DIR__ . '/../includes/helper/error_helper.php',
|
||||||
__DIR__ . '/../includes/helper/email_helper.php',
|
__DIR__ . '/../includes/helper/email_helper.php',
|
||||||
|
|
|
@ -13,5 +13,5 @@ function credits_title()
|
||||||
*/
|
*/
|
||||||
function guest_credits()
|
function guest_credits()
|
||||||
{
|
{
|
||||||
return view(__DIR__ . '/../../templates/guest_credits.html');
|
return view(__DIR__ . '/../../templates/pages/credits.html');
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ function view_user_shifts()
|
||||||
return page([
|
return page([
|
||||||
div('col-md-12', [
|
div('col-md-12', [
|
||||||
msg(),
|
msg(),
|
||||||
view(__DIR__ . '/../../templates/user_shifts.html', [
|
view(__DIR__ . '/../../templates/pages/user-shifts.html', [
|
||||||
'title' => shifts_title(),
|
'title' => shifts_title(),
|
||||||
'room_select' => make_select($rooms, $shiftsFilter->getRooms(), 'rooms', _('Rooms')),
|
'room_select' => make_select($rooms, $shiftsFilter->getRooms(), 'rooms', _('Rooms')),
|
||||||
'start_select' => html_select_key(
|
'start_select' => html_select_key(
|
||||||
|
|
|
@ -66,6 +66,9 @@ function form_date($name, $label, $value, $start_date = '', $end_date = '')
|
||||||
$value = is_numeric($value) ? date('Y-m-d', $value) : '';
|
$value = is_numeric($value) ? date('Y-m-d', $value) : '';
|
||||||
$start_date = is_numeric($start_date) ? date('Y-m-d', $start_date) : '';
|
$start_date = is_numeric($start_date) ? date('Y-m-d', $start_date) : '';
|
||||||
$end_date = is_numeric($end_date) ? date('Y-m-d', $end_date) : '';
|
$end_date = is_numeric($end_date) ? date('Y-m-d', $end_date) : '';
|
||||||
|
$locale = $locale = session()->get('locale');
|
||||||
|
$shortLocale = substr($locale, 0, 2);
|
||||||
|
|
||||||
return form_element($label, '
|
return form_element($label, '
|
||||||
<div class="input-group date" id="' . $dom_id . '">
|
<div class="input-group date" id="' . $dom_id . '">
|
||||||
<input name="' . $name . '" class="form-control" value="' . htmlspecialchars($value) . '">'
|
<input name="' . $name . '" class="form-control" value="' . htmlspecialchars($value) . '">'
|
||||||
|
@ -73,13 +76,13 @@ function form_date($name, $label, $value, $start_date = '', $end_date = '')
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function(){
|
$(function(){
|
||||||
$(\'#' . $dom_id . '\').datepicker({
|
$("#' . $dom_id . '").datepicker({
|
||||||
language: \'' . locale_short() . '\',
|
language: "' . $shortLocale . '",
|
||||||
todayBtn: \'linked\',
|
todayBtn: "linked",
|
||||||
format: \'yyyy-mm-dd\',
|
format: "yyyy-mm-dd",
|
||||||
startDate: \'' . $start_date . '\',
|
startDate: "' . $start_date . '",
|
||||||
endDate: \'' . $end_date . '\',
|
endDate: "' . $end_date . '",
|
||||||
orientation: \'bottom\'
|
orientation: "bottom"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -110,7 +110,7 @@ function make_user_submenu()
|
||||||
{
|
{
|
||||||
global $privileges, $page;
|
global $privileges, $page;
|
||||||
|
|
||||||
$user_submenu = make_langselect();
|
$user_submenu = make_language_select();
|
||||||
|
|
||||||
if (in_array('user_settings', $privileges) || in_array('logout', $privileges)) {
|
if (in_array('user_settings', $privileges) || in_array('logout', $privileges)) {
|
||||||
$user_submenu[] = toolbar_item_divider();
|
$user_submenu[] = toolbar_item_divider();
|
||||||
|
@ -227,6 +227,30 @@ function make_room_navigation($menu)
|
||||||
return $menu;
|
return $menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders language selection.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function make_language_select()
|
||||||
|
{
|
||||||
|
$request = app('request');
|
||||||
|
$activeLocale = session()->get('locale');
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
foreach (config('locales') as $locale => $name) {
|
||||||
|
$url = url($request->getPathInfo(), ['set-locale' => $locale]);
|
||||||
|
|
||||||
|
$items[] = toolbar_item_link(
|
||||||
|
htmlspecialchars($url),
|
||||||
|
'',
|
||||||
|
$name,
|
||||||
|
$locale == $activeLocale
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -107,6 +107,7 @@ class Application extends Container
|
||||||
$this->instance('path', $appPath);
|
$this->instance('path', $appPath);
|
||||||
$this->instance('path.config', $appPath . DIRECTORY_SEPARATOR . 'config');
|
$this->instance('path.config', $appPath . DIRECTORY_SEPARATOR . 'config');
|
||||||
$this->instance('path.lang', $appPath . DIRECTORY_SEPARATOR . 'locale');
|
$this->instance('path.lang', $appPath . DIRECTORY_SEPARATOR . 'locale');
|
||||||
|
$this->instance('path.views', $appPath . DIRECTORY_SEPARATOR . 'templates');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,7 @@ class ConfigServiceProvider extends ServiceProvider
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
$config = $this->app->make(Config::class);
|
$config = $this->app->make(Config::class);
|
||||||
|
$this->app->instance(Config::class, $config);
|
||||||
$this->app->instance('config', $config);
|
$this->app->instance('config', $config);
|
||||||
|
|
||||||
foreach ($this->configFiles as $file) {
|
foreach ($this->configFiles as $file) {
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Helpers;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config;
|
||||||
|
use Engelsystem\Container\ServiceProvider;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session;
|
||||||
|
|
||||||
|
class TranslationServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
/** @var Config $config */
|
||||||
|
$config = $this->app->get('config');
|
||||||
|
/** @var Session $session */
|
||||||
|
$session = $this->app->get('session');
|
||||||
|
|
||||||
|
$locales = $config->get('locales');
|
||||||
|
$locale = $config->get('default_locale');
|
||||||
|
|
||||||
|
$sessionLocale = $session->get('locale', $locale);
|
||||||
|
if (isset($locales[$sessionLocale])) {
|
||||||
|
$locale = $sessionLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initGettext();
|
||||||
|
$session->set('locale', $locale);
|
||||||
|
|
||||||
|
$translator = $this->app->make(
|
||||||
|
Translator::class,
|
||||||
|
['locale' => $locale, 'locales' => $locales, 'localeChangeCallback' => [$this, 'setLocale']]
|
||||||
|
);
|
||||||
|
$this->app->instance(Translator::class, $translator);
|
||||||
|
$this->app->instance('translator', $translator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $textDomain
|
||||||
|
* @param string $encoding
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
protected function initGettext($textDomain = 'default', $encoding = 'UTF-8')
|
||||||
|
{
|
||||||
|
bindtextdomain($textDomain, $this->app->get('path.lang'));
|
||||||
|
bind_textdomain_codeset($textDomain, $encoding);
|
||||||
|
textdomain($textDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $locale
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function setLocale($locale)
|
||||||
|
{
|
||||||
|
putenv('LC_ALL=' . $locale);
|
||||||
|
setlocale(LC_ALL, $locale);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Helpers;
|
||||||
|
|
||||||
|
class Translator
|
||||||
|
{
|
||||||
|
/** @var string[] */
|
||||||
|
protected $locales;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $locale;
|
||||||
|
|
||||||
|
/** @var callable */
|
||||||
|
protected $localeChangeCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translator constructor.
|
||||||
|
*
|
||||||
|
* @param string $locale
|
||||||
|
* @param string[] $locales
|
||||||
|
* @param callable $localeChangeCallback
|
||||||
|
*/
|
||||||
|
public function __construct(string $locale, array $locales = [], callable $localeChangeCallback = null)
|
||||||
|
{
|
||||||
|
$this->localeChangeCallback = $localeChangeCallback;
|
||||||
|
|
||||||
|
$this->setLocale($locale);
|
||||||
|
$this->setLocales($locales);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the translation for a given key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param array $replace
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function translate(string $key, array $replace = []): string
|
||||||
|
{
|
||||||
|
$translated = $this->translateGettext($key);
|
||||||
|
|
||||||
|
if (!empty($replace)) {
|
||||||
|
$translated = call_user_func_array('sprintf', array_merge([$translated], $replace));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $translated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the key via gettext
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
protected function translateGettext(string $key): string
|
||||||
|
{
|
||||||
|
return _($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLocale(): string
|
||||||
|
{
|
||||||
|
return $this->locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $locale
|
||||||
|
*/
|
||||||
|
public function setLocale(string $locale)
|
||||||
|
{
|
||||||
|
$this->locale = $locale;
|
||||||
|
|
||||||
|
if (is_callable($this->localeChangeCallback)) {
|
||||||
|
call_user_func_array($this->localeChangeCallback, [$locale]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getLocales(): array
|
||||||
|
{
|
||||||
|
return $this->locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $locale
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasLocale(string $locale): bool
|
||||||
|
{
|
||||||
|
return isset($this->locales[$locale]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $locales
|
||||||
|
*/
|
||||||
|
public function setLocales(array $locales)
|
||||||
|
{
|
||||||
|
$this->locales = $locales;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Engelsystem\Http;
|
namespace Engelsystem\Http;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\Renderer;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||||
|
|
||||||
|
@ -9,6 +10,25 @@ class Response extends SymfonyResponse implements ResponseInterface
|
||||||
{
|
{
|
||||||
use MessageTrait;
|
use MessageTrait;
|
||||||
|
|
||||||
|
/** @var Renderer */
|
||||||
|
protected $view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $content
|
||||||
|
* @param int $status
|
||||||
|
* @param array $headers
|
||||||
|
* @param Renderer $view
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$content = '',
|
||||||
|
int $status = 200,
|
||||||
|
array $headers = array(),
|
||||||
|
Renderer $view = null
|
||||||
|
) {
|
||||||
|
$this->view = $view;
|
||||||
|
parent::__construct($content, $status, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified status code and, optionally, reason phrase.
|
* Return an instance with the specified status code and, optionally, reason phrase.
|
||||||
*
|
*
|
||||||
|
@ -72,4 +92,25 @@ class Response extends SymfonyResponse implements ResponseInterface
|
||||||
|
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance with the rendered content.
|
||||||
|
*
|
||||||
|
* THis method retains the immutability of the message and returns
|
||||||
|
* an instance with the updated status and headers
|
||||||
|
*
|
||||||
|
* @param string $view
|
||||||
|
* @param array $data
|
||||||
|
* @param int $status
|
||||||
|
* @param string[]|string[][] $headers
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function withView($view, $data = [], $status = 200, $headers = [])
|
||||||
|
{
|
||||||
|
if (!$this->view instanceof Renderer) {
|
||||||
|
throw new \InvalidArgumentException('Renderer not defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->create($this->view->render($view, $data), $status, $headers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ class SessionServiceProvider extends ServiceProvider
|
||||||
$this->app->bind(SessionStorageInterface::class, 'session.storage');
|
$this->app->bind(SessionStorageInterface::class, 'session.storage');
|
||||||
|
|
||||||
$session = $this->app->make(Session::class);
|
$session = $this->app->make(Session::class);
|
||||||
|
$this->app->instance(Session::class, $session);
|
||||||
$this->app->instance('session', $session);
|
$this->app->instance('session', $session);
|
||||||
|
|
||||||
/** @var Request $request */
|
/** @var Request $request */
|
||||||
|
|
|
@ -9,6 +9,7 @@ class UrlGeneratorServiceProvider extends ServiceProvider
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
$urlGenerator = $this->app->make(UrlGenerator::class);
|
$urlGenerator = $this->app->make(UrlGenerator::class);
|
||||||
|
$this->app->instance(UrlGenerator::class, $urlGenerator);
|
||||||
$this->app->instance('http.urlGenerator', $urlGenerator);
|
$this->app->instance('http.urlGenerator', $urlGenerator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Middleware;
|
||||||
|
|
||||||
|
use Engelsystem\Http\Response;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
use Twig_LoaderInterface as TwigLoader;
|
||||||
|
|
||||||
|
class ErrorHandler implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/** @var TwigLoader */
|
||||||
|
protected $loader;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $viewPrefix = 'errors/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TwigLoader $loader
|
||||||
|
*/
|
||||||
|
public function __construct(TwigLoader $loader)
|
||||||
|
{
|
||||||
|
$this->loader = $loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles any error messages
|
||||||
|
*
|
||||||
|
* Should be added at the beginning
|
||||||
|
*
|
||||||
|
* @param ServerRequestInterface $request
|
||||||
|
* @param RequestHandlerInterface $handler
|
||||||
|
* @return ResponseInterface
|
||||||
|
*/
|
||||||
|
public function process(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
RequestHandlerInterface $handler
|
||||||
|
): ResponseInterface {
|
||||||
|
$response = $handler->handle($request);
|
||||||
|
|
||||||
|
$statusCode = $response->getStatusCode();
|
||||||
|
if ($statusCode < 400 || !$response instanceof Response) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$view = $this->selectView($statusCode);
|
||||||
|
|
||||||
|
return $response->withView(
|
||||||
|
$this->viewPrefix . $view,
|
||||||
|
[
|
||||||
|
'status' => $statusCode,
|
||||||
|
'content' => $response->getContent(),
|
||||||
|
],
|
||||||
|
$statusCode,
|
||||||
|
$response->getHeaders()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a view based on the given status code
|
||||||
|
*
|
||||||
|
* @param int $statusCode
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function selectView(int $statusCode): string
|
||||||
|
{
|
||||||
|
$hundreds = intdiv($statusCode, 100);
|
||||||
|
|
||||||
|
$viewsList = [$statusCode, $hundreds, $hundreds * 100];
|
||||||
|
foreach ($viewsList as $view) {
|
||||||
|
if ($this->loader->exists($this->viewPrefix . $view)) {
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'default';
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,7 +83,7 @@ class LegacyMiddleware implements MiddlewareInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($title) and empty($content)) {
|
if (empty($title) and empty($content)) {
|
||||||
$page = '404';
|
$page = 404;
|
||||||
$title = _('Page not found');
|
$title = _('Page not found');
|
||||||
$content = _('This page could not be found or you don\'t have permission to view it. You probably have to sign in or register in order to gain access!');
|
$content = _('This page could not be found or you don\'t have permission to view it. You probably have to sign in or register in order to gain access!');
|
||||||
}
|
}
|
||||||
|
@ -277,29 +277,17 @@ class LegacyMiddleware implements MiddlewareInterface
|
||||||
$parameters['meetings'] = 1;
|
$parameters['meetings'] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = 200;
|
if (!empty($page) && is_int($page)) {
|
||||||
if ($page == '404') {
|
return response($content, (int)$page);
|
||||||
$status = 404;
|
|
||||||
$content = info($content, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response(view(__DIR__ . '/../../templates/layout.html', [
|
return response(view('layouts/app', [
|
||||||
'theme' => isset($user) ? $user['color'] : config('theme'),
|
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'atom_link' => ($page == 'news' || $page == 'user_meetings')
|
'atom_feed' => ($page == 'news' || $page == 'user_meetings') ? $parameters : [],
|
||||||
? ' <link href="'
|
|
||||||
. page_link_to('atom', $parameters)
|
|
||||||
. '" type = "application/atom+xml" rel = "alternate" title = "Atom Feed">'
|
|
||||||
: '',
|
|
||||||
'start_page_url' => page_link_to('/'),
|
|
||||||
'credits_url' => page_link_to('credits'),
|
|
||||||
'menu' => make_menu(),
|
'menu' => make_menu(),
|
||||||
'content' => msg() . $content,
|
'content' => msg() . $content,
|
||||||
'header_toolbar' => header_toolbar(),
|
'header_toolbar' => header_toolbar(),
|
||||||
'faq_url' => config('faq_url'),
|
|
||||||
'contact_email' => config('contact_email'),
|
|
||||||
'locale' => locale(),
|
|
||||||
'event_info' => EventConfig_info($event_config) . ' <br />'
|
'event_info' => EventConfig_info($event_config) . ' <br />'
|
||||||
]), $status);
|
]), 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Middleware;
|
||||||
|
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session;
|
||||||
|
|
||||||
|
class SetLocale implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/** @var Translator */
|
||||||
|
protected $translator;
|
||||||
|
|
||||||
|
/** @var Session */
|
||||||
|
protected $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Translator $translator
|
||||||
|
* @param Session $session
|
||||||
|
*/
|
||||||
|
public function __construct(Translator $translator, Session $session)
|
||||||
|
{
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->session = $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an incoming server request and setting the locale if required
|
||||||
|
*
|
||||||
|
* @param ServerRequestInterface $request
|
||||||
|
* @param RequestHandlerInterface $handler
|
||||||
|
* @return ResponseInterface
|
||||||
|
*/
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$query = $request->getQueryParams();
|
||||||
|
if (isset($query['set-locale']) && $this->translator->hasLocale($query['set-locale'])) {
|
||||||
|
$locale = $query['set-locale'];
|
||||||
|
|
||||||
|
$this->translator->setLocale($locale);
|
||||||
|
$this->session->set('locale', $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,12 +24,14 @@ class RendererServiceProvider extends ServiceProvider
|
||||||
protected function registerRenderer()
|
protected function registerRenderer()
|
||||||
{
|
{
|
||||||
$renderer = $this->app->make(Renderer::class);
|
$renderer = $this->app->make(Renderer::class);
|
||||||
|
$this->app->instance(Renderer::class, $renderer);
|
||||||
$this->app->instance('renderer', $renderer);
|
$this->app->instance('renderer', $renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function registerHtmlEngine()
|
protected function registerHtmlEngine()
|
||||||
{
|
{
|
||||||
$htmlEngine = $this->app->make(HtmlEngine::class);
|
$htmlEngine = $this->app->make(HtmlEngine::class);
|
||||||
|
$this->app->instance(HtmlEngine::class, $htmlEngine);
|
||||||
$this->app->instance('renderer.htmlEngine', $htmlEngine);
|
$this->app->instance('renderer.htmlEngine', $htmlEngine);
|
||||||
$this->app->tag('renderer.htmlEngine', ['renderer.engine']);
|
$this->app->tag('renderer.htmlEngine', ['renderer.engine']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config as EngelsystemConfig;
|
||||||
|
use Twig_Extension as TwigExtension;
|
||||||
|
use Twig_Function as TwigFunction;
|
||||||
|
|
||||||
|
class Config extends TwigExtension
|
||||||
|
{
|
||||||
|
/** @var EngelsystemConfig */
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EngelsystemConfig $config
|
||||||
|
*/
|
||||||
|
public function __construct(EngelsystemConfig $config)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TwigFunction[]
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFunction('config', [$this->config, 'get']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Twig_Extension as TwigExtension;
|
||||||
|
use Twig_Extension_GlobalsInterface as GlobalsInterface;
|
||||||
|
|
||||||
|
class Globals extends TwigExtension implements GlobalsInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a list of global variables to add to the existing list.
|
||||||
|
*
|
||||||
|
* @return array An array of global variables
|
||||||
|
*/
|
||||||
|
public function getGlobals()
|
||||||
|
{
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'user' => isset($user) ? $user : [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
|
||||||
|
use Twig_Extension as TwigExtension;
|
||||||
|
use Twig_Function as TwigFunction;
|
||||||
|
|
||||||
|
class Session extends TwigExtension
|
||||||
|
{
|
||||||
|
/** @var SymfonySession */
|
||||||
|
protected $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SymfonySession $session
|
||||||
|
*/
|
||||||
|
public function __construct(SymfonySession $session)
|
||||||
|
{
|
||||||
|
$this->session = $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TwigFunction[]
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFunction('session_get', [$this->session, 'get']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Twig_Extension as TwigExtension;
|
||||||
|
use Twig_Extensions_TokenParser_Trans as TranslationTokenParser;
|
||||||
|
use Twig_Filter as TwigFilter;
|
||||||
|
use Twig_Function as TwigFunction;
|
||||||
|
use Twig_TokenParserInterface as TwigTokenParser;
|
||||||
|
|
||||||
|
class Translation extends TwigExtension
|
||||||
|
{
|
||||||
|
/** @var Translator */
|
||||||
|
protected $translator;
|
||||||
|
|
||||||
|
/** @var TranslationTokenParser */
|
||||||
|
protected $tokenParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Translator $translator
|
||||||
|
* @param TranslationTokenParser $tokenParser
|
||||||
|
*/
|
||||||
|
public function __construct(Translator $translator, TranslationTokenParser $tokenParser)
|
||||||
|
{
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->tokenParser = $tokenParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFilters()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFilter('trans', [$this->translator, 'translate']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TwigFunction[]
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFunction('__', [$this->translator, 'translate']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TwigTokenParser[]
|
||||||
|
*/
|
||||||
|
public function getTokenParsers()
|
||||||
|
{
|
||||||
|
return [$this->tokenParser];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Http\UrlGenerator;
|
||||||
|
use Twig_Extension as TwigExtension;
|
||||||
|
use Twig_Function as TwigFunction;
|
||||||
|
|
||||||
|
class Url extends TwigExtension
|
||||||
|
{
|
||||||
|
/** @var UrlGenerator */
|
||||||
|
protected $urlGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param UrlGenerator $urlGenerator
|
||||||
|
*/
|
||||||
|
public function __construct(UrlGenerator $urlGenerator)
|
||||||
|
{
|
||||||
|
$this->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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer;
|
||||||
|
|
||||||
|
use Twig_Environment as Twig;
|
||||||
|
use Twig_Error_Loader as LoaderError;
|
||||||
|
use Twig_Error_Runtime as RuntimeError;
|
||||||
|
use Twig_Error_Syntax as SyntaxError;
|
||||||
|
|
||||||
|
class TwigEngine implements EngineInterface
|
||||||
|
{
|
||||||
|
/** @var Twig */
|
||||||
|
protected $twig;
|
||||||
|
|
||||||
|
public function __construct(Twig $twig)
|
||||||
|
{
|
||||||
|
$this->twig = $twig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a twig template
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param array $data
|
||||||
|
* @return string
|
||||||
|
* @throws LoaderError|RuntimeError|SyntaxError
|
||||||
|
*/
|
||||||
|
public function get($path, $data = [])
|
||||||
|
{
|
||||||
|
return $this->twig->render($path, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function canRender($path)
|
||||||
|
{
|
||||||
|
return $this->twig->getLoader()->exists($path);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Renderer;
|
||||||
|
|
||||||
|
use Twig_Error_Loader;
|
||||||
|
use Twig_Loader_Filesystem as FilesystemLoader;
|
||||||
|
|
||||||
|
class TwigLoader extends FilesystemLoader
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param bool $throw
|
||||||
|
* @return false|string
|
||||||
|
* @throws Twig_Error_Loader
|
||||||
|
*/
|
||||||
|
public function findTemplate($name, $throw = true)
|
||||||
|
{
|
||||||
|
$extension = '.twig';
|
||||||
|
$extensionLength = strlen($extension);
|
||||||
|
if (substr($name, -$extensionLength, $extensionLength) !== $extension) {
|
||||||
|
$name .= $extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::findTemplate($name, $throw);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
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\Translation;
|
||||||
|
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,
|
||||||
|
'translation' => Translation::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()
|
||||||
|
{
|
||||||
|
$viewsPath = $this->app->get('path.views');
|
||||||
|
|
||||||
|
$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']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
use Engelsystem\Application;
|
use Engelsystem\Application;
|
||||||
use Engelsystem\Config\Config;
|
use Engelsystem\Config\Config;
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
use Engelsystem\Http\Request;
|
use Engelsystem\Http\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Renderer\Renderer;
|
|
||||||
use Engelsystem\Http\UrlGenerator;
|
use Engelsystem\Http\UrlGenerator;
|
||||||
|
use Engelsystem\Renderer\Renderer;
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +119,40 @@ function session($key = null, $default = null)
|
||||||
return $session->get($key, $default);
|
return $session->get($key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the given message
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param array $replace
|
||||||
|
* @return string|Translator
|
||||||
|
*/
|
||||||
|
function trans($key = null, $replace = [])
|
||||||
|
{
|
||||||
|
/** @var Translator $translator */
|
||||||
|
$translator = app('translator');
|
||||||
|
|
||||||
|
if (is_null($key)) {
|
||||||
|
return $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $translator->translate($key, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the given message
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param array $replace
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function __($key, $replace = [])
|
||||||
|
{
|
||||||
|
/** @var Translator $translator */
|
||||||
|
$translator = app('translator');
|
||||||
|
|
||||||
|
return $translator->translate($key, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $parameters
|
* @param array $parameters
|
||||||
|
@ -139,7 +174,7 @@ function url($path = null, $parameters = [])
|
||||||
* @param mixed[] $data
|
* @param mixed[] $data
|
||||||
* @return Renderer|string
|
* @return Renderer|string
|
||||||
*/
|
*/
|
||||||
function view($template = null, $data = null)
|
function view($template = null, $data = [])
|
||||||
{
|
{
|
||||||
$renderer = app('renderer');
|
$renderer = app('renderer');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% extends "layouts/app.twig" %}
|
||||||
|
|
||||||
|
{% block title %}{% if status == 404 %}{{ __("Page not found") }}{% else %}Error {{ status }}{% endif %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="alert alert-info">{{ content }}</div>
|
||||||
|
{% endblock %}
|
|
@ -1,46 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="%locale%">
|
|
||||||
<head>
|
|
||||||
<title>%title% - Engelsystem</title>
|
|
||||||
<meta charset="UTF-8"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="%start_page_url%assets/theme%theme%.css"/>
|
|
||||||
<script type="text/javascript" src="%start_page_url%assets/vendor.js"></script>
|
|
||||||
%atom_link%
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="navbar navbar-default navbar-fixed-top">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed"
|
|
||||||
data-toggle="collapse" data-target="#navbar-collapse-1">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="%start_page_url%">
|
|
||||||
<span class="icon-icon_angel"></span> <strong class="visible-lg-inline">ENGELSYSTEM</strong>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="collapse navbar-collapse" id="navbar-collapse-1">%menu% %header_toolbar%</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">%content%</div>
|
|
||||||
<div class="row" id="footer">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<hr/>
|
|
||||||
<div class="text-center footer" style="margin-bottom: 10px;">
|
|
||||||
%event_info%
|
|
||||||
<a href="%faq_url%">FAQ</a>
|
|
||||||
· <a href="%contact_email%"><span class="glyphicon glyphicon-envelope"></span> Contact</a>
|
|
||||||
· <a href="https://github.com/engelsystem/engelsystem/issues">Bugs / Features</a>
|
|
||||||
· <a href="https://github.com/engelsystem/engelsystem/">Development Platform</a>
|
|
||||||
· <a href="%credits_url%">Credits</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
{% set theme = user.color|default(config('theme')) %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
{% block head %}
|
||||||
|
<title>{% block title %}{{ title }}{% endblock %} - Engelsystem</title>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/theme{{ theme }}.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="vendor/icomoon/style.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="vendor/bootstrap-datepicker-1.7.1/css/bootstrap-datepicker3.min.css"/>
|
||||||
|
<script type="text/javascript" src="vendor/jquery-2.1.1.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/jquery-ui.min.js"></script>
|
||||||
|
{% if atom_feed -%}
|
||||||
|
<link href="{{ url('atom', atom_feed) }}" type="application/atom+xml" rel="alternate" title="Atom Feed">
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="navbar navbar-default navbar-fixed-top">
|
||||||
|
{% block header %}
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed"
|
||||||
|
data-toggle="collapse" data-target="#navbar-collapse-1">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand" href="{{ url('/') }}">
|
||||||
|
<span class="icon-icon_angel"></span> <strong class="visible-lg-inline">ENGELSYSTEM</strong>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% block navbar %}
|
||||||
|
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
||||||
|
{{ menu|raw }}
|
||||||
|
{{ header_toolbar|raw }}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">{% block content %}{{ content|raw }}{% endblock %}</div>
|
||||||
|
<div class="row" id="footer">
|
||||||
|
{% block footer %}
|
||||||
|
<div class="col-md-12">
|
||||||
|
<hr/>
|
||||||
|
<div class="text-center footer" style="margin-bottom: 10px;">
|
||||||
|
{% block eventinfo %}
|
||||||
|
{{ event_info|raw }}
|
||||||
|
{% endblock %}
|
||||||
|
<a href="{{ config('faq_url') }}">FAQ</a>
|
||||||
|
· <a href="{{ config('contact_email') }}">
|
||||||
|
<span class="glyphicon glyphicon-envelope"></span>Contact
|
||||||
|
</a>
|
||||||
|
· <a href="https://github.com/engelsystem/engelsystem/issues">Bugs / Features</a>
|
||||||
|
· <a href="https://github.com/engelsystem/engelsystem/">Development Platform</a>
|
||||||
|
· <a href="{{ url('credits') }}">Credits</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/js/bootstrap-datepicker.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/locales/bootstrap-datepicker.de.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/Chart.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/forms.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/moment-with-locales.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
moment.locale("{{ session_get('locale')|escape('js') }}");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="js/moment-countdown.js"></script>
|
||||||
|
<script type="text/javascript" src="js/sticky-headers.js"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,15 +6,15 @@
|
||||||
<p>
|
<p>
|
||||||
The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>.
|
The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>.
|
||||||
It was then completely rewritten and enhanced by
|
It was then completely rewritten and enhanced by
|
||||||
<a href="http://notrademark.de/">msquare</a> (maintainer),
|
<a href="https://notrademark.de">msquare</a> (maintainer),
|
||||||
<a href="http://myigel.name/">MyIgel</a>,
|
<a href="https://myigel.name">MyIgel</a>,
|
||||||
<a href="http://mortzu.de/">mortzu</a>,
|
<a href="https://mortzu.de">mortzu</a>,
|
||||||
<a href="http://jplitza.de/">jplitza</a> and
|
<a href="https://jplitza.de">jplitza</a> and
|
||||||
gnomus.
|
<a href="https://github.com/gnomus">gnomus</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Please look at the <a href="https://github.com/engelsystem/engelsystem/graphs/contributors">contributor
|
Please look at the <a href="https://github.com/engelsystem/engelsystem/graphs/contributors">
|
||||||
list on github</a> for a more complete version.
|
contributor list on github</a> for a more complete version.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
<p>
|
<p>
|
||||||
Webspace, development platform and domain on <a href="https://engelsystem.de">engelsystem.de</a>
|
Webspace, development platform and domain on <a href="https://engelsystem.de">engelsystem.de</a>
|
||||||
is currently provided by <a href="https://www.wybt.net/">would you buy this?</a> (ichdasich)
|
is currently provided by <a href="https://www.wybt.net/">would you buy this?</a> (ichdasich)
|
||||||
and adminstrated by <a href="http://mortzu.de/">mortzu</a>,
|
and adminstrated by <a href="https://mortzu.de">mortzu</a>,
|
||||||
<a href="http://derf.homelinux.org/">derf</a> and ichdasich.
|
<a href="http://derf.homelinux.org">derf</a> and ichdasich.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
|
@ -48,6 +48,7 @@ class ApplicationTest extends TestCase
|
||||||
$this->assertTrue($app->has('path'));
|
$this->assertTrue($app->has('path'));
|
||||||
$this->assertTrue($app->has('path.config'));
|
$this->assertTrue($app->has('path.config'));
|
||||||
$this->assertTrue($app->has('path.lang'));
|
$this->assertTrue($app->has('path.lang'));
|
||||||
|
$this->assertTrue($app->has('path.views'));
|
||||||
|
|
||||||
$this->assertEquals(realpath('.'), $app->path());
|
$this->assertEquals(realpath('.'), $app->path());
|
||||||
$this->assertEquals(realpath('.') . '/config', $app->get('path.config'));
|
$this->assertEquals(realpath('.') . '/config', $app->get('path.config'));
|
||||||
|
|
|
@ -24,8 +24,13 @@ class ConfigServiceProviderTest extends ServiceProviderTest
|
||||||
Application::setInstance($app);
|
Application::setInstance($app);
|
||||||
|
|
||||||
$this->setExpects($app, 'make', [Config::class], $config);
|
$this->setExpects($app, 'make', [Config::class], $config);
|
||||||
$this->setExpects($app, 'instance', ['config', $config]);
|
|
||||||
$this->setExpects($app, 'get', ['path.config'], __DIR__ . '/../../../config', $this->atLeastOnce());
|
$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, 'set', null, null, $this->exactly(2));
|
||||||
$config->expects($this->exactly(3))
|
$config->expects($this->exactly(3))
|
||||||
|
@ -60,7 +65,12 @@ class ConfigServiceProviderTest extends ServiceProviderTest
|
||||||
Application::setInstance($app);
|
Application::setInstance($app);
|
||||||
|
|
||||||
$this->setExpects($app, 'make', [Config::class], $config);
|
$this->setExpects($app, 'make', [Config::class], $config);
|
||||||
$this->setExpects($app, 'instance', ['config', $config]);
|
$app->expects($this->exactly(2))
|
||||||
|
->method('instance')
|
||||||
|
->withConsecutive(
|
||||||
|
[Config::class, $config],
|
||||||
|
['config', $config]
|
||||||
|
);
|
||||||
$this->setExpects($app, 'get', ['path.config'], __DIR__ . '/not_existing', $this->atLeastOnce());
|
$this->setExpects($app, 'get', ['path.config'], __DIR__ . '/not_existing', $this->atLeastOnce());
|
||||||
|
|
||||||
$this->setExpects($config, 'set', null, null, $this->never());
|
$this->setExpects($config, 'set', null, null, $this->never());
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Helpers;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config;
|
||||||
|
use Engelsystem\Helpers\TranslationServiceProvider;
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Engelsystem\Test\Unit\ServiceProviderTest;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session;
|
||||||
|
|
||||||
|
class TranslationServiceProviderTest extends ServiceProviderTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Helpers\TranslationServiceProvider::register()
|
||||||
|
*/
|
||||||
|
public function testRegister()
|
||||||
|
{
|
||||||
|
$app = $this->getApp(['make', 'instance', 'get']);
|
||||||
|
/** @var Config|MockObject $config */
|
||||||
|
$config = $this->createMock(Config::class);
|
||||||
|
/** @var Session|MockObject $session */
|
||||||
|
$session = $this->createMock(Session::class);
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->createMock(Translator::class);
|
||||||
|
|
||||||
|
/** @var TranslationServiceProvider|MockObject $serviceProvider */
|
||||||
|
$serviceProvider = $this->getMockBuilder(TranslationServiceProvider::class)
|
||||||
|
->setConstructorArgs([$app])
|
||||||
|
->setMethods(['initGettext', 'setLocale'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$serviceProvider->expects($this->once())
|
||||||
|
->method('initGettext');
|
||||||
|
|
||||||
|
$app->expects($this->exactly(2))
|
||||||
|
->method('get')
|
||||||
|
->withConsecutive(['config'], ['session'])
|
||||||
|
->willReturnOnConsecutiveCalls($config, $session);
|
||||||
|
|
||||||
|
$defaultLocale = 'fo_OO';
|
||||||
|
$locale = 'te_ST.WTF-9';
|
||||||
|
$locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?'];
|
||||||
|
$config->expects($this->exactly(2))
|
||||||
|
->method('get')
|
||||||
|
->withConsecutive(
|
||||||
|
['locales'],
|
||||||
|
['default_locale']
|
||||||
|
)
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
$locales,
|
||||||
|
$defaultLocale
|
||||||
|
);
|
||||||
|
|
||||||
|
$session->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with('locale', $defaultLocale)
|
||||||
|
->willReturn($locale);
|
||||||
|
$session->expects($this->once())
|
||||||
|
->method('set')
|
||||||
|
->with('locale', $locale);
|
||||||
|
|
||||||
|
$app->expects($this->once())
|
||||||
|
->method('make')
|
||||||
|
->with(
|
||||||
|
Translator::class,
|
||||||
|
[
|
||||||
|
'locale' => $locale,
|
||||||
|
'locales' => $locales,
|
||||||
|
'localeChangeCallback' => [$serviceProvider, 'setLocale']
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->willReturn($translator);
|
||||||
|
|
||||||
|
$app->expects($this->exactly(2))
|
||||||
|
->method('instance')
|
||||||
|
->withConsecutive(
|
||||||
|
[Translator::class, $translator],
|
||||||
|
['translator', $translator]
|
||||||
|
);
|
||||||
|
|
||||||
|
$serviceProvider->register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Helpers;
|
||||||
|
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Engelsystem\Test\Unit\ServiceProviderTest;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class TranslatorTest extends ServiceProviderTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::__construct()
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::setLocale()
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::setLocales()
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::getLocale()
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::getLocales()
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::hasLocale()
|
||||||
|
*/
|
||||||
|
public function testInit()
|
||||||
|
{
|
||||||
|
$locales = ['te_ST.ER-01' => 'Tests', 'fo_OO' => 'SomeFOO'];
|
||||||
|
$locale = 'te_ST.ER-01';
|
||||||
|
|
||||||
|
/** @var callable|MockObject $callable */
|
||||||
|
$callable = $this->getMockBuilder(stdClass::class)
|
||||||
|
->setMethods(['__invoke'])
|
||||||
|
->getMock();
|
||||||
|
$callable->expects($this->exactly(2))
|
||||||
|
->method('__invoke')
|
||||||
|
->withConsecutive(['te_ST.ER-01'], ['fo_OO']);
|
||||||
|
|
||||||
|
$translator = new Translator($locale, $locales, $callable);
|
||||||
|
|
||||||
|
$this->assertEquals($locales, $translator->getLocales());
|
||||||
|
$this->assertEquals($locale, $translator->getLocale());
|
||||||
|
|
||||||
|
$translator->setLocale('fo_OO');
|
||||||
|
$this->assertEquals('fo_OO', $translator->getLocale());
|
||||||
|
|
||||||
|
$newLocales = ['lo_RM' => 'Lorem', 'ip_SU-M' => 'Ipsum'];
|
||||||
|
$translator->setLocales($newLocales);
|
||||||
|
$this->assertEquals($newLocales, $translator->getLocales());
|
||||||
|
|
||||||
|
$this->assertTrue($translator->hasLocale('ip_SU-M'));
|
||||||
|
$this->assertFalse($translator->hasLocale('te_ST.ER-01'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::translate()
|
||||||
|
*/
|
||||||
|
public function testTranslate()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->getMockBuilder(Translator::class)
|
||||||
|
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
||||||
|
->setMethods(['translateGettext'])
|
||||||
|
->getMock();
|
||||||
|
$translator->expects($this->once())
|
||||||
|
->method('translateGettext')
|
||||||
|
->with('My favourite number is %u!')
|
||||||
|
->willReturn('Meine Lieblingszahl ist die %u!');
|
||||||
|
|
||||||
|
$return = $translator->translate('My favourite number is %u!', [3]);
|
||||||
|
$this->assertEquals('Meine Lieblingszahl ist die 3!', $return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace Engelsystem\Test\Unit;
|
||||||
use Engelsystem\Application;
|
use Engelsystem\Application;
|
||||||
use Engelsystem\Config\Config;
|
use Engelsystem\Config\Config;
|
||||||
use Engelsystem\Container\Container;
|
use Engelsystem\Container\Container;
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
use Engelsystem\Http\Request;
|
use Engelsystem\Http\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Renderer\Renderer;
|
use Engelsystem\Renderer\Renderer;
|
||||||
use Engelsystem\Http\UrlGenerator;
|
|
||||||
use Engelsystem\Http\UrlGeneratorInterface;
|
use Engelsystem\Http\UrlGeneratorInterface;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use PHPUnit_Framework_MockObject_MockObject as MockObject;
|
use PHPUnit_Framework_MockObject_MockObject as MockObject;
|
||||||
|
@ -195,6 +195,29 @@ class HelpersTest extends TestCase
|
||||||
$this->assertEquals('rendered template', view('template.name', ['template' => 'data']));
|
$this->assertEquals('rendered template', view('template.name', ['template' => 'data']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \__
|
||||||
|
* @covers \trans
|
||||||
|
*/
|
||||||
|
public function testTrans()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->getMockBuilder(Translator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->getAppMock('translator', $translator);
|
||||||
|
|
||||||
|
$translator->expects($this->exactly(2))
|
||||||
|
->method('translate')
|
||||||
|
->with('Lorem %s Ipsum', ['foo'])
|
||||||
|
->willReturn('Lorem foo Ipsum');
|
||||||
|
|
||||||
|
$this->assertEquals($translator, trans());
|
||||||
|
$this->assertEquals('Lorem foo Ipsum', trans('Lorem %s Ipsum', ['foo']));
|
||||||
|
$this->assertEquals('Lorem foo Ipsum', __('Lorem %s Ipsum', ['foo']));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \url
|
* @covers \url
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
namespace Engelsystem\Test\Unit\Http;
|
namespace Engelsystem\Test\Unit\Http;
|
||||||
|
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
|
use Engelsystem\Renderer\Renderer;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||||
|
@ -46,4 +48,37 @@ class ResponseTest extends TestCase
|
||||||
$this->assertNotEquals($response, $newResponse);
|
$this->assertNotEquals($response, $newResponse);
|
||||||
$this->assertEquals('Lorem Ipsum?', $newResponse->getContent());
|
$this->assertEquals('Lorem Ipsum?', $newResponse->getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Http\Response::withView
|
||||||
|
*/
|
||||||
|
public function testWithView()
|
||||||
|
{
|
||||||
|
/** @var REnderer|MockObject $renderer */
|
||||||
|
$renderer = $this->createMock(Renderer::class);
|
||||||
|
|
||||||
|
$renderer->expects($this->once())
|
||||||
|
->method('render')
|
||||||
|
->with('foo', ['lorem' => 'ipsum'])
|
||||||
|
->willReturn('Foo ipsum!');
|
||||||
|
|
||||||
|
$response = new Response('', 200, [], $renderer);
|
||||||
|
$newResponse = $response->withView('foo', ['lorem' => 'ipsum'], 505, ['test' => 'er']);
|
||||||
|
|
||||||
|
$this->assertNotEquals($response, $newResponse);
|
||||||
|
$this->assertEquals('Foo ipsum!', $newResponse->getContent());
|
||||||
|
$this->assertEquals(505, $newResponse->getStatusCode());
|
||||||
|
$this->assertArraySubset(['test' => ['er']], $newResponse->getHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Http\Response::withView
|
||||||
|
*/
|
||||||
|
public function testWithViewNoRenderer()
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
|
||||||
|
$response = new Response();
|
||||||
|
$response->withView('foo');
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -54,6 +54,7 @@ class SessionServiceProviderTest extends ServiceProviderTest
|
||||||
->method('instance')
|
->method('instance')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
['session.storage', $sessionStorage],
|
['session.storage', $sessionStorage],
|
||||||
|
[Session::class, $session],
|
||||||
['session', $session]
|
['session', $session]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -88,10 +89,11 @@ class SessionServiceProviderTest extends ServiceProviderTest
|
||||||
$sessionStorage,
|
$sessionStorage,
|
||||||
$session
|
$session
|
||||||
);
|
);
|
||||||
$app->expects($this->exactly(2))
|
$app->expects($this->exactly(3))
|
||||||
->method('instance')
|
->method('instance')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
['session.storage', $sessionStorage],
|
['session.storage', $sessionStorage],
|
||||||
|
[Session::class, $session],
|
||||||
['session', $session]
|
['session', $session]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,12 @@ class UrlGeneratorServiceProviderTest extends ServiceProviderTest
|
||||||
$app = $this->getApp();
|
$app = $this->getApp();
|
||||||
|
|
||||||
$this->setExpects($app, 'make', [UrlGenerator::class], $urlGenerator);
|
$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 = new UrlGeneratorServiceProvider($app);
|
||||||
$serviceProvider->register();
|
$serviceProvider->register();
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Middleware;
|
||||||
|
|
||||||
|
use Engelsystem\Http\Response;
|
||||||
|
use Engelsystem\Middleware\ErrorHandler;
|
||||||
|
use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddlewareHandler;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Twig_LoaderInterface as TwigLoader;
|
||||||
|
|
||||||
|
class ErrorHandlerTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Middleware\ErrorHandler::__construct
|
||||||
|
* @covers \Engelsystem\Middleware\ErrorHandler::process
|
||||||
|
* @covers \Engelsystem\Middleware\ErrorHandler::selectView
|
||||||
|
*/
|
||||||
|
public function testProcess()
|
||||||
|
{
|
||||||
|
/** @var TwigLoader|MockObject $twigLoader */
|
||||||
|
$twigLoader = $this->createMock(TwigLoader::class);
|
||||||
|
/** @var ServerRequestInterface|MockObject $request */
|
||||||
|
$request = $this->createMock(ServerRequestInterface::class);
|
||||||
|
/** @var ResponseInterface|MockObject $psrResponse */
|
||||||
|
$psrResponse = $this->getMockForAbstractClass(ResponseInterface::class);
|
||||||
|
$returnResponseHandler = new ReturnResponseMiddlewareHandler($psrResponse);
|
||||||
|
|
||||||
|
$psrResponse->expects($this->once())
|
||||||
|
->method('getStatusCode')
|
||||||
|
->willReturn(505);
|
||||||
|
|
||||||
|
$errorHandler = new ErrorHandler($twigLoader);
|
||||||
|
|
||||||
|
$return = $errorHandler->process($request, $returnResponseHandler);
|
||||||
|
$this->assertEquals($psrResponse, $return, 'Plain PSR-7 Response should be passed directly');
|
||||||
|
|
||||||
|
/** @var Response|MockObject $response */
|
||||||
|
$response = $this->createMock(Response::class);
|
||||||
|
|
||||||
|
$response->expects($this->exactly(3))
|
||||||
|
->method('getStatusCode')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
200,
|
||||||
|
418,
|
||||||
|
505
|
||||||
|
);
|
||||||
|
|
||||||
|
$returnResponseHandler->setResponse($response);
|
||||||
|
$return = $errorHandler->process($request, $returnResponseHandler);
|
||||||
|
$this->assertEquals($response, $return, 'Only Responses >= 400 should be processed');
|
||||||
|
|
||||||
|
$twigLoader->expects($this->exactly(4))
|
||||||
|
->method('exists')
|
||||||
|
->withConsecutive(
|
||||||
|
['errors/418'],
|
||||||
|
['errors/4'],
|
||||||
|
['errors/400'],
|
||||||
|
['errors/505']
|
||||||
|
)
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
$response->expects($this->exactly(2))
|
||||||
|
->method('getContent')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
'Teapot',
|
||||||
|
'Internal Error!'
|
||||||
|
);
|
||||||
|
|
||||||
|
$response->expects($this->exactly(2))
|
||||||
|
->method('withView')
|
||||||
|
->withConsecutive(
|
||||||
|
['errors/default', ['status' => 418, 'content' => 'Teapot'], 418],
|
||||||
|
['errors/505', ['status' => 505, 'content' => 'Internal Error!'], 505]
|
||||||
|
)
|
||||||
|
->willReturn($response);
|
||||||
|
|
||||||
|
$errorHandler->process($request, $returnResponseHandler);
|
||||||
|
$errorHandler->process($request, $returnResponseHandler);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Middleware;
|
||||||
|
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Engelsystem\Middleware\SetLocale;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use PHPUnit_Framework_MockObject_MockObject as MockObject;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session;
|
||||||
|
|
||||||
|
class SetLocaleTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Middleware\SetLocale::__construct
|
||||||
|
* @covers \Engelsystem\Middleware\SetLocale::process
|
||||||
|
*/
|
||||||
|
public function testRegister()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->createMock(Translator::class);
|
||||||
|
/** @var Session|MockObject $session */
|
||||||
|
$session = $this->createMock(Session::class);
|
||||||
|
/** @var ServerRequestInterface|MockObject $request */
|
||||||
|
$request = $this->getMockForAbstractClass(ServerRequestInterface::class);
|
||||||
|
/** @var RequestHandlerInterface|MockObject $handler */
|
||||||
|
$handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
|
||||||
|
/** @var ResponseInterface|MockObject $response */
|
||||||
|
$response = $this->getMockForAbstractClass(ResponseInterface::class);
|
||||||
|
|
||||||
|
$locale = 'te_ST.UTF8';
|
||||||
|
|
||||||
|
$request->expects($this->exactly(3))
|
||||||
|
->method('getQueryParams')
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
[],
|
||||||
|
['set-locale' => 'en_US.UTF8'],
|
||||||
|
['set-locale' => $locale]
|
||||||
|
);
|
||||||
|
|
||||||
|
$translator->expects($this->exactly(2))
|
||||||
|
->method('hasLocale')
|
||||||
|
->withConsecutive(
|
||||||
|
['en_US.UTF8'],
|
||||||
|
[$locale]
|
||||||
|
)
|
||||||
|
->willReturnOnConsecutiveCalls(
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$translator->expects($this->once())
|
||||||
|
->method('setLocale')
|
||||||
|
->with($locale);
|
||||||
|
|
||||||
|
$session->expects($this->once())
|
||||||
|
->method('set')
|
||||||
|
->with('locale', $locale);
|
||||||
|
|
||||||
|
$handler->expects($this->exactly(3))
|
||||||
|
->method('handle')
|
||||||
|
->with($request)
|
||||||
|
->willReturn($response);
|
||||||
|
|
||||||
|
$middleware = new SetLocale($translator, $session);
|
||||||
|
$middleware->process($request, $handler);
|
||||||
|
$middleware->process($request, $handler);
|
||||||
|
$middleware->process($request, $handler);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,4 +27,14 @@ class ReturnResponseMiddlewareHandler implements RequestHandlerInterface
|
||||||
{
|
{
|
||||||
return $this->response;
|
return $this->response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the response
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
*/
|
||||||
|
public function setResponse(ResponseInterface $response)
|
||||||
|
{
|
||||||
|
$this->response = $response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,12 @@ class RendererServiceProviderTest extends ServiceProviderTest
|
||||||
$htmlEngine
|
$htmlEngine
|
||||||
);
|
);
|
||||||
|
|
||||||
$app->expects($this->exactly(2))
|
$app->expects($this->exactly(4))
|
||||||
->method('instance')
|
->method('instance')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
|
[Renderer::class, $renderer],
|
||||||
['renderer', $renderer],
|
['renderer', $renderer],
|
||||||
|
[HtmlEngine::class, $htmlEngine],
|
||||||
['renderer.htmlEngine', $htmlEngine]
|
['renderer.htmlEngine', $htmlEngine]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config as EngelsystemConfig;
|
||||||
|
use Engelsystem\Renderer\Twig\Extensions\Config;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
|
||||||
|
class ConfigTest extends ExtensionTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Config::__construct
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Config::getFunctions
|
||||||
|
*/
|
||||||
|
public function testGetFunctions()
|
||||||
|
{
|
||||||
|
/** @var EngelsystemConfig|MockObject $config */
|
||||||
|
$config = $this->createMock(EngelsystemConfig::class);
|
||||||
|
|
||||||
|
$extension = new Config($config);
|
||||||
|
$functions = $extension->getFunctions();
|
||||||
|
|
||||||
|
$this->assertExtensionExists('config', [$config, 'get'], $functions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Twig_Function as TwigFunction;
|
||||||
|
|
||||||
|
abstract class ExtensionTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Assert that a twig filter was registered
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param callable $callback
|
||||||
|
* @param TwigFunction[] $functions
|
||||||
|
*/
|
||||||
|
protected function assertFilterExists($name, $callback, $functions)
|
||||||
|
{
|
||||||
|
foreach ($functions as $function) {
|
||||||
|
if ($function->getName() != $name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals($callback, $function->getCallable());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->fail(sprintf('Filter %s not found', $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that a twig function was registered
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param callable $callback
|
||||||
|
* @param TwigFunction[] $functions
|
||||||
|
*/
|
||||||
|
protected function assertExtensionExists($name, $callback, $functions)
|
||||||
|
{
|
||||||
|
foreach ($functions as $function) {
|
||||||
|
if ($function->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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that a token parser was set
|
||||||
|
*
|
||||||
|
* @param $tokenParser
|
||||||
|
* @param $tokenParsers
|
||||||
|
*/
|
||||||
|
protected function assertTokenParserExists($tokenParser, $tokenParsers)
|
||||||
|
{
|
||||||
|
$this->assertArraySubset(
|
||||||
|
[$tokenParser],
|
||||||
|
$tokenParsers,
|
||||||
|
sprintf('Token parser %s not found', get_class($tokenParser))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\Twig\Extensions\Globals;
|
||||||
|
|
||||||
|
class GlobalsTest extends ExtensionTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Globals::getGlobals
|
||||||
|
*/
|
||||||
|
public function testGetGlobals()
|
||||||
|
{
|
||||||
|
$extension = new Globals();
|
||||||
|
$globals = $extension->getGlobals();
|
||||||
|
|
||||||
|
$this->assertGlobalsExists('user', [], $globals);
|
||||||
|
|
||||||
|
global $user;
|
||||||
|
$user['foo'] = 'bar';
|
||||||
|
|
||||||
|
$globals = $extension->getGlobals();
|
||||||
|
$this->assertGlobalsExists('user', ['foo' => 'bar'], $globals);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\Twig\Extensions\Session;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
|
||||||
|
|
||||||
|
class SessionTest extends ExtensionTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Session::__construct
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Session::getFunctions
|
||||||
|
*/
|
||||||
|
public function testGetGlobals()
|
||||||
|
{
|
||||||
|
/** @var SymfonySession|MockObject $session */
|
||||||
|
$session = $this->createMock(SymfonySession::class);
|
||||||
|
|
||||||
|
$extension = new Session($session);
|
||||||
|
$functions = $extension->getFunctions();
|
||||||
|
|
||||||
|
$this->assertExtensionExists('session_get', [$session, 'get'], $functions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Helpers\Translator;
|
||||||
|
use Engelsystem\Renderer\Twig\Extensions\Translation;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use Twig_Extensions_TokenParser_Trans as TranslationTokenParser;
|
||||||
|
|
||||||
|
class TranslationTest extends ExtensionTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Translation::__construct
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Translation::getFilters
|
||||||
|
*/
|
||||||
|
public function testGeFilters()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->createMock(Translator::class);
|
||||||
|
/** @var TranslationTokenParser|MockObject $parser */
|
||||||
|
$parser = $this->createMock(TranslationTokenParser::class);
|
||||||
|
|
||||||
|
$extension = new Translation($translator, $parser);
|
||||||
|
$filters = $extension->getFilters();
|
||||||
|
|
||||||
|
$this->assertExtensionExists('trans', [$translator, 'translate'], $filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Translation::getFunctions
|
||||||
|
*/
|
||||||
|
public function testGetFunctions()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->createMock(Translator::class);
|
||||||
|
/** @var TranslationTokenParser|MockObject $parser */
|
||||||
|
$parser = $this->createMock(TranslationTokenParser::class);
|
||||||
|
|
||||||
|
$extension = new Translation($translator, $parser);
|
||||||
|
$functions = $extension->getFunctions();
|
||||||
|
|
||||||
|
$this->assertExtensionExists('__', [$translator, 'translate'], $functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Translation::getTokenParsers
|
||||||
|
*/
|
||||||
|
public function testGetTokenParsers()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->createMock(Translator::class);
|
||||||
|
/** @var TranslationTokenParser|MockObject $parser */
|
||||||
|
$parser = $this->createMock(TranslationTokenParser::class);
|
||||||
|
|
||||||
|
$extension = new Translation($translator, $parser);
|
||||||
|
$tokenParsers = $extension->getTokenParsers();
|
||||||
|
|
||||||
|
$this->assertTokenParserExists($parser, $tokenParsers);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||||
|
|
||||||
|
use Engelsystem\Http\UrlGenerator;
|
||||||
|
use Engelsystem\Renderer\Twig\Extensions\Url;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
|
||||||
|
class UrlTest extends ExtensionTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Url::__construct
|
||||||
|
* @covers \Engelsystem\Renderer\Twig\Extensions\Url::getFunctions
|
||||||
|
*/
|
||||||
|
public function testGetGlobals()
|
||||||
|
{
|
||||||
|
/** @var UrlGenerator|MockObject $urlGenerator */
|
||||||
|
$urlGenerator = $this->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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\TwigEngine;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Twig_Environment as Twig;
|
||||||
|
use Twig_LoaderInterface as LoaderInterface;
|
||||||
|
|
||||||
|
class TwigEngineTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\TwigEngine::__construct
|
||||||
|
* @covers \Engelsystem\Renderer\TwigEngine::get
|
||||||
|
*/
|
||||||
|
public function testGet()
|
||||||
|
{
|
||||||
|
/** @var Twig|MockObject $twig */
|
||||||
|
$twig = $this->createMock(Twig::class);
|
||||||
|
|
||||||
|
$path = 'foo.twig';
|
||||||
|
$data = ['lorem' => 'ipsum'];
|
||||||
|
|
||||||
|
$twig->expects($this->once())
|
||||||
|
->method('render')
|
||||||
|
->with($path, $data)
|
||||||
|
->willReturn('LoremIpsum!');
|
||||||
|
|
||||||
|
$engine = new TwigEngine($twig);
|
||||||
|
$return = $engine->get($path, $data);
|
||||||
|
$this->assertEquals('LoremIpsum!', $return);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\TwigEngine::canRender
|
||||||
|
*/
|
||||||
|
public function testCanRender()
|
||||||
|
{
|
||||||
|
/** @var Twig|MockObject $twig */
|
||||||
|
$twig = $this->createMock(Twig::class);
|
||||||
|
/** @var LoaderInterface|MockObject $loader */
|
||||||
|
$loader = $this->getMockForAbstractClass(LoaderInterface::class);
|
||||||
|
|
||||||
|
$path = 'foo.twig';
|
||||||
|
|
||||||
|
$twig->expects($this->once())
|
||||||
|
->method('getLoader')
|
||||||
|
->willReturn($loader);
|
||||||
|
$loader->expects($this->once())
|
||||||
|
->method('exists')
|
||||||
|
->with($path)
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$engine = new TwigEngine($twig);
|
||||||
|
$return = $engine->canRender($path);
|
||||||
|
$this->assertTrue($return);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\TwigLoader;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ReflectionClass as Reflection;
|
||||||
|
|
||||||
|
class TwigLoaderTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Renderer\TwigLoader::findTemplate
|
||||||
|
*/
|
||||||
|
public function testFindTemplate()
|
||||||
|
{
|
||||||
|
$loader = new TwigLoader();
|
||||||
|
|
||||||
|
$reflection = new Reflection(get_class($loader));
|
||||||
|
$property = $reflection->getProperty('cache');
|
||||||
|
$property->setAccessible(true);
|
||||||
|
|
||||||
|
$realPath = __DIR__ . '/Stub/foo.twig';
|
||||||
|
$property->setValue($loader, ['Stub/foo.twig' => $realPath]);
|
||||||
|
|
||||||
|
$return = $loader->findTemplate('Stub/foo.twig');
|
||||||
|
$this->assertEquals($realPath, $return);
|
||||||
|
|
||||||
|
$return = $loader->findTemplate('Stub/foo');
|
||||||
|
$this->assertEquals($realPath, $return);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Engelsystem\Test\Unit\Renderer;
|
||||||
|
|
||||||
|
use Engelsystem\Renderer\TwigEngine;
|
||||||
|
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::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);
|
||||||
|
/** @var TwigLoader|MockObject $twigLoader */
|
||||||
|
$twigLoader = $this->createMock(TwigLoader::class);
|
||||||
|
/** @var Twig|MockObject $twig */
|
||||||
|
$twig = $this->createMock(Twig::class);
|
||||||
|
|
||||||
|
$app = $this->getApp(['make', 'instance', 'tag', 'get']);
|
||||||
|
|
||||||
|
$viewsPath = __DIR__ . '/Stub';
|
||||||
|
|
||||||
|
$app->expects($this->exactly(3))
|
||||||
|
->method('make')
|
||||||
|
->withConsecutive(
|
||||||
|
[TwigLoader::class, ['paths' => $viewsPath]],
|
||||||
|
[Twig::class],
|
||||||
|
[TwigEngine::class]
|
||||||
|
)->willReturnOnConsecutiveCalls(
|
||||||
|
$twigLoader,
|
||||||
|
$twig,
|
||||||
|
$twigEngine
|
||||||
|
);
|
||||||
|
|
||||||
|
$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]
|
||||||
|
);
|
||||||
|
|
||||||
|
$app->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with('path.views')
|
||||||
|
->willReturn($viewsPath);
|
||||||
|
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue