Merge pull request #347 from MyIgel/master
Implemented Container, closes #342
This commit is contained in:
commit
801c17aa6c
|
@ -14,12 +14,14 @@ Thumbs.db
|
|||
_vimrc_local.vim
|
||||
.sass-cache
|
||||
|
||||
# PHPstorm config
|
||||
# PHPstorm files
|
||||
/.idea/
|
||||
/.phpstorm.meta.php
|
||||
|
||||
# Project files
|
||||
/config/config.php
|
||||
/test/coverage
|
||||
/public/coverage
|
||||
|
||||
# Composer files
|
||||
/vendor/
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
"php": ">=7.0.0",
|
||||
"erusev/parsedown": "1.6.*",
|
||||
"twbs/bootstrap": "^3.3",
|
||||
"symfony/http-foundation": "^3.3"
|
||||
"symfony/http-foundation": "^3.3",
|
||||
"psr/container": "^1.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.3"
|
||||
|
|
|
@ -44,6 +44,9 @@ return [
|
|||
// Number of News shown on one site
|
||||
'display_news' => 6,
|
||||
|
||||
// Users are able to sign up
|
||||
'registration_enabled' => true,
|
||||
|
||||
// Only arrived angels can sign up for shifts
|
||||
'signup_requires_arrival' => false,
|
||||
|
||||
|
|
|
@ -28,3 +28,6 @@ UPDATE `Groups` SET UID = UID * 10;
|
|||
INSERT INTO `Groups` (Name, UID) VALUES ('News Admin', -65);
|
||||
INSERT INTO `Privileges` (id, name, `desc`) VALUES (42, 'admin_news_html', 'Use HTML in news');
|
||||
INSERT INTO `GroupPrivileges` (group_id, privilege_id) VALUES (-65, 14), (-65, 42);
|
||||
|
||||
-- Add log level to LogEntries
|
||||
ALTER TABLE `LogEntries` CHANGE COLUMN `nick` `level` VARCHAR(20) NOT NULL;
|
||||
|
|
|
@ -1,24 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Application;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Database\Db;
|
||||
use Engelsystem\Exceptions\Handler as ExceptionHandler;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Logger\EngelsystemLogger;
|
||||
use Engelsystem\Renderer\HtmlEngine;
|
||||
use Engelsystem\Renderer\Renderer;
|
||||
use Engelsystem\Routing\UrlGenerator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
|
||||
|
||||
/**
|
||||
* This file includes all needed functions, connects to the db etc.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/autoload.php';
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the application
|
||||
*/
|
||||
$app = Application::getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* Load configuration
|
||||
*/
|
||||
$config = new Config();
|
||||
Config::setInstance($config);
|
||||
$app->instance('config', $config);
|
||||
$config->set(require __DIR__ . '/../config/config.default.php');
|
||||
|
||||
if (file_exists(__DIR__ . '/../config/config.php')) {
|
||||
|
@ -37,7 +49,8 @@ date_default_timezone_set($config->get('timezone'));
|
|||
* @var Request $request
|
||||
*/
|
||||
$request = Request::createFromGlobals();
|
||||
$request::setInstance($request);
|
||||
$app->instance('request', $request);
|
||||
|
||||
|
||||
/**
|
||||
* Check for maintenance
|
||||
|
@ -48,18 +61,26 @@ if ($config->get('maintenance')) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register UrlGenerator
|
||||
*/
|
||||
$urlGenerator = new UrlGenerator();
|
||||
$app->instance('routing.urlGenerator', $urlGenerator);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize renderer
|
||||
*/
|
||||
$renderer = new Renderer();
|
||||
$app->instance('renderer', $renderer);
|
||||
$renderer->addRenderer(new HtmlEngine());
|
||||
Renderer::setInstance($renderer);
|
||||
|
||||
|
||||
/**
|
||||
* Register error handler
|
||||
*/
|
||||
$errorHandler = new ExceptionHandler();
|
||||
$app->instance('error.handler', $errorHandler);
|
||||
if (config('environment') == 'development') {
|
||||
$errorHandler->setEnvironment(ExceptionHandler::ENV_DEVELOPMENT);
|
||||
ini_set('display_errors', true);
|
||||
|
@ -80,6 +101,14 @@ Db::connect(
|
|||
Db::getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
Db::getPdo()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
|
||||
/**
|
||||
* Init logger
|
||||
*/
|
||||
$logger = new EngelsystemLogger();
|
||||
$app->instance('logger', $logger);
|
||||
$app->instance(LoggerInterface::class, $logger);
|
||||
$app->instance(EngelsystemLogger::class, $logger);
|
||||
|
||||
|
||||
/**
|
||||
* Include legacy code
|
||||
|
@ -170,7 +199,9 @@ foreach ($includeFiles as $file) {
|
|||
/**
|
||||
* Init application
|
||||
*/
|
||||
$session = new Session();
|
||||
$sessionStorage = (PHP_SAPI != 'cli' ? new NativeSessionStorage(['cookie_httponly' => true]) : new MockArraySessionStorage());
|
||||
$session = new Session($sessionStorage);
|
||||
$app->instance('session', $session);
|
||||
$session->start();
|
||||
$request->setSession($session);
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Http\Request;
|
||||
|
||||
/**
|
||||
* Return currently active locale
|
||||
*
|
||||
|
@ -65,7 +63,7 @@ function gettext_locale($locale = null)
|
|||
*/
|
||||
function make_langselect()
|
||||
{
|
||||
$request = Request::getInstance();
|
||||
$request = app('request');
|
||||
|
||||
$items = [];
|
||||
foreach (config('locales') as $locale => $name) {
|
||||
|
|
|
@ -5,16 +5,16 @@ use Engelsystem\Database\DB;
|
|||
/**
|
||||
* Creates a log entry.
|
||||
*
|
||||
* @param string $nick Username
|
||||
* @param string $message Log Message
|
||||
* @param string $logLevel Log level
|
||||
* @param string $message Log Message
|
||||
* @return bool
|
||||
*/
|
||||
function LogEntry_create($nick, $message)
|
||||
function LogEntry_create($logLevel, $message)
|
||||
{
|
||||
return DB::insert('
|
||||
INSERT INTO `LogEntries` (`timestamp`, `nick`, `message`)
|
||||
INSERT INTO `LogEntries` (`timestamp`, `level`, `message`)
|
||||
VALUES(?, ?, ?)
|
||||
', [time(), $nick, $message]);
|
||||
', [time(), $logLevel, $message]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ function LogEntries_filter($keyword)
|
|||
return DB::select('
|
||||
SELECT *
|
||||
FROM `LogEntries`
|
||||
WHERE `nick` LIKE ?
|
||||
WHERE `level` LIKE ?
|
||||
OR `message` LIKE ?
|
||||
ORDER BY `timestamp` DESC
|
||||
',
|
||||
|
|
|
@ -17,12 +17,10 @@ function admin_log()
|
|||
if (request()->has('keyword')) {
|
||||
$filter = strip_request_item('keyword');
|
||||
}
|
||||
$log_entries_source = LogEntries_filter($filter);
|
||||
$log_entries = LogEntries_filter($filter);
|
||||
|
||||
$log_entries = [];
|
||||
foreach ($log_entries_source as $log_entry) {
|
||||
foreach ($log_entries as &$log_entry) {
|
||||
$log_entry['date'] = date('d.m.Y H:i', $log_entry['timestamp']);
|
||||
$log_entries[] = $log_entry;
|
||||
}
|
||||
|
||||
return page_with_title(admin_log_title(), [
|
||||
|
@ -33,7 +31,7 @@ function admin_log()
|
|||
]),
|
||||
table([
|
||||
'date' => 'Time',
|
||||
'nick' => 'Angel',
|
||||
'level' => 'Type',
|
||||
'message' => 'Log Entry'
|
||||
], $log_entries)
|
||||
]);
|
||||
|
|
|
@ -33,7 +33,7 @@ function logout_title()
|
|||
*/
|
||||
function guest_register()
|
||||
{
|
||||
global $user;
|
||||
global $user, $privileges;
|
||||
$tshirt_sizes = config('tshirt_sizes');
|
||||
$enable_tshirt_size = config('enable_tshirt_size');
|
||||
$min_password_length = config('min_password_length');
|
||||
|
@ -75,6 +75,14 @@ function guest_register()
|
|||
}
|
||||
}
|
||||
|
||||
if (!in_array('register', $privileges) || (!isset($user) && !config('registration_enabled'))) {
|
||||
error(_('Registration is disabled.'));
|
||||
|
||||
return page_with_title(register_title(), [
|
||||
msg(),
|
||||
]);
|
||||
}
|
||||
|
||||
if ($request->has('submit')) {
|
||||
$valid = true;
|
||||
|
||||
|
@ -496,7 +504,7 @@ function get_register_hint()
|
|||
{
|
||||
global $privileges;
|
||||
|
||||
if (in_array('register', $privileges)) {
|
||||
if (in_array('register', $privileges) && config('registration_enabled')) {
|
||||
return join('', [
|
||||
'<p>' . _('Please sign up, if you want to help us!') . '</p>',
|
||||
buttons([
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Database\DB;
|
||||
use Engelsystem\Http\Request;
|
||||
|
||||
/**
|
||||
* Publically available page to feed the news to feed readers
|
||||
|
@ -45,7 +44,7 @@ function user_atom()
|
|||
*/
|
||||
function make_atom_entries_from_news($news_entries)
|
||||
{
|
||||
$request = Request::getInstance();
|
||||
$request = app('request');
|
||||
$html = '<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Engelsystem</title>
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
function engelsystem_log($message)
|
||||
{
|
||||
global $user;
|
||||
|
||||
$nick = "Guest";
|
||||
$logger = app('logger');
|
||||
|
||||
if (isset($user)) {
|
||||
$nick = User_Nick_render($user);
|
||||
}
|
||||
LogEntry_create($nick, $message);
|
||||
|
||||
$logger->info('{nick}: {message}', ['nick' => $nick, 'message' => $message]);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ function header_toolbar()
|
|||
);
|
||||
}
|
||||
|
||||
if (!isset($user) && in_array('register', $privileges)) {
|
||||
if (!isset($user) && in_array('register', $privileges) && config('registration_enabled')) {
|
||||
$toolbar_items[] = toolbar_item_link(page_link_to('register'), 'plus', register_title(), $page == 'register');
|
||||
}
|
||||
|
||||
|
|
|
@ -475,13 +475,27 @@ function AngelTypes_about_view_angeltype($angeltype)
|
|||
*/
|
||||
function AngelTypes_about_view($angeltypes, $user_logged_in)
|
||||
{
|
||||
global $privileges;
|
||||
|
||||
$buttons = [];
|
||||
|
||||
if ($user_logged_in) {
|
||||
$buttons[] = button(page_link_to('angeltypes'), angeltypes_title(), 'back');
|
||||
} else {
|
||||
if (in_array('register', $privileges) && config('registration_enabled')) {
|
||||
$buttons[] = button(page_link_to('register'), register_title());
|
||||
}
|
||||
|
||||
$buttons[] = button(page_link_to('login'), login_title());
|
||||
}
|
||||
|
||||
$faqUrl = config('faq_url');
|
||||
if (!empty($faqUrl)) {
|
||||
$buttons[] = button($faqUrl, _('FAQ'), 'btn-primary');
|
||||
}
|
||||
|
||||
$content = [
|
||||
buttons([
|
||||
!$user_logged_in ? button(page_link_to('register'), register_title()) : '',
|
||||
!$user_logged_in ? button(page_link_to('login'), login_title()) : '',
|
||||
$user_logged_in ? button(page_link_to('angeltypes'), angeltypes_title(), 'back') : '',
|
||||
button(config('faq_url'), _('FAQ'), 'btn-primary')
|
||||
]),
|
||||
buttons($buttons),
|
||||
'<p>' . _('Here is the list of teams and their tasks. If you have questions, read the FAQ.') . '</p>',
|
||||
'<hr />'
|
||||
];
|
||||
|
|
10
phpunit.xml
10
phpunit.xml
|
@ -1,17 +1,19 @@
|
|||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
bootstrap="./includes/engelsystem_provider.php"
|
||||
bootstrap="./includes/autoload.php"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.3/phpunit.xsd"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Models">
|
||||
<directory>./test/model/</directory>
|
||||
<testsuite name="Feature">
|
||||
<directory>./tests/Feature</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Unit">
|
||||
<directory>./tests/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./include/</directory>
|
||||
<directory>./public/</directory>
|
||||
<directory>./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Http\Request;
|
||||
|
||||
require_once realpath(__DIR__ . '/../includes/engelsystem_provider.php');
|
||||
|
||||
$free_pages = [
|
||||
|
@ -27,7 +25,6 @@ $page = '';
|
|||
$title = '';
|
||||
$content = '';
|
||||
|
||||
/** @var Request $request */
|
||||
$page = $request->query->get('p');
|
||||
if (empty($page)) {
|
||||
$page = $request->path();
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem;
|
||||
|
||||
use Engelsystem\Container\Container;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class Application extends Container
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerBaseBindings();
|
||||
}
|
||||
|
||||
protected function registerBaseBindings()
|
||||
{
|
||||
self::setInstance($this);
|
||||
Container::setInstance($this);
|
||||
$this->instance('app', $this);
|
||||
$this->instance('container', $this);
|
||||
$this->instance(Container::class, $this);
|
||||
$this->instance(Application::class, $this);
|
||||
$this->instance(ContainerInterface::class, $this);
|
||||
}
|
||||
}
|
|
@ -2,15 +2,8 @@
|
|||
|
||||
namespace Engelsystem\Config;
|
||||
|
||||
use ErrorException;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var self
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* The config values
|
||||
*
|
||||
|
@ -104,25 +97,4 @@ class Config
|
|||
{
|
||||
$this->remove($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Config
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance instanceof self) {
|
||||
throw new ErrorException('Config not initialized');
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param self $instance
|
||||
*/
|
||||
public static function setInstance($instance)
|
||||
{
|
||||
self::$instance = $instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Container;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class Container implements ContainerInterface
|
||||
{
|
||||
/**
|
||||
* The globally available container
|
||||
*
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Contains the shared instances
|
||||
*
|
||||
* @var mixed[]
|
||||
*/
|
||||
protected $instances = [];
|
||||
|
||||
/**
|
||||
* Finds an entry of the container by its identifier and returns it
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for
|
||||
*
|
||||
* @throws NotFoundExceptionInterface No entry was found for **this** identifier
|
||||
* @throws ContainerExceptionInterface Error while retrieving the entry
|
||||
*
|
||||
* @return mixed Entry
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
if ($this->has($id)) {
|
||||
return $this->resolve($id);
|
||||
}
|
||||
|
||||
throw new NotFoundException(sprintf('The entry with the id "%s" could not be found', $id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a shared entry in the container
|
||||
*
|
||||
* @param string $abstract Identifier of the entry to set
|
||||
* @param mixed $instance Entry
|
||||
*/
|
||||
public function instance($abstract, $instance)
|
||||
{
|
||||
$this->singleton($abstract, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a shared entry as singleton in the container
|
||||
*
|
||||
* @param string $abstract
|
||||
* @param mixed $instance
|
||||
*/
|
||||
public function singleton($abstract, $instance)
|
||||
{
|
||||
$this->instances[$abstract] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the container can return an entry for the given identifier
|
||||
* Returns false otherwise
|
||||
*
|
||||
* `has($id)` returning true does not mean that `get($id)` will not throw an exception
|
||||
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($id)
|
||||
{
|
||||
return isset($this->instances[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the requested object
|
||||
*
|
||||
* @param string $abstract
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolve($abstract)
|
||||
{
|
||||
return $this->instances[$abstract];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the globally available instance of the container
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(static::$instance)) {
|
||||
static::$instance = new static;
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the globally available instance of the container
|
||||
*
|
||||
* @param Container $container
|
||||
*/
|
||||
public static function setInstance(Container $container)
|
||||
{
|
||||
static::$instance = $container;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Container;
|
||||
|
||||
use Exception;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
||||
class ContainerException extends Exception implements ContainerExceptionInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Container;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class NotFoundException extends ContainerException implements NotFoundExceptionInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ class Handler
|
|||
/**
|
||||
* @param Throwable $e
|
||||
*/
|
||||
public function exceptionHandler(Throwable $e)
|
||||
public function exceptionHandler($e)
|
||||
{
|
||||
$this->handle(
|
||||
'exception',
|
||||
|
|
|
@ -2,14 +2,10 @@
|
|||
|
||||
namespace Engelsystem\Http;
|
||||
|
||||
use ErrorException;
|
||||
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
|
||||
|
||||
class Request extends SymfonyRequest
|
||||
{
|
||||
/** @var self */
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Get POST input
|
||||
*
|
||||
|
@ -68,25 +64,4 @@ class Request extends SymfonyRequest
|
|||
{
|
||||
return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance instanceof self) {
|
||||
throw new ErrorException('Request not initialized');
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param self $instance
|
||||
*/
|
||||
public static function setInstance($instance)
|
||||
{
|
||||
self::$instance = $instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Logger;
|
||||
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Psr\Log\InvalidArgumentException;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class EngelsystemLogger extends AbstractLogger
|
||||
{
|
||||
protected $allowedLevels = [
|
||||
LogLevel::ALERT,
|
||||
LogLevel::CRITICAL,
|
||||
LogLevel::DEBUG,
|
||||
LogLevel::EMERGENCY,
|
||||
LogLevel::ERROR,
|
||||
LogLevel::INFO,
|
||||
LogLevel::NOTICE,
|
||||
LogLevel::WARNING,
|
||||
];
|
||||
|
||||
/**
|
||||
* Logs with an arbitrary level.
|
||||
*
|
||||
* @TODO: Implement $context['exception']
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
if (!$this->checkLevel($level)) {
|
||||
throw new InvalidArgumentException();
|
||||
}
|
||||
|
||||
$message = $this->interpolate($message, $context);
|
||||
|
||||
LogEntry_create($level, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates context values into the message placeholders.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
* @return string
|
||||
*/
|
||||
protected function interpolate($message, array $context = [])
|
||||
{
|
||||
foreach ($context as $key => $val) {
|
||||
// check that the value can be casted to string
|
||||
if (is_array($val) || (is_object($val) && !method_exists($val, '__toString'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// replace the values of the message
|
||||
$message = str_replace('{' . $key . '}', $val, $message);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkLevel($level)
|
||||
{
|
||||
return in_array($level, $this->allowedLevels);
|
||||
}
|
||||
}
|
|
@ -29,6 +29,6 @@ class HtmlEngine implements EngineInterface
|
|||
*/
|
||||
public function canRender($path)
|
||||
{
|
||||
return strpos($path, '.html') && file_exists($path);
|
||||
return strpos($path, '.htm') && file_exists($path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
namespace Engelsystem\Renderer;
|
||||
|
||||
use ErrorException;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
|
||||
class Renderer
|
||||
{
|
||||
/** @var self */
|
||||
protected static $instance;
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/** @var EngineInterface[] */
|
||||
protected $renderer = [];
|
||||
|
@ -29,7 +28,10 @@ class Renderer
|
|||
return $renderer->get($template, $data);
|
||||
}
|
||||
|
||||
engelsystem_error('Unable to find a renderer for template file «' . $template . '».');
|
||||
if ($this->logger) {
|
||||
$this->logger->error('Unable to find a renderer for template file "{file}"', ['file' => $template]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -42,21 +44,4 @@ class Renderer
|
|||
{
|
||||
$this->renderer[] = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param self $instance
|
||||
*/
|
||||
public static function setInstance($instance)
|
||||
{
|
||||
self::$instance = $instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Engelsystem\Routing;
|
||||
|
||||
use Engelsystem\Http\Request;
|
||||
|
||||
class UrlGenerator
|
||||
{
|
||||
/**
|
||||
|
@ -11,10 +9,10 @@ class UrlGenerator
|
|||
* @param array $parameters
|
||||
* @return string
|
||||
*/
|
||||
public static function to($path, $parameters = [])
|
||||
public function to($path, $parameters = [])
|
||||
{
|
||||
$path = '/' . ltrim($path, '/');
|
||||
$request = Request::getInstance();
|
||||
$request = app('request');
|
||||
$uri = $request->getUriForPath($path);
|
||||
|
||||
if (!empty($parameters) && is_array($parameters)) {
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
<?php
|
||||
// Some useful functions
|
||||
|
||||
use Engelsystem\Application;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Renderer\Renderer;
|
||||
use Engelsystem\Routing\UrlGenerator;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
/**
|
||||
* Get the global app instance
|
||||
*
|
||||
* @param string $id
|
||||
* @return mixed
|
||||
*/
|
||||
function app($id = null)
|
||||
{
|
||||
if (is_null($id)) {
|
||||
return Application::getInstance();
|
||||
}
|
||||
|
||||
return Application::getInstance()->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set config values
|
||||
*
|
||||
|
@ -16,15 +32,18 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
|||
*/
|
||||
function config($key = null, $default = null)
|
||||
{
|
||||
$config = app('config');
|
||||
|
||||
if (empty($key)) {
|
||||
return Config::getInstance();
|
||||
return $config;
|
||||
}
|
||||
|
||||
if (is_array($key)) {
|
||||
Config::getInstance()->set($key);
|
||||
$config->set($key);
|
||||
return true;
|
||||
}
|
||||
|
||||
return Config::getInstance()->get($key, $default);
|
||||
return $config->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,7 +53,7 @@ function config($key = null, $default = null)
|
|||
*/
|
||||
function request($key = null, $default = null)
|
||||
{
|
||||
$request = Request::getInstance();
|
||||
$request = app('request');
|
||||
|
||||
if (is_null($key)) {
|
||||
return $request;
|
||||
|
@ -50,7 +69,7 @@ function request($key = null, $default = null)
|
|||
*/
|
||||
function session($key = null, $default = null)
|
||||
{
|
||||
$session = request()->getSession();
|
||||
$session = app('session');
|
||||
|
||||
if (is_null($key)) {
|
||||
return $session;
|
||||
|
@ -66,7 +85,7 @@ function session($key = null, $default = null)
|
|||
*/
|
||||
function view($template = null, $data = null)
|
||||
{
|
||||
$renderer = Renderer::getInstance();
|
||||
$renderer = app('renderer');
|
||||
|
||||
if (is_null($template)) {
|
||||
return $renderer;
|
||||
|
@ -78,9 +97,15 @@ function view($template = null, $data = null)
|
|||
/**
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @return string
|
||||
* @return UrlGenerator|string
|
||||
*/
|
||||
function url($path, $parameters = [])
|
||||
function url($path = null, $parameters = [])
|
||||
{
|
||||
return UrlGenerator::to($path, $parameters);
|
||||
$urlGenerator = app('routing.urlGenerator');
|
||||
|
||||
if (is_null($path)) {
|
||||
return $urlGenerator;
|
||||
}
|
||||
|
||||
return $urlGenerator->to($path, $parameters);
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
namespace Engelsystem\Test;
|
||||
|
||||
use \PHPUnit\Framework\TestCase;
|
||||
|
||||
class LogEntriesModelTest extends TestCase
|
||||
{
|
||||
|
||||
public function create_LogEntry()
|
||||
{
|
||||
LogEntry_create('test', 'test');
|
||||
}
|
||||
|
||||
public function test_LogEntry_create()
|
||||
{
|
||||
$count = count(LogEntries());
|
||||
$this->assertNotFalse(LogEntry_create('test', 'test_LogEntry_create'));
|
||||
|
||||
// There should be one more log entry now
|
||||
$this->assertEquals(count(LogEntries()), $count + 1);
|
||||
}
|
||||
|
||||
public function test_LogEntries_clear_all()
|
||||
{
|
||||
$this->create_LogEntry();
|
||||
$this->assertTrue(count(LogEntries()) > 0);
|
||||
$this->assertNotFalse(LogEntries_clear_all());
|
||||
$this->assertEquals(count(LogEntries()), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @after
|
||||
*/
|
||||
public function teardown()
|
||||
{
|
||||
LogEntries_clear_all();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Logger;
|
||||
|
||||
use Engelsystem\Logger\EngelsystemLogger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\InvalidArgumentException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class EngelsystemLoggerTest extends TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
require_once __DIR__ . '/../../../includes/engelsystem_provider.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return new EngelsystemLogger();
|
||||
}
|
||||
|
||||
public function testImplements()
|
||||
{
|
||||
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function provideLogLevels()
|
||||
{
|
||||
return [
|
||||
[LogLevel::ALERT],
|
||||
[LogLevel::CRITICAL],
|
||||
[LogLevel::DEBUG],
|
||||
[LogLevel::EMERGENCY],
|
||||
[LogLevel::ERROR],
|
||||
[LogLevel::INFO],
|
||||
[LogLevel::NOTICE],
|
||||
[LogLevel::WARNING],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideLogLevels
|
||||
* @param string $level
|
||||
*/
|
||||
public function testAllLevels($level)
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
|
||||
LogEntries_clear_all();
|
||||
|
||||
$logger->log($level, 'First log message');
|
||||
$logger->{$level}('Second log message');
|
||||
|
||||
$entries = LogEntries();
|
||||
$this->assertCount(2, $entries);
|
||||
}
|
||||
|
||||
public function testContextReplacement()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
LogEntries_clear_all();
|
||||
|
||||
$logger->log(LogLevel::INFO, 'My username is {username}', ['username' => 'Foo']);
|
||||
|
||||
$entry = $this->getLastEntry();
|
||||
$this->assertEquals('My username is Foo', $entry['message']);
|
||||
$this->assertEquals(LogLevel::INFO, $entry['level']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function provideContextReplaceValues()
|
||||
{
|
||||
return [
|
||||
['Data and {context}', [], 'Data and {context}'],
|
||||
['Data and {context}', ['context' => null], 'Data and '],
|
||||
['Data and {context}', ['context' => new \stdClass()], 'Data and {context}'],
|
||||
['Some user asked: {question}', ['question' => 'Foo?'], 'Some user asked: Foo?'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideContextReplaceValues
|
||||
*
|
||||
* @param string $message
|
||||
* @param string[] $context
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testContextReplaceValues($message, $context, $expected)
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
$logger->log(LogLevel::INFO, $message, $context);
|
||||
|
||||
$entry = $this->getLastEntry();
|
||||
$this->assertEquals($expected, $entry['message']);
|
||||
}
|
||||
|
||||
public function testContextToString()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
LogEntries_clear_all();
|
||||
|
||||
$mock = $this->getMockBuilder('someDataProvider')
|
||||
->setMethods(['__toString'])
|
||||
->getMock();
|
||||
|
||||
$mock->expects($this->atLeastOnce())
|
||||
->method('__toString')
|
||||
->will($this->returnValue('FooBar'));
|
||||
|
||||
$logger->log(LogLevel::INFO, 'Some data and {context}', ['context' => $mock]);
|
||||
|
||||
$entry = $this->getLastEntry();
|
||||
$this->assertEquals('Some data and FooBar', $entry['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testThrowExceptionOnInvalidLevel()
|
||||
{
|
||||
$logger = $this->getLogger();
|
||||
|
||||
$logger->log('This log level should never be defined', 'Some message');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLastEntry()
|
||||
{
|
||||
$entries = LogEntries();
|
||||
$entry = array_pop($entries);
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
LogEntries_clear_all();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
class LogEntriesModelTest extends TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
require_once __DIR__ . '/../../../includes/engelsystem_provider.php';
|
||||
}
|
||||
|
||||
public function testCreateLogEntry()
|
||||
{
|
||||
LogEntries_clear_all();
|
||||
$count = count(LogEntries());
|
||||
$this->assertNotFalse(LogEntry_create(LogLevel::WARNING, 'test_LogEntry_create'));
|
||||
|
||||
// There should be one more log entry now
|
||||
$this->assertEquals(count(LogEntries()), $count + 1);
|
||||
}
|
||||
|
||||
public function testClearAllLogEntries()
|
||||
{
|
||||
LogEntry_create(LogLevel::WARNING, 'test');
|
||||
$this->assertTrue(count(LogEntries()) > 0);
|
||||
|
||||
$this->assertNotFalse(LogEntries_clear_all());
|
||||
$this->assertCount(0, LogEntries());
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
LogEntries_clear_all();
|
||||
}
|
||||
}
|
|
@ -1,13 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test;
|
||||
|
||||
use \PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RoomModelTest extends TestCase
|
||||
{
|
||||
|
||||
private $room_id = null;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
require_once __DIR__ . '/../../../includes/engelsystem_provider.php';
|
||||
}
|
||||
|
||||
public function create_Room()
|
||||
{
|
||||
$this->room_id = Room_create('test', false, true, '');
|
||||
|
@ -16,20 +21,17 @@ class RoomModelTest extends TestCase
|
|||
public function test_Room()
|
||||
{
|
||||
$this->create_Room();
|
||||
|
||||
|
||||
$room = Room($this->room_id);
|
||||
|
||||
|
||||
$this->assertNotFalse($room);
|
||||
$this->assertNotNull($room);
|
||||
$this->assertEquals($room['Name'], 'test');
|
||||
|
||||
$this->assertNull(Room(- 1));
|
||||
|
||||
$this->assertNull(Room(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @after
|
||||
*/
|
||||
public function teardown()
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->room_id != null) {
|
||||
Room_delete($this->room_id);
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Application;
|
||||
use Engelsystem\Container\Container;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class ApplicationTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Application::__construct
|
||||
* @covers \Engelsystem\Application::registerBaseBindings
|
||||
*/
|
||||
public function testConstructor()
|
||||
{
|
||||
$app = new Application();
|
||||
|
||||
$this->assertInstanceOf(Container::class, $app);
|
||||
$this->assertInstanceOf(ContainerInterface::class, $app);
|
||||
$this->assertSame($app, $app->get('app'));
|
||||
$this->assertSame($app, $app->get('container'));
|
||||
$this->assertSame($app, $app->get(Container::class));
|
||||
$this->assertSame($app, $app->get(Application::class));
|
||||
$this->assertSame($app, $app->get(ContainerInterface::class));
|
||||
$this->assertSame($app, Container::getInstance());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Config\Config;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConfigTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::get
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$config->set('test', 'FooBar');
|
||||
$this->assertEquals(['test' => 'FooBar'], $config->get(null));
|
||||
$this->assertEquals('FooBar', $config->get('test'));
|
||||
|
||||
$this->assertEquals('defaultValue', $config->get('notExisting', 'defaultValue'));
|
||||
|
||||
$this->assertNull($config->get('notExisting'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::set
|
||||
*/
|
||||
public function testSet()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$config->set('test', 'FooBar');
|
||||
$this->assertEquals('FooBar', $config->get('test'));
|
||||
|
||||
$config->set([
|
||||
'name' => 'Engelsystem',
|
||||
'mail' => ['user' => 'test'],
|
||||
]);
|
||||
$this->assertEquals('Engelsystem', $config->get('name'));
|
||||
$this->assertEquals(['user' => 'test'], $config->get('mail'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::has
|
||||
*/
|
||||
public function testHas()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$this->assertFalse($config->has('test'));
|
||||
|
||||
$config->set('test', 'FooBar');
|
||||
$this->assertTrue($config->has('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::remove
|
||||
*/
|
||||
public function testRemove()
|
||||
{
|
||||
$config = new Config();
|
||||
$config->set(['foo' => 'bar', 'test' => '123']);
|
||||
|
||||
$config->remove('foo');
|
||||
$this->assertEquals(['test' => '123'], $config->get(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::__get
|
||||
*/
|
||||
public function testMagicGet()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$config->set('test', 'FooBar');
|
||||
$this->assertEquals('FooBar', $config->test);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::__set
|
||||
*/
|
||||
public function testMagicSet()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$config->test = 'FooBar';
|
||||
$this->assertEquals('FooBar', $config->get('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::__isset
|
||||
*/
|
||||
public function testMagicIsset()
|
||||
{
|
||||
$config = new Config();
|
||||
|
||||
$this->assertFalse(isset($config->test));
|
||||
|
||||
$config->set('test', 'FooBar');
|
||||
$this->assertTrue(isset($config->test));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Config\Config::__unset
|
||||
*/
|
||||
public function testMagicUnset()
|
||||
{
|
||||
$config = new Config();
|
||||
$config->set(['foo' => 'bar', 'test' => '123']);
|
||||
|
||||
unset($config->foo);
|
||||
$this->assertEquals(['test' => '123'], $config->get(null));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Container\Container;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ContainerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::get
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$container = new Container();
|
||||
$class = new class
|
||||
{
|
||||
};
|
||||
|
||||
$container->instance('foo', $class);
|
||||
$this->assertSame($class, $container->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::get
|
||||
* @expectedException \Engelsystem\Container\NotFoundException
|
||||
*/
|
||||
public function testGetException()
|
||||
{
|
||||
$container = new Container();
|
||||
|
||||
$container->get('not.registered.service');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::instance
|
||||
* @covers \Engelsystem\Container\Container::resolve
|
||||
*/
|
||||
public function testInstance()
|
||||
{
|
||||
$container = new Container();
|
||||
$class = new class
|
||||
{
|
||||
};
|
||||
|
||||
$container->instance('foo', $class);
|
||||
$this->assertSame($class, $container->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::has
|
||||
*/
|
||||
public function testHas()
|
||||
{
|
||||
$container = new Container();
|
||||
|
||||
$this->assertFalse($container->has('test'));
|
||||
|
||||
$class = new class
|
||||
{
|
||||
};
|
||||
|
||||
$container->instance('test', $class);
|
||||
$this->assertTrue($container->has('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::singleton
|
||||
*/
|
||||
public function testSingleton()
|
||||
{
|
||||
$container = new Container();
|
||||
$class = new class
|
||||
{
|
||||
};
|
||||
|
||||
$container->singleton('foo', $class);
|
||||
$this->assertSame($class, $container->get('foo'));
|
||||
$this->assertSame($class, $container->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Container\Container::setInstance
|
||||
* @covers \Engelsystem\Container\Container::getInstance
|
||||
*/
|
||||
public function testContainerSingleton()
|
||||
{
|
||||
// Ensure that no container has been initialized
|
||||
$reflection = new \ReflectionProperty(Container::class, 'instance');
|
||||
$reflection->setAccessible(true);
|
||||
$reflection->setValue(null, null);
|
||||
$reflection->setAccessible(false);
|
||||
|
||||
$container0 = new Container();
|
||||
$container = Container::getInstance();
|
||||
|
||||
$this->assertNotSame($container0, $container);
|
||||
|
||||
$container1 = new Container;
|
||||
Container::setInstance($container1);
|
||||
|
||||
$this->assertSame($container1, Container::getInstance());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Application;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Container\Container;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Renderer\Renderer;
|
||||
use Engelsystem\Routing\UrlGenerator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
class HelpersTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers \app
|
||||
*/
|
||||
public function testApp()
|
||||
{
|
||||
$class = new class
|
||||
{
|
||||
};
|
||||
|
||||
$appMock = $this->getAppMock('some.name', $class);
|
||||
|
||||
$this->assertEquals($appMock, app());
|
||||
$this->assertEquals($class, app('some.name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \config
|
||||
*/
|
||||
public function testConfig()
|
||||
{
|
||||
$configMock = $this->getMockBuilder(Config::class)
|
||||
->getMock();
|
||||
|
||||
$this->getAppMock('config', $configMock);
|
||||
$this->assertEquals($configMock, config());
|
||||
|
||||
$configMock->expects($this->once())
|
||||
->method('set')
|
||||
->with(['foo' => 'bar']);
|
||||
|
||||
$this->assertTrue(config(['foo' => 'bar']));
|
||||
|
||||
$configMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('mail')
|
||||
->willReturn(['user' => 'FooBar']);
|
||||
|
||||
$this->assertEquals(['user' => 'FooBar'], config('mail'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \request
|
||||
*/
|
||||
public function testRequest()
|
||||
{
|
||||
$requestMock = $this->getMockBuilder(Request::class)
|
||||
->getMock();
|
||||
|
||||
$this->getAppMock('request', $requestMock);
|
||||
$this->assertEquals($requestMock, request());
|
||||
|
||||
$requestMock->expects($this->once())
|
||||
->method('input')
|
||||
->with('requestKey')
|
||||
->willReturn('requestValue');
|
||||
|
||||
$this->assertEquals('requestValue', request('requestKey'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \session
|
||||
*/
|
||||
public function testSession()
|
||||
{
|
||||
$sessionMock = $this->getMockBuilder(Session::class)
|
||||
->getMock();
|
||||
|
||||
$this->getAppMock('session', $sessionMock);
|
||||
$this->assertEquals($sessionMock, session());
|
||||
|
||||
$sessionMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('someKey')
|
||||
->willReturn('someValue');
|
||||
|
||||
$this->assertEquals('someValue', session('someKey'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \view
|
||||
*/
|
||||
public function testView()
|
||||
{
|
||||
$rendererMock = $this->getMockBuilder(Renderer::class)
|
||||
->getMock();
|
||||
|
||||
$this->getAppMock('renderer', $rendererMock);
|
||||
$this->assertEquals($rendererMock, view());
|
||||
|
||||
$rendererMock->expects($this->once())
|
||||
->method('render')
|
||||
->with('template.name', ['template' => 'data'])
|
||||
->willReturn('rendered template');
|
||||
|
||||
$this->assertEquals('rendered template', view('template.name', ['template' => 'data']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \url
|
||||
*/
|
||||
public function testUrl()
|
||||
{
|
||||
$urlGeneratorMock = $this->getMockBuilder(UrlGenerator::class)
|
||||
->getMock();
|
||||
|
||||
$this->getAppMock('routing.urlGenerator', $urlGeneratorMock);
|
||||
$this->assertEquals($urlGeneratorMock, url());
|
||||
|
||||
$urlGeneratorMock->expects($this->once())
|
||||
->method('to')
|
||||
->with('foo/bar', ['param' => 'value'])
|
||||
->willReturn('http://lorem.ipsum/foo/bar?param=value');
|
||||
|
||||
$this->assertEquals('http://lorem.ipsum/foo/bar?param=value', url('foo/bar', ['param' => 'value']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @param object $object
|
||||
* @return Application|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function getAppMock($alias, $object)
|
||||
{
|
||||
$appMock = $this->getMockBuilder(Container::class)
|
||||
->getMock();
|
||||
|
||||
$appMock->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->with($alias)
|
||||
->willReturn($object);
|
||||
|
||||
/** @var $appMock Application */
|
||||
Application::setInstance($appMock);
|
||||
|
||||
return $appMock;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Renderer\HtmlEngine;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class HtmlEngineTest extends TestCase
|
||||
{
|
||||
/** @var string[] */
|
||||
protected $tmpFileNames = [];
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Renderer\HtmlEngine::get
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$engine = new HtmlEngine();
|
||||
|
||||
$file = $this->createTempFile('<div>%main_content%</div>');
|
||||
|
||||
$data = $engine->get($file, ['main_content' => 'Lorem ipsum dolor sit']);
|
||||
$this->assertEquals('<div>Lorem ipsum dolor sit</div>', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Renderer\HtmlEngine::canRender
|
||||
*/
|
||||
public function testCanRender()
|
||||
{
|
||||
$engine = new HtmlEngine();
|
||||
|
||||
$this->assertFalse($engine->canRender('/dev/null'));
|
||||
|
||||
$file = $this->createTempFile();
|
||||
$this->assertTrue($engine->canRender($file));
|
||||
|
||||
$htmFile = $this->createTempFile('', '.htm');
|
||||
$this->assertTrue($engine->canRender($htmFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @param string $extension
|
||||
* @return string
|
||||
*/
|
||||
protected function createTempFile($content = '', $extension = '.html')
|
||||
{
|
||||
$tmpFileName = tempnam(sys_get_temp_dir(), 'EngelsystemUnitTest');
|
||||
|
||||
$fileName = $tmpFileName . $extension;
|
||||
rename($tmpFileName, $fileName);
|
||||
|
||||
file_put_contents($fileName, $content);
|
||||
|
||||
$this->tmpFileNames[] = $fileName;
|
||||
|
||||
return $fileName;
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
foreach ($this->tmpFileNames as $fileName) {
|
||||
unlink($fileName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Renderer\EngineInterface;
|
||||
use Engelsystem\Renderer\Renderer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class RendererTest extends TestCase
|
||||
{
|
||||
public function testGet()
|
||||
{
|
||||
$renderer = new Renderer();
|
||||
|
||||
$nullRenderer = $this->getMockForAbstractClass(EngineInterface::class);
|
||||
|
||||
$nullRenderer->expects($this->atLeastOnce())
|
||||
->method('canRender')
|
||||
->willReturn(false);
|
||||
$renderer->addRenderer($nullRenderer);
|
||||
|
||||
$mockRenderer = $this->getMockForAbstractClass(EngineInterface::class);
|
||||
|
||||
$mockRenderer->expects($this->atLeastOnce())
|
||||
->method('canRender')
|
||||
->with('foo.template')
|
||||
->willReturn(true);
|
||||
|
||||
$mockRenderer->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->with('foo.template', ['lorem' => 'ipsum'])
|
||||
->willReturn('Rendered content');
|
||||
|
||||
$renderer->addRenderer($mockRenderer);
|
||||
$data = $renderer->render('foo.template', ['lorem' => 'ipsum']);
|
||||
|
||||
$this->assertEquals('Rendered content', $data);
|
||||
}
|
||||
|
||||
public function testError()
|
||||
{
|
||||
$renderer = new Renderer();
|
||||
|
||||
$loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
|
||||
$loggerMock
|
||||
->expects($this->once())
|
||||
->method('error');
|
||||
|
||||
$renderer->setLogger($loggerMock);
|
||||
|
||||
$data = $renderer->render('testing.template');
|
||||
$this->assertEquals('', $data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Config;
|
||||
|
||||
use Engelsystem\Application;
|
||||
use Engelsystem\Container\Container;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Routing\UrlGenerator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class UrlGeneratorTest extends TestCase
|
||||
{
|
||||
public function provideLinksTo()
|
||||
{
|
||||
return [
|
||||
['/foo/path', '/foo/path', 'http://foo.bar/foo/path', [], 'http://foo.bar/foo/path'],
|
||||
['foo', '/foo', 'https://foo.bar/foo', [], 'https://foo.bar/foo'],
|
||||
['foo', '/foo', 'http://f.b/foo', ['test' => 'abc', 'bla' => 'foo'], 'http://f.b/foo?test=abc&bla=foo'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideLinksTo
|
||||
* @covers \Engelsystem\Routing\UrlGenerator::to
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $willReturn
|
||||
* @param string $urlToPath
|
||||
* @param string[] $arguments
|
||||
* @param string $expectedUrl
|
||||
*/
|
||||
public function testTo($urlToPath, $path, $willReturn, $arguments, $expectedUrl)
|
||||
{
|
||||
$app = new Container();
|
||||
$urlGenerator = new UrlGenerator();
|
||||
Application::setInstance($app);
|
||||
|
||||
$request = $this->getMockBuilder(Request::class)
|
||||
->getMock();
|
||||
|
||||
$request->expects($this->once())
|
||||
->method('getUriForPath')
|
||||
->with($path)
|
||||
->willReturn($willReturn);
|
||||
|
||||
$app->instance('request', $request);
|
||||
|
||||
$url = $urlGenerator->to($urlToPath, $arguments);
|
||||
$this->assertEquals($expectedUrl, $url);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue