Unified user notifications
This commit is contained in:
parent
1fe30fc82f
commit
713f8222e4
|
@ -88,7 +88,7 @@ function angeltype_delete_controller()
|
|||
if (request()->hasPostData('delete')) {
|
||||
$angeltype->delete();
|
||||
engelsystem_log('Deleted angeltype: ' . AngelType_name_render($angeltype, true));
|
||||
success(sprintf(__('Angeltype %s deleted.'), AngelType_name_render($angeltype)));
|
||||
success(sprintf(__('Angeltype %s deleted.'), $angeltype->name));
|
||||
throw_redirect(page_link_to('angeltypes'));
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype
|
|||
$shiftEntry->save();
|
||||
ShiftEntry_onCreate($shiftEntry);
|
||||
|
||||
success(sprintf(__('%s has been subscribed to the shift.'), User_Nick_render($signup_user)));
|
||||
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->name));
|
||||
throw_redirect(shift_link($shift));
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ function shift_entry_create_controller_supporter(Shift $shift, AngelType $angelt
|
|||
$shiftEntry->save();
|
||||
ShiftEntry_onCreate($shiftEntry);
|
||||
|
||||
success(sprintf(__('%s has been subscribed to the shift.'), User_Nick_render($signup_user)));
|
||||
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->name));
|
||||
throw_redirect(shift_link($shift));
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ function user_angeltypes_delete_all_controller(): array
|
|||
->delete();
|
||||
|
||||
engelsystem_log(sprintf('Denied all users for angeltype %s', AngelType_name_render($angeltype, true)));
|
||||
success(sprintf(__('Denied all users for angeltype %s.'), AngelType_name_render($angeltype)));
|
||||
success(sprintf(__('Denied all users for angeltype %s.'), $angeltype->name));
|
||||
throw_redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]));
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ function user_angeltypes_confirm_all_controller(): array
|
|||
->update(['confirm_user_id' => $user->id]);
|
||||
|
||||
engelsystem_log(sprintf('Confirmed all users for angeltype %s', AngelType_name_render($angeltype, true)));
|
||||
success(sprintf(__('Confirmed all users for angeltype %s.'), AngelType_name_render($angeltype)));
|
||||
success(sprintf(__('Confirmed all users for angeltype %s.'), $angeltype->name));
|
||||
|
||||
foreach ($users as $user) {
|
||||
user_angeltype_confirm_email($user, $angeltype);
|
||||
|
@ -169,11 +169,7 @@ function user_angeltype_confirm_controller(): array
|
|||
User_Nick_render($user_source, true),
|
||||
AngelType_name_render($angeltype, true)
|
||||
));
|
||||
success(sprintf(
|
||||
__('%s confirmed for angeltype %s.'),
|
||||
User_Nick_render($user_source),
|
||||
AngelType_name_render($angeltype)
|
||||
));
|
||||
success(sprintf(__('%s confirmed for angeltype %s.'), $user_source->name, $angeltype->name));
|
||||
|
||||
user_angeltype_confirm_email($user_source, $angeltype);
|
||||
|
||||
|
@ -268,7 +264,7 @@ function user_angeltype_delete_controller(): array
|
|||
$user_angeltype->delete();
|
||||
|
||||
engelsystem_log(sprintf('User %s removed from %s.', User_Nick_render($user_source, true), $angeltype->name));
|
||||
success(sprintf(__('User %s removed from %s.'), User_Nick_render($user_source), $angeltype->name));
|
||||
success(sprintf(__('User %s removed from %s.'), $user_source->name, $angeltype->name));
|
||||
|
||||
throw_redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]));
|
||||
}
|
||||
|
@ -323,11 +319,7 @@ function user_angeltype_update_controller(): array
|
|||
AngelType_name_render($angeltype, true),
|
||||
User_Nick_render($user_source, true)
|
||||
));
|
||||
success(sprintf(
|
||||
$msg,
|
||||
AngelType_name_render($angeltype),
|
||||
User_Nick_render($user_source)
|
||||
));
|
||||
success(sprintf($msg, $angeltype->name, $user_source->name));
|
||||
|
||||
throw_redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]));
|
||||
}
|
||||
|
@ -375,11 +367,7 @@ function user_angeltype_add_controller(): array
|
|||
User_Nick_render($user_source, true),
|
||||
AngelType_name_render($angeltype, true)
|
||||
));
|
||||
success(sprintf(
|
||||
__('User %s added to %s.'),
|
||||
User_Nick_render($user_source),
|
||||
AngelType_name_render($angeltype)
|
||||
));
|
||||
success(sprintf(__('User %s added to %s.'), $user_source->name, $angeltype->name));
|
||||
|
||||
if ($request->hasPostData('auto_confirm_user')) {
|
||||
$userAngelType->confirmUser()->associate($user_source);
|
||||
|
|
|
@ -48,7 +48,7 @@ function engelsystem_email_to_user($recipientUser, $title, $message, $notIfItsMe
|
|||
$translator->setLocale($locale);
|
||||
|
||||
if (!$status) {
|
||||
error(sprintf(__('User %s could not be notified by email due to an error.'), User_Nick_render($recipientUser)));
|
||||
error(sprintf(__('User %s could not be notified by email due to an error.'), $recipientUser->name));
|
||||
engelsystem_log(sprintf('User %s could not be notified by email due to an error.', $recipientUser->name));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,15 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
|
||||
/**
|
||||
* Returns messages from session and removes them from the stack
|
||||
* @param bool $includeMessagesFromNewProcedure
|
||||
* If set, the messages from the new procedure are also included.
|
||||
* The output will be similar to how it would be with messages.twig.
|
||||
* @see \Engelsystem\Controllers\HasUserNotifications
|
||||
* Returns messages from session and removes them from the stack by rendering the messages twig template
|
||||
* @return string
|
||||
* @see \Engelsystem\Controllers\HasUserNotifications
|
||||
*/
|
||||
function msg(bool $includeMessagesFromNewProcedure = false)
|
||||
function msg()
|
||||
{
|
||||
$session = session();
|
||||
|
||||
$message = $session->get('msg', '');
|
||||
$session->set('msg', '');
|
||||
|
||||
if ($includeMessagesFromNewProcedure) {
|
||||
foreach (session()->get('errors', []) as $msg) {
|
||||
$message .= error(__($msg), true);
|
||||
}
|
||||
foreach (session()->get('warnings', []) as $msg) {
|
||||
$message .= warning(__($msg), true);
|
||||
}
|
||||
foreach (session()->get('information', []) as $msg) {
|
||||
$message .= info(__($msg), true);
|
||||
}
|
||||
foreach (session()->get('messages', []) as $msg) {
|
||||
$message .= success(__($msg), true);
|
||||
}
|
||||
|
||||
foreach (['errors', 'warnings', 'information', 'messages'] as $type) {
|
||||
session()->remove($type);
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
return view('layouts/parts/messages.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,7 +21,7 @@ function msg(bool $includeMessagesFromNewProcedure = false)
|
|||
*/
|
||||
function info($msg, $immediately = false)
|
||||
{
|
||||
return alert('info', $msg, $immediately);
|
||||
return alert(NotificationType::INFORMATION, $msg, $immediately);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +33,7 @@ function info($msg, $immediately = false)
|
|||
*/
|
||||
function warning($msg, $immediately = false)
|
||||
{
|
||||
return alert('warning', $msg, $immediately);
|
||||
return alert(NotificationType::WARNING, $msg, $immediately);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +45,7 @@ function warning($msg, $immediately = false)
|
|||
*/
|
||||
function error($msg, $immediately = false)
|
||||
{
|
||||
return alert('danger', $msg, $immediately);
|
||||
return alert(NotificationType::ERROR, $msg, $immediately);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,31 +57,44 @@ function error($msg, $immediately = false)
|
|||
*/
|
||||
function success($msg, $immediately = false)
|
||||
{
|
||||
return alert('success', $msg, $immediately);
|
||||
return alert(NotificationType::MESSAGE, $msg, $immediately);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an alert message with the given alert-* class.
|
||||
* Renders an alert message with the given alert-* class or sets it in session
|
||||
*
|
||||
* @param string $class
|
||||
* @see \Engelsystem\Controllers\HasUserNotifications
|
||||
*
|
||||
* @param NotificationType $type
|
||||
* @param string $msg
|
||||
* @param bool $immediately
|
||||
* @return string
|
||||
*/
|
||||
function alert($class, $msg, $immediately = false)
|
||||
function alert(NotificationType $type, $msg, $immediately = false)
|
||||
{
|
||||
if (empty($msg)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($immediately) {
|
||||
return '<div class="alert alert-' . $class . '" role="alert">' . $msg . '</div>';
|
||||
$type = str_replace(
|
||||
[
|
||||
NotificationType::ERROR->value,
|
||||
NotificationType::WARNING->value,
|
||||
NotificationType::INFORMATION->value,
|
||||
NotificationType::MESSAGE->value,
|
||||
],
|
||||
['danger', 'warning', 'info', 'success'],
|
||||
$type->value
|
||||
);
|
||||
return '<div class="alert alert-' . $type . '" role="alert">' . $msg . '</div>';
|
||||
}
|
||||
|
||||
$type = 'messages.' . $type->value;
|
||||
$session = session();
|
||||
$message = $session->get('msg', '');
|
||||
$message .= alert($class, $msg, true);
|
||||
$session->set('msg', $message);
|
||||
$messages = $session->get($type, []);
|
||||
$messages[] = $msg;
|
||||
$session->set($type, $messages);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ function admin_shifts()
|
|||
}
|
||||
|
||||
// Load angeltypes
|
||||
/** @var AngelType[] $types */
|
||||
$types = AngelType::all();
|
||||
$needed_angel_types = [];
|
||||
foreach ($types as $type) {
|
||||
|
|
|
@ -121,7 +121,7 @@ function guest_register()
|
|||
}
|
||||
if (User::whereName($nick)->count() > 0) {
|
||||
$valid = false;
|
||||
$msg .= error(sprintf(__('Your nick "%s" already exists.'), $nick), true);
|
||||
$msg .= error(sprintf(__('Your nick "%s" already exists.'), htmlspecialchars($nick)), true);
|
||||
}
|
||||
} else {
|
||||
$valid = false;
|
||||
|
@ -330,8 +330,8 @@ function guest_register()
|
|||
}
|
||||
|
||||
// If a welcome message is present, display it on the next page
|
||||
if ($message = $config->get('welcome_msg')) {
|
||||
info((new Parsedown())->text($message));
|
||||
if ($config->get('welcome_msg')) {
|
||||
$session->set('show_welcome', true);
|
||||
}
|
||||
|
||||
// Login the user
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers\Admin\Schedule;
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use DateTimeInterface;
|
||||
use Engelsystem\Controllers\BaseController;
|
||||
|
@ -83,7 +84,7 @@ class ImportSchedule extends BaseController
|
|||
[
|
||||
'is_index' => true,
|
||||
'schedules' => ScheduleUrl::all(),
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -98,7 +99,7 @@ class ImportSchedule extends BaseController
|
|||
[
|
||||
'schedule' => $schedule,
|
||||
'shift_types' => ShiftType::all()->pluck('name', 'id'),
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,7 @@ class ImportSchedule extends BaseController
|
|||
$schedule
|
||||
) = $this->getScheduleData($request);
|
||||
} catch (ErrorException $e) {
|
||||
$this->addNotification($e->getMessage(), 'errors');
|
||||
$this->addNotification($e->getMessage(), NotificationType::ERROR);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,7 @@ class ImportSchedule extends BaseController
|
|||
'update' => $changeEvents,
|
||||
'delete' => $deleteEvents,
|
||||
],
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -210,7 +211,7 @@ class ImportSchedule extends BaseController
|
|||
$scheduleUrl
|
||||
) = $this->getScheduleData($request);
|
||||
} catch (ErrorException $e) {
|
||||
$this->addNotification($e->getMessage(), 'errors');
|
||||
$this->addNotification($e->getMessage(), NotificationType::ERROR);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
@ -250,8 +251,8 @@ class ImportSchedule extends BaseController
|
|||
$scheduleUrl->touch();
|
||||
$this->log('Ended schedule "{name}" import', ['name' => $scheduleUrl->name]);
|
||||
|
||||
return redirect($this->url, 303)
|
||||
->with('messages', ['schedule.import.success']);
|
||||
$this->addNotification('schedule.import.success');
|
||||
return redirect($this->url, 303);
|
||||
}
|
||||
|
||||
protected function createRoom(Room $room): void
|
||||
|
|
|
@ -126,7 +126,7 @@ function ShiftEntry_create_view_supporter(Shift $shift, Room $room, AngelType $a
|
|||
Shift_view_header($shift, $room),
|
||||
info(sprintf(
|
||||
__('Do you want to sign up the following user for this shift as %s?'),
|
||||
AngelType_name_render($angeltype)
|
||||
$angeltype->name
|
||||
), true),
|
||||
form([
|
||||
form_select('user_id', __('User'), $users_select, $signup_user->id),
|
||||
|
@ -153,7 +153,7 @@ function ShiftEntry_create_view_user(Shift $shift, Room $room, AngelType $angelt
|
|||
. ' <small title="' . $start . '" data-countdown-ts="' . $shift->start->timestamp . '">%c</small>',
|
||||
[
|
||||
Shift_view_header($shift, $room),
|
||||
info(sprintf(__('Do you want to sign up for this shift as %s?'), AngelType_name_render($angeltype)), true),
|
||||
info(sprintf(__('Do you want to sign up for this shift as %s?'), $angeltype->name), true),
|
||||
form([
|
||||
form_textarea('comment', __('Comment (for your eyes only):'), $comment),
|
||||
form_submit('submit', icon('check-lg') . __('Save')),
|
||||
|
|
|
@ -20,7 +20,7 @@ function UserAngelType_update_view(UserAngelType $user_angeltype, User $user, An
|
|||
? __('Do you really want to add supporter rights for %s to %s?')
|
||||
: __('Do you really want to remove supporter rights for %s from %s?'),
|
||||
$angeltype->name,
|
||||
User_Nick_render($user)
|
||||
$user->name
|
||||
), true),
|
||||
form([
|
||||
buttons([
|
||||
|
@ -92,7 +92,7 @@ function UserAngelType_confirm_view(UserAngelType $user_angeltype, User $user, A
|
|||
msg(),
|
||||
info(sprintf(
|
||||
__('Do you really want to confirm %s for %s?'),
|
||||
User_Nick_render($user),
|
||||
$user->name,
|
||||
$angeltype->name
|
||||
), true),
|
||||
form([
|
||||
|
@ -116,7 +116,7 @@ function UserAngelType_delete_view(UserAngelType $user_angeltype, User $user, An
|
|||
msg(),
|
||||
info(sprintf(
|
||||
__('Do you really want to delete %s from %s?'),
|
||||
User_Nick_render($user),
|
||||
$user->name,
|
||||
$angeltype->name
|
||||
), true),
|
||||
form([
|
||||
|
@ -170,7 +170,7 @@ function UserAngelType_join_view($user, AngelType $angeltype)
|
|||
msg(),
|
||||
info(sprintf(
|
||||
__('Do you really want to add %s to %s?'),
|
||||
User_Nick_render($user),
|
||||
$user->name,
|
||||
$angeltype->name
|
||||
), true),
|
||||
form([
|
||||
|
|
|
@ -534,7 +534,7 @@ function User_view(
|
|||
. htmlspecialchars($user_source->name)
|
||||
. (config('enable_user_name') ? ' <small>' . $user_name . '</small>' : ''),
|
||||
[
|
||||
msg(true),
|
||||
msg(),
|
||||
div('row', [
|
||||
div('col-md-12', [
|
||||
buttons([
|
||||
|
|
|
@ -1545,8 +1545,8 @@ msgstr ""
|
|||
|
||||
#: includes/pages/guest_login.php:82
|
||||
#, php-format
|
||||
msgid "Your nick "%s" already exists."
|
||||
msgstr "Der Nick "%s" existiert schon."
|
||||
msgid "Your nick \"%s\" already exists."
|
||||
msgstr "Der Nick \"%s\" existiert bereits."
|
||||
|
||||
#: includes/pages/guest_login.php:86
|
||||
msgid "Please enter a nickname."
|
||||
|
|
|
@ -1296,8 +1296,8 @@ msgstr "Logout"
|
|||
|
||||
#: includes/pages/guest_login.php:56
|
||||
#, php-format
|
||||
msgid "Your nick "%s" already exists."
|
||||
msgstr "Seu apelido "%s" já existe."
|
||||
msgid "Your nick \"%s\" already exists."
|
||||
msgstr "Seu apelido \"%s\" já existe."
|
||||
|
||||
#: includes/pages/guest_login.php:60
|
||||
#, php-format
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
{% import 'macros/base.twig' as m %}
|
||||
|
||||
{{ msg() }}
|
||||
|
||||
{% for message in errors|default([]) %}
|
||||
{% for message in notifications('error') %}
|
||||
{{ m.alert(__(message), 'danger') }}
|
||||
{% endfor %}
|
||||
|
||||
{% for message in warnings|default([]) %}
|
||||
{% for message in notifications('warning') %}
|
||||
{{ m.alert(__(message), 'warning') }}
|
||||
{% endfor %}
|
||||
|
||||
{% for message in information|default([]) %}
|
||||
{% for message in notifications('information') %}
|
||||
{{ m.alert(__(message), 'info') }}
|
||||
{% endfor %}
|
||||
|
||||
{% for message in messages|default([]) %}
|
||||
{% for message in notifications('message') %}
|
||||
{{ m.alert(__(message), 'success') }}
|
||||
{% endfor %}
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
<div class="card-body">
|
||||
{% include 'layouts/parts/messages.twig' %}
|
||||
|
||||
{% if session_get('show_welcome', false) %}
|
||||
{{ m.alert(config('welcome_msg') | md, null, true) }}
|
||||
{% endif %}
|
||||
|
||||
<form action="" enctype="multipart/form-data" method="post">
|
||||
{{ csrf() }}
|
||||
<div class="mb-3">
|
||||
|
|
|
@ -83,7 +83,7 @@ class FaqController extends BaseController
|
|||
{
|
||||
return $this->response->withView(
|
||||
'pages/faq/edit.twig',
|
||||
['faq' => $faq] + $this->getNotifications()
|
||||
['faq' => $faq]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class NewsController extends BaseController
|
|||
'news' => $news,
|
||||
'is_meeting' => $news ? $news->is_meeting : $isMeetingDefault,
|
||||
'is_pinned' => $news ? $news->is_pinned : false,
|
||||
] + $this->getNotifications(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class QuestionsController extends BaseController
|
|||
|
||||
return $this->response->withView(
|
||||
'pages/questions/overview.twig',
|
||||
['questions' => $questions, 'is_admin' => true] + $this->getNotifications()
|
||||
['questions' => $questions, 'is_admin' => true]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ class QuestionsController extends BaseController
|
|||
{
|
||||
return $this->response->withView(
|
||||
'pages/questions/edit.twig',
|
||||
['question' => $question, 'is_admin' => true] + $this->getNotifications()
|
||||
['question' => $question, 'is_admin' => true]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class UserShirtController extends BaseController
|
|||
|
||||
return $this->response->withView(
|
||||
'admin/user/edit-shirt.twig',
|
||||
['userdata' => $user] + $this->getNotifications()
|
||||
['userdata' => $user]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ class UserWorkLogController extends BaseController
|
|||
'work_hours' => $work_hours,
|
||||
'comment' => $comment,
|
||||
'is_edit' => $is_edit,
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,7 @@ class AuthController extends BaseController
|
|||
|
||||
protected function showLogin(): Response
|
||||
{
|
||||
return $this->response->withView(
|
||||
'pages/login',
|
||||
$this->getNotifications()
|
||||
);
|
||||
return $this->response->withView('pages/login');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +55,7 @@ class AuthController extends BaseController
|
|||
$user = $this->auth->authenticate($data['login'], $data['password']);
|
||||
|
||||
if (!$user instanceof User) {
|
||||
$this->addNotification('auth.not-found', 'errors');
|
||||
$this->addNotification('auth.not-found', NotificationType::ERROR);
|
||||
|
||||
return $this->showLogin();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class FaqController extends BaseController
|
|||
|
||||
return $this->response->withView(
|
||||
'pages/faq/overview.twig',
|
||||
['text' => $text, 'items' => $faq] + $this->getNotifications()
|
||||
['text' => $text, 'items' => $faq]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,25 +4,40 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
trait HasUserNotifications
|
||||
{
|
||||
protected function addNotification(string|array $value, string $type = 'messages'): void
|
||||
protected function addNotification(string|array $value, NotificationType $type = NotificationType::MESSAGE): void
|
||||
{
|
||||
$type = 'messages.' . $type->value;
|
||||
session()->set(
|
||||
$type,
|
||||
array_merge(session()->get($type, []), [$value])
|
||||
array_merge_recursive(session()->get($type, []), (array) $value)
|
||||
);
|
||||
}
|
||||
|
||||
protected function getNotifications(): array
|
||||
/**
|
||||
* @param NotificationType[]|null $types
|
||||
* @return array<string,Collection|array<string>>
|
||||
*/
|
||||
protected function getNotifications(array $types = null): array
|
||||
{
|
||||
$return = [];
|
||||
foreach (['errors', 'warnings', 'information', 'messages'] as $type) {
|
||||
$return[$type] = Collection::make(Arr::flatten(session()->get($type, [])));
|
||||
session()->remove($type);
|
||||
$types = $types ?: [
|
||||
NotificationType::ERROR,
|
||||
NotificationType::WARNING,
|
||||
NotificationType::INFORMATION,
|
||||
NotificationType::MESSAGE,
|
||||
];
|
||||
|
||||
foreach ($types as $type) {
|
||||
$type = $type->value;
|
||||
$path = 'messages.' . $type;
|
||||
$return[$type] = Collection::make(
|
||||
session()->get($path, [])
|
||||
)->flatten();
|
||||
session()->remove($path);
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
|
|
@ -157,8 +157,6 @@ class NewsController extends BaseController
|
|||
*/
|
||||
protected function renderView(string $page, array $data): Response
|
||||
{
|
||||
$data += $this->getNotifications();
|
||||
|
||||
return $this->response->withView($page, $data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers;
|
||||
|
||||
enum NotificationType: string
|
||||
{
|
||||
case ERROR = 'error';
|
||||
case WARNING = 'warning';
|
||||
case INFORMATION = 'information';
|
||||
case MESSAGE = 'message';
|
||||
}
|
|
@ -88,7 +88,7 @@ class PasswordResetController extends BaseController
|
|||
]);
|
||||
|
||||
if ($data['password'] !== $data['password_confirmation']) {
|
||||
$this->addNotification('validation.password.confirmed', 'errors');
|
||||
$this->addNotification('validation.password.confirmed', NotificationType::ERROR);
|
||||
|
||||
return $this->showView('pages/password/reset-form');
|
||||
}
|
||||
|
@ -101,10 +101,7 @@ class PasswordResetController extends BaseController
|
|||
|
||||
protected function showView(string $view = 'pages/password/reset', array $data = []): Response
|
||||
{
|
||||
return $this->response->withView(
|
||||
$view,
|
||||
array_merge_recursive($this->getNotifications(), $data)
|
||||
);
|
||||
return $this->response->withView($view, $data);
|
||||
}
|
||||
|
||||
protected function requireToken(Request $request): PasswordReset
|
||||
|
|
|
@ -40,7 +40,7 @@ class QuestionsController extends BaseController
|
|||
|
||||
return $this->response->withView(
|
||||
'pages/questions/overview.twig',
|
||||
['questions' => $questions] + $this->getNotifications()
|
||||
['questions' => $questions]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class QuestionsController extends BaseController
|
|||
{
|
||||
return $this->response->withView(
|
||||
'pages/questions/edit.twig',
|
||||
['question' => null] + $this->getNotifications()
|
||||
['question' => null]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class SettingsController extends BaseController
|
|||
[
|
||||
'settings_menu' => $this->settingsMenu(),
|
||||
'user' => $user,
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,10 @@ class SettingsController extends BaseController
|
|||
|
||||
if (config('enable_planned_arrival')) {
|
||||
if (!$this->isArrivalDateValid($data['planned_arrival_date'], $data['planned_departure_date'])) {
|
||||
$this->addNotification('settings.profile.planned_arrival_date.invalid', 'errors');
|
||||
$this->addNotification('settings.profile.planned_arrival_date.invalid', NotificationType::ERROR);
|
||||
return $this->redirect->to('/settings/profile');
|
||||
} elseif (!$this->isDepartureDateValid($data['planned_arrival_date'], $data['planned_departure_date'])) {
|
||||
$this->addNotification('settings.profile.planned_departure_date.invalid', 'errors');
|
||||
$this->addNotification('settings.profile.planned_departure_date.invalid', NotificationType::ERROR);
|
||||
return $this->redirect->to('/settings/profile');
|
||||
} else {
|
||||
$user->personalData->planned_arrival_date = $data['planned_arrival_date'];
|
||||
|
@ -115,7 +115,7 @@ class SettingsController extends BaseController
|
|||
[
|
||||
'settings_menu' => $this->settingsMenu(),
|
||||
'min_length' => config('min_password_length'),
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -131,9 +131,9 @@ class SettingsController extends BaseController
|
|||
]);
|
||||
|
||||
if (!empty($user->password) && !$this->auth->verifyPassword($user, $data['password'])) {
|
||||
$this->addNotification('auth.password.error', 'errors');
|
||||
$this->addNotification('auth.password.error', NotificationType::ERROR);
|
||||
} elseif ($data['new_password'] != $data['new_password2']) {
|
||||
$this->addNotification('validation.password.confirmed', 'errors');
|
||||
$this->addNotification('validation.password.confirmed', NotificationType::ERROR);
|
||||
} else {
|
||||
$this->auth->setPassword($user, $data['new_password']);
|
||||
|
||||
|
@ -158,7 +158,7 @@ class SettingsController extends BaseController
|
|||
'settings_menu' => $this->settingsMenu(),
|
||||
'themes' => $themes,
|
||||
'current_theme' => $currentTheme,
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ class SettingsController extends BaseController
|
|||
'settings_menu' => $this->settingsMenu(),
|
||||
'languages' => $languages,
|
||||
'current_language' => $currentLanguage,
|
||||
] + $this->getNotifications()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ class SettingsController extends BaseController
|
|||
[
|
||||
'settings_menu' => $this->settingsMenu(),
|
||||
'providers' => $providers,
|
||||
] + $this->getNotifications(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Middleware;
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Http\Exceptions\HttpException;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Request;
|
||||
|
@ -55,7 +56,10 @@ class ErrorHandler implements MiddlewareInterface
|
|||
$response = $this->createResponse($e->getMessage(), $e->getStatusCode(), $e->getHeaders());
|
||||
} catch (ValidationException $e) {
|
||||
$response = $this->redirectBack();
|
||||
$response->with('errors', ['validation' => $e->getValidator()->getErrors()]);
|
||||
$response->with(
|
||||
'messages.' . NotificationType::ERROR->value,
|
||||
['validation' => $e->getValidator()->getErrors()]
|
||||
);
|
||||
|
||||
if ($request instanceof Request) {
|
||||
$response->withInput(Arr::except($request->request->all(), $this->formIgnore));
|
||||
|
|
|
@ -26,7 +26,6 @@ class Legacy extends TwigExtension
|
|||
new TwigFunction('menuUserHints', 'header_render_hints', $isSafeHtml),
|
||||
new TwigFunction('menuLanguages', 'make_language_select', $isSafeHtml),
|
||||
new TwigFunction('page', [$this, 'getPage']),
|
||||
new TwigFunction('msg', 'msg', $isSafeHtml),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Renderer\Twig\Extensions;
|
||||
|
||||
use Engelsystem\Controllers\HasUserNotifications;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
|
||||
use Twig\Extension\AbstractExtension as TwigExtension;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class Notification extends TwigExtension
|
||||
{
|
||||
use HasUserNotifications;
|
||||
|
||||
public function __construct(protected SymfonySession $session)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TwigFunction[]
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
new TwigFunction('notifications', [$this, 'notifications']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Collection[]
|
||||
*/
|
||||
public function notifications(string $type = null): Collection
|
||||
{
|
||||
$types = $type ? [NotificationType::from($type)] : null;
|
||||
|
||||
$messages = $this->getNotifications($types);
|
||||
if ($types) {
|
||||
$messages = $messages[$type] ?? [];
|
||||
}
|
||||
|
||||
return collect($messages);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ use Engelsystem\Renderer\Twig\Extensions\Develop;
|
|||
use Engelsystem\Renderer\Twig\Extensions\Globals;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Legacy;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Markdown;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Notification;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Session;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Translation;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Url;
|
||||
|
@ -34,6 +35,7 @@ class TwigServiceProvider extends ServiceProvider
|
|||
'csrf' => Csrf::class,
|
||||
'develop' => Develop::class,
|
||||
'globals' => Globals::class,
|
||||
'notification' => Notification::class,
|
||||
'twigmodel' => TwigModel::class,
|
||||
'session' => Session::class,
|
||||
'legacy' => Legacy::class,
|
||||
|
|
|
@ -5,12 +5,11 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\Admin\FaqController;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Validation\Validator;
|
||||
use Engelsystem\Models\Faq;
|
||||
use Engelsystem\Test\Unit\Controllers\ControllerTest;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
class FaqControllerTest extends ControllerTest
|
||||
{
|
||||
|
@ -33,10 +32,7 @@ class FaqControllerTest extends ControllerTest
|
|||
->willReturnCallback(function ($view, $data) {
|
||||
$this->assertEquals('pages/faq/edit.twig', $view);
|
||||
|
||||
/** @var Collection $warnings */
|
||||
$warnings = $data['messages'];
|
||||
$this->assertNotEmpty($data['faq']);
|
||||
$this->assertTrue($warnings->isEmpty());
|
||||
|
||||
return $this->response;
|
||||
});
|
||||
|
@ -45,6 +41,7 @@ class FaqControllerTest extends ControllerTest
|
|||
$controller = $this->app->make(FaqController::class);
|
||||
|
||||
$controller->edit($this->request);
|
||||
$this->assertHasNoNotifications(NotificationType::WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,14 +79,10 @@ class FaqControllerTest extends ControllerTest
|
|||
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Updated'));
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$messages = $session->get('messages');
|
||||
$this->assertEquals('faq.edit.success', $messages[0]);
|
||||
|
||||
$faq = (new Faq())->find(2);
|
||||
$this->assertEquals('Foo?', $faq->question);
|
||||
$this->assertEquals('Bar!', $faq->text);
|
||||
$this->assertHasNotification('faq.edit.success');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,10 +146,7 @@ class FaqControllerTest extends ControllerTest
|
|||
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Deleted'));
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$messages = $session->get('messages');
|
||||
$this->assertEquals('faq.delete.success', $messages[0]);
|
||||
$this->assertHasNotification('faq.delete.success');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\Admin\NewsController;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Events\EventDispatcher;
|
||||
use Engelsystem\Helpers\Authenticator;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
|
@ -12,9 +13,7 @@ use Engelsystem\Http\Validation\Validator;
|
|||
use Engelsystem\Models\News;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\Controllers\ControllerTest;
|
||||
use Illuminate\Support\Collection;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
class NewsControllerTest extends ControllerTest
|
||||
{
|
||||
|
@ -42,10 +41,7 @@ class NewsControllerTest extends ControllerTest
|
|||
->willReturnCallback(function ($view, $data) {
|
||||
$this->assertEquals('pages/news/edit.twig', $view);
|
||||
|
||||
/** @var Collection $warnings */
|
||||
$warnings = $data['warnings'];
|
||||
$this->assertNotEmpty($data['news']);
|
||||
$this->assertTrue($warnings->isEmpty());
|
||||
|
||||
return $this->response;
|
||||
});
|
||||
|
@ -54,6 +50,7 @@ class NewsControllerTest extends ControllerTest
|
|||
$controller = $this->app->make(NewsController::class);
|
||||
|
||||
$controller->edit($this->request);
|
||||
$this->assertHasNoNotifications(NotificationType::WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,10 +144,7 @@ class NewsControllerTest extends ControllerTest
|
|||
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Updated'));
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$messages = $session->get('messages');
|
||||
$this->assertEquals('news.edit.success', $messages[0]);
|
||||
$this->assertHasNotification('news.edit.success');
|
||||
|
||||
$news = (new News())->find($id);
|
||||
$this->assertEquals($text, $news->text);
|
||||
|
@ -224,10 +218,7 @@ class NewsControllerTest extends ControllerTest
|
|||
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Deleted'));
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$messages = $session->get('messages');
|
||||
$this->assertEquals('news.delete.success', $messages[0]);
|
||||
$this->assertHasNotification('news.delete.success');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Engelsystem\Test\Unit\Controllers;
|
|||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\AuthController;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Helpers\Authenticator;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Redirector;
|
||||
|
@ -16,13 +17,12 @@ use Engelsystem\Http\Validation\Validator;
|
|||
use Engelsystem\Models\User\Settings;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
|
||||
class AuthControllerTest extends TestCase
|
||||
class AuthControllerTest extends ControllerTest
|
||||
{
|
||||
use ArraySubsetAsserts;
|
||||
use HasDatabase;
|
||||
|
@ -42,11 +42,6 @@ class AuthControllerTest extends TestCase
|
|||
/** @var Authenticator|MockObject $auth */
|
||||
list(, $session, $redirect, $config, $auth) = $this->getMocks();
|
||||
|
||||
$session->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->willReturnCallback(function ($type) {
|
||||
return $type == 'errors' ? ['foo' => 'bar'] : [];
|
||||
});
|
||||
$response->expects($this->once())
|
||||
->method('withView')
|
||||
->with('pages/login')
|
||||
|
@ -70,11 +65,10 @@ class AuthControllerTest extends TestCase
|
|||
/** @var Config $config */
|
||||
/** @var Authenticator|MockObject $auth */
|
||||
list(, , $redirect, $config, $auth) = $this->getMocks();
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
$this->session = new Session(new MockArraySessionStorage());
|
||||
$this->app->instance('session', $this->session);
|
||||
/** @var Validator|MockObject $validator */
|
||||
$validator = new Validator();
|
||||
$session->set('errors', [['bar' => 'some.bar.error']]);
|
||||
$this->app->instance('session', $session);
|
||||
$user = $this->createUser();
|
||||
|
||||
$auth->expects($this->exactly(2))
|
||||
|
@ -86,13 +80,12 @@ class AuthControllerTest extends TestCase
|
|||
->method('withView')
|
||||
->willReturnCallback(function ($view, $data = []) use ($response) {
|
||||
$this->assertEquals('pages/login', $view);
|
||||
$this->assertArraySubset(['errors' => collect(['some.bar.error', 'auth.not-found'])], $data);
|
||||
return $response;
|
||||
});
|
||||
|
||||
/** @var AuthController|MockObject $controller */
|
||||
$controller = $this->getMockBuilder(AuthController::class)
|
||||
->setConstructorArgs([$response, $session, $redirect, $config, $auth])
|
||||
->setConstructorArgs([$response, $this->session, $redirect, $config, $auth])
|
||||
->onlyMethods(['loginUser'])
|
||||
->getMock();
|
||||
$controller->setValidator($validator);
|
||||
|
@ -120,7 +113,7 @@ class AuthControllerTest extends TestCase
|
|||
// No user found
|
||||
$request = new Request([], ['login' => 'foo', 'password' => 'bar']);
|
||||
$controller->postLogin($request);
|
||||
$this->assertEquals([], $session->all());
|
||||
$this->assertHasNotification('auth.not-found', NotificationType::ERROR);
|
||||
|
||||
// Authenticated user
|
||||
$controller->postLogin($request);
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Test\Unit\Controllers;
|
||||
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Http\UrlGenerator;
|
||||
|
@ -33,12 +34,26 @@ abstract class ControllerTest extends TestCase
|
|||
protected Session $session;
|
||||
|
||||
/**
|
||||
* @param string|null $type
|
||||
* @param string|string[] $value
|
||||
*/
|
||||
protected function assertHasNotification(string $value, string $type = 'messages'): void
|
||||
protected function setNotification(string|array $value, NotificationType $type = NotificationType::MESSAGE): void
|
||||
{
|
||||
$messages = $this->session->get($type, []);
|
||||
$this->assertTrue(in_array($value, $messages));
|
||||
$this->session->set(
|
||||
'messages.' . $type->value,
|
||||
array_merge($this->session->get('messages.' . $type->value, []), (array) $value)
|
||||
);
|
||||
}
|
||||
|
||||
protected function assertHasNotification(string $value, NotificationType $type = NotificationType::MESSAGE): void
|
||||
{
|
||||
$messages = $this->session->get('messages.' . $type->value, []);
|
||||
$this->assertTrue(in_array($value, $messages), 'Has ' . $type->value . ' notification: ' . $value);
|
||||
}
|
||||
|
||||
protected function assertHasNoNotifications(NotificationType $type = null): void
|
||||
{
|
||||
$messages = $this->session->get('messages' . ($type ? '.' . $type->value : ''), []);
|
||||
$this->assertEmpty($messages, 'Has no' . ($type ? ' ' . $type->value : '') . ' notification.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Test\Unit\Controllers;
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Test\Unit\Controllers\Stub\HasUserNotificationsImplementation;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use Illuminate\Support\Collection;
|
||||
|
@ -22,16 +23,17 @@ class HasUserNotificationsTest extends TestCase
|
|||
$this->app->instance('session', $session);
|
||||
|
||||
$notify = new HasUserNotificationsImplementation();
|
||||
$notify->add('Foo', 'errors');
|
||||
$notify->add('Bar', 'warnings');
|
||||
$notify->add(['Baz', 'Lorem'], 'information');
|
||||
$notify->add(['Hm', ['Uff', 'sum']], 'messages');
|
||||
$notify->add('Foo', NotificationType::ERROR);
|
||||
$notify->add('Bar', NotificationType::WARNING);
|
||||
$notify->add(['Baz', 'Lorem'], NotificationType::INFORMATION);
|
||||
$notify->add(['Hm', ['test'], 'some' => ['Uff', 'sum']], NotificationType::MESSAGE);
|
||||
$notify->add(['some' => ['it']], NotificationType::MESSAGE);
|
||||
|
||||
$this->assertEquals([
|
||||
'errors' => new Collection(['Foo']),
|
||||
'warnings' => new Collection(['Bar']),
|
||||
'information' => new Collection(['Baz', 'Lorem']),
|
||||
'messages' => new Collection(['Hm', 'Uff', 'sum']),
|
||||
NotificationType::ERROR->value => new Collection(['Foo']),
|
||||
NotificationType::WARNING->value => new Collection(['Bar']),
|
||||
NotificationType::INFORMATION->value => new Collection(['Baz', 'Lorem']),
|
||||
NotificationType::MESSAGE->value => new Collection(['Hm', 'test', 'Uff', 'sum', 'it']),
|
||||
], $notify->get());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Engelsystem\Test\Unit\Controllers;
|
|||
|
||||
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Controllers\PasswordResetController;
|
||||
use Engelsystem\Helpers\Authenticator;
|
||||
use Engelsystem\Http\Exceptions\HttpNotFound;
|
||||
|
@ -18,13 +19,12 @@ use Engelsystem\Models\User\PasswordReset;
|
|||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Renderer\Renderer;
|
||||
use Engelsystem\Test\Unit\HasDatabase;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\Test\TestLogger;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
|
||||
class PasswordResetControllerTest extends TestCase
|
||||
class PasswordResetControllerTest extends ControllerTest
|
||||
{
|
||||
use ArraySubsetAsserts;
|
||||
use HasDatabase;
|
||||
|
@ -55,7 +55,7 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$controller = $this->getController(
|
||||
'pages/password/reset-success',
|
||||
['type' => 'email', 'errors' => collect()]
|
||||
['type' => 'email']
|
||||
);
|
||||
/** @var TestLogger $log */
|
||||
$log = $this->args['log'];
|
||||
|
@ -67,6 +67,7 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$this->assertNotEmpty((new PasswordReset())->find($user->id)->first());
|
||||
$this->assertTrue($log->hasInfoThatContains($user->name));
|
||||
$this->assertHasNoNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,10 +93,11 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$controller = $this->getController(
|
||||
'pages/password/reset-success',
|
||||
['type' => 'email', 'errors' => collect()]
|
||||
['type' => 'email']
|
||||
);
|
||||
|
||||
$controller->postReset($request);
|
||||
$this->assertHasNoNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,7 +150,7 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$controller = $this->getController(
|
||||
'pages/password/reset-success',
|
||||
['type' => 'reset', 'errors' => collect()]
|
||||
['type' => 'reset']
|
||||
);
|
||||
|
||||
$auth = new Authenticator($request, $this->args['session'], $user);
|
||||
|
@ -159,6 +161,7 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$this->assertEmpty((new PasswordReset())->find($user->id));
|
||||
$this->assertNotNull(auth()->authenticate($user->name, $password));
|
||||
$this->assertHasNoNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,16 +182,10 @@ class PasswordResetControllerTest extends TestCase
|
|||
['token' => $token->token]
|
||||
);
|
||||
|
||||
$controller = $this->getController(
|
||||
'pages/password/reset-form',
|
||||
['errors' => collect(['some.other.error', 'validation.password.confirmed'])]
|
||||
);
|
||||
/** @var Session $session */
|
||||
$session = $this->args['session'];
|
||||
$session->set('errors', ['foo' => ['bar' => 'some.other.error']]);
|
||||
$controller = $this->getController('pages/password/reset-form');
|
||||
|
||||
$controller->postResetPassword($request);
|
||||
$this->assertEmpty($session->get('errors'));
|
||||
$this->assertHasNotification('validation.password.confirmed', NotificationType::ERROR);
|
||||
}
|
||||
|
||||
protected function getControllerArgs(): array
|
||||
|
@ -203,6 +200,10 @@ class PasswordResetControllerTest extends TestCase
|
|||
|
||||
$this->app->instance('session', $session);
|
||||
|
||||
$this->session = $session;
|
||||
$this->response = $response;
|
||||
$this->log = $log;
|
||||
|
||||
return $this->args = [
|
||||
'response' => $response,
|
||||
'session' => $session,
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Engelsystem\Test\Unit\Controllers;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Controllers\SettingsController;
|
||||
use Engelsystem\Http\Exceptions\HttpNotFound;
|
||||
use Engelsystem\Http\Response;
|
||||
|
@ -133,7 +134,7 @@ class SettingsControllerTest extends ControllerTest
|
|||
$this->setUpProfileTest();
|
||||
config(['buildup_start' => new Carbon('2022-01-02')]); // arrival before buildup
|
||||
$this->controller->saveProfile($this->request);
|
||||
$this->assertHasNotification('settings.profile.planned_arrival_date.invalid', 'errors');
|
||||
$this->assertHasNotification('settings.profile.planned_arrival_date.invalid', NotificationType::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +145,7 @@ class SettingsControllerTest extends ControllerTest
|
|||
$this->setUpProfileTest();
|
||||
config(['teardown_end' => new Carbon('2022-01-01')]); // departure after teardown
|
||||
$this->controller->saveProfile($this->request);
|
||||
$this->assertHasNotification('settings.profile.planned_departure_date.invalid', 'errors');
|
||||
$this->assertHasNotification('settings.profile.planned_departure_date.invalid', NotificationType::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,7 +273,7 @@ class SettingsControllerTest extends ControllerTest
|
|||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$messages = $session->get('messages');
|
||||
$messages = $session->get('messages.' . NotificationType::MESSAGE->value);
|
||||
$this->assertEquals('settings.password.success', $messages[0]);
|
||||
}
|
||||
|
||||
|
@ -328,10 +329,7 @@ class SettingsControllerTest extends ControllerTest
|
|||
|
||||
$this->controller->savePassword($this->request);
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$errors = $session->get('errors');
|
||||
$this->assertEquals('auth.password.error', $errors[0]);
|
||||
$this->assertHasNotification('auth.password.error', NotificationType::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -359,10 +357,7 @@ class SettingsControllerTest extends ControllerTest
|
|||
|
||||
$this->controller->savePassword($this->request);
|
||||
|
||||
/** @var Session $session */
|
||||
$session = $this->app->get('session');
|
||||
$errors = $session->get('errors');
|
||||
$this->assertEquals('validation.password.confirmed', $errors[0]);
|
||||
$this->assertHasNotification('validation.password.confirmed', NotificationType::ERROR);
|
||||
}
|
||||
|
||||
public function savePasswordValidationProvider(): array
|
||||
|
@ -558,7 +553,6 @@ class SettingsControllerTest extends ControllerTest
|
|||
->method('withView')
|
||||
->willReturnCallback(function ($view, $data) use ($providers) {
|
||||
$this->assertEquals('pages/settings/oauth', $view);
|
||||
$this->assertArrayHasKey('information', $data);
|
||||
$this->assertArrayHasKey('providers', $data);
|
||||
$this->assertEquals($providers, $data['providers']);
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Test\Unit\Controllers\Stub;
|
||||
|
||||
use Engelsystem\Controllers\HasUserNotifications;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
|
||||
class HasUserNotificationsImplementation
|
||||
{
|
||||
use HasUserNotifications;
|
||||
|
||||
public function add(string|array $value, string $type = 'messages'): void
|
||||
public function add(string|array $value, NotificationType $type = NotificationType::MESSAGE): void
|
||||
{
|
||||
$this->addNotification($value, $type);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Engelsystem\Test\Unit\Middleware;
|
||||
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Http\Exceptions\HttpException;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Psr7ServiceProvider;
|
||||
|
@ -185,7 +186,10 @@ class ErrorHandlerTest extends TestCase
|
|||
->willReturn(['foo' => ['validation.foo.numeric']]);
|
||||
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
$session->set('errors', ['validation' => ['foo' => ['validation.foo.required']]]);
|
||||
$session->set(
|
||||
'messages.' . NotificationType::ERROR->value,
|
||||
['validation' => ['foo' => ['validation.foo.required']]]
|
||||
);
|
||||
$request = Request::create(
|
||||
'/foo/bar',
|
||||
'POST',
|
||||
|
@ -208,7 +212,7 @@ class ErrorHandlerTest extends TestCase
|
|||
$this->assertEquals(302, $return->getStatusCode());
|
||||
$this->assertEquals('http://localhost/', $return->getHeaderLine('location'));
|
||||
$this->assertEquals([
|
||||
'errors' => [
|
||||
'messages.' . NotificationType::ERROR->value => [
|
||||
'validation' => [
|
||||
'foo' => [
|
||||
'validation.foo.required',
|
||||
|
|
|
@ -27,7 +27,6 @@ class LegacyTest extends ExtensionTest
|
|||
$this->assertExtensionExists('menuUserHints', 'header_render_hints', $functions, $isSafeHtml);
|
||||
$this->assertExtensionExists('menuLanguages', 'make_language_select', $functions, $isSafeHtml);
|
||||
$this->assertExtensionExists('page', [$extension, 'getPage'], $functions);
|
||||
$this->assertExtensionExists('msg', 'msg', $functions, $isSafeHtml);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Renderer\Twig\Extensions\Notification;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
|
||||
class NotificationTest extends ExtensionTest
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Renderer\Twig\Extensions\Notification::__construct
|
||||
* @covers \Engelsystem\Renderer\Twig\Extensions\Notification::getFunctions
|
||||
*/
|
||||
public function testGetFunctions(): void
|
||||
{
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
|
||||
$extension = new Notification($session);
|
||||
|
||||
$functions = $extension->getFunctions();
|
||||
$this->assertExtensionExists('notifications', [$extension, 'notifications'], $functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Renderer\Twig\Extensions\Notification::notifications
|
||||
*/
|
||||
public function testNotifications(): void
|
||||
{
|
||||
$session = new Session(new MockArraySessionStorage());
|
||||
|
||||
$extension = new Notification($session);
|
||||
$this->app->instance('session', $session);
|
||||
|
||||
$notificationsList = $extension->notifications()->toArray();
|
||||
$this->assertIsArray($notificationsList);
|
||||
foreach ($notificationsList as $notification) {
|
||||
$this->assertEmpty($notification);
|
||||
}
|
||||
|
||||
$session->set('messages.' . NotificationType::ERROR->value, 'some error');
|
||||
$session->set('messages.' . NotificationType::WARNING->value, 'a warning');
|
||||
$session->set('messages.' . NotificationType::INFORMATION->value, 'for your information');
|
||||
$session->set('messages.' . NotificationType::MESSAGE->value, 'i\'m a message');
|
||||
|
||||
$notifications = $extension->notifications();
|
||||
$this->assertEquals(['some error'], $notifications[NotificationType::ERROR->value]->toArray());
|
||||
$this->assertEquals(['a warning'], $notifications[NotificationType::WARNING->value]->toArray());
|
||||
$this->assertEquals(['for your information'], $notifications[NotificationType::INFORMATION->value]->toArray());
|
||||
$this->assertEquals(['i\'m a message'], $notifications[NotificationType::MESSAGE->value]->toArray());
|
||||
|
||||
$session->set('messages.' . NotificationType::ERROR->value, 'Test error');
|
||||
$notifications = $extension->notifications(NotificationType::ERROR->value);
|
||||
$this->assertEquals(['Test error'], $notifications->toArray());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue