Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
abstract class AbstractActivityEvent extends Event
{
/**
* @var Activity
*/
private $activity;
public function __construct(Activity $activity)
public function __construct(private Activity $activity)
{
$this->activity = $activity;
}
public function getActivity(): Activity

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
abstract class AbstractCustomerEvent extends Event
{
/**
* @var Customer
*/
private $customer;
public function __construct(Customer $customer)
public function __construct(private Customer $customer)
{
$this->customer = $customer;
}
public function getCustomer(): Customer

View File

@@ -15,23 +15,13 @@ use Symfony\Contracts\EventDispatcher\Event;
abstract class AbstractMetaDisplayEvent extends Event implements MetaDisplayEventInterface
{
/**
* @var BaseQuery
*/
private $query;
/**
* @var string
*/
private $location;
/**
* @var MetaTableTypeInterface[]
*/
private $fields = [];
public function __construct(BaseQuery $query, string $location)
public function __construct(private BaseQuery $query, private string $location)
{
$this->query = $query;
$this->location = $location;
}
/**
@@ -59,7 +49,7 @@ abstract class AbstractMetaDisplayEvent extends Event implements MetaDisplayEven
*
* @param MetaTableTypeInterface $meta
*/
public function addField(MetaTableTypeInterface $meta)
public function addField(MetaTableTypeInterface $meta): void
{
$this->fields[] = $meta;
}

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
abstract class AbstractProjectEvent extends Event
{
/**
* @var Project
*/
private $project;
public function __construct(Project $project)
public function __construct(private Project $project)
{
$this->project = $project;
}
public function getProject(): Project

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
abstract class AbstractTimesheetEvent extends Event
{
/**
* @var Timesheet
*/
private $timesheet;
public function __construct(Timesheet $timesheet)
public function __construct(private Timesheet $timesheet)
{
$this->timesheet = $timesheet;
}
public function getTimesheet(): Timesheet

View File

@@ -18,13 +18,10 @@ use Symfony\Contracts\EventDispatcher\Event;
abstract class AbstractTimesheetMultipleEvent extends Event
{
/**
* @var Timesheet[]
* @param array<Timesheet> $timesheets
*/
private $timesheets;
public function __construct(array $timesheets)
public function __construct(private array $timesheets)
{
$this->timesheets = $timesheets;
}
public function getTimesheets(): array

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
abstract class AbstractUserEvent extends Event
{
/**
* @var User
*/
private $user;
public function __construct(User $user)
public function __construct(private User $user)
{
$this->user = $user;
}
public function getUser(): User

View File

@@ -13,20 +13,13 @@ use App\Model\ActivityBudgetStatisticModel;
final class ActivityBudgetStatisticEvent
{
private $models;
private $begin;
private $end;
/**
* @param ActivityBudgetStatisticModel[] $models
* @param \DateTime|null $begin
* @param \DateTime|null $end
*/
public function __construct(array $models, ?\DateTime $begin = null, ?\DateTime $end = null)
public function __construct(private array $models, private ?\DateTime $begin = null, private ?\DateTime $end = null)
{
$this->models = $models;
$this->begin = $begin;
$this->end = $end;
}
public function getModel(int $activityId): ?ActivityBudgetStatisticModel

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class ActivityMetaDefinitionEvent extends Event
{
/**
* @var Activity
*/
private $entity;
public function __construct(Activity $entity)
public function __construct(private Activity $entity)
{
$this->entity = $entity;
}
public function getEntity(): Activity

View File

@@ -11,16 +11,13 @@ namespace App\Event;
use Symfony\Contracts\EventDispatcher\Event;
class CalendarConfigurationEvent extends Event
final class CalendarConfigurationEvent extends Event
{
/**
* @var array<string, string|int|bool|array>
* @param array<string, string|int|bool|array> $configuration
*/
private $configuration;
public function __construct(array $configuration)
public function __construct(private array $configuration)
{
$this->configuration = $configuration;
}
public function getConfiguration(): array

View File

@@ -15,23 +15,13 @@ use Symfony\Contracts\EventDispatcher\Event;
final class CalendarDragAndDropSourceEvent extends Event
{
/**
* @var User
*/
private $user;
/**
* @var DragAndDropSource[]
*/
private $sources = [];
/**
* @var int
*/
private $maxEntries = 0;
public function __construct(User $user, int $maxEntries)
public function __construct(private User $user, private int $maxEntries)
{
$this->user = $user;
$this->maxEntries = $maxEntries;
}
public function getUser(): User

View File

@@ -15,18 +15,13 @@ use Symfony\Contracts\EventDispatcher\Event;
final class CalendarGoogleSourceEvent extends Event
{
/**
* @var User
*/
private $user;
/**
* @var GoogleSource[]
*/
private $sources = [];
public function __construct(User $user)
public function __construct(private User $user)
{
$this->user = $user;
}
public function getUser(): User

View File

@@ -10,8 +10,6 @@
namespace App\Event;
use App\Utils\MenuItemModel;
use KevinPapst\AdminLTEBundle\Event\SidebarMenuEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\EventDispatcher\Event;
/**
@@ -19,70 +17,50 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class ConfigureMainMenuEvent extends Event
{
/**
* @deprecated since 1.4, will be removed with 2.0
*/
public const CONFIGURE = ConfigureMainMenuEvent::class;
private MenuItemModel $menu;
private MenuItemModel $apps;
private MenuItemModel $admin;
private MenuItemModel $system;
/**
* @var Request
*/
private $request;
/**
* @var SidebarMenuEvent
*/
private $event;
/**
* @var MenuItemModel
*/
private $admin;
/**
* @var MenuItemModel
*/
private $system;
/**
* @param Request $request
* @param SidebarMenuEvent $event
* @param MenuItemModel $admin
* @param MenuItemModel $system
*/
public function __construct(Request $request, SidebarMenuEvent $event, MenuItemModel $admin, MenuItemModel $system)
public function __construct()
{
$this->request = $request;
$this->event = $event;
$this->admin = $admin;
$this->system = $system;
$this->menu = new MenuItemModel('main', 'menu.root');
$this->apps = new MenuItemModel('apps', 'menu.apps', '', [], 'applications');
$this->admin = new MenuItemModel('admin', 'menu.admin', '', [], 'administration');
$this->system = new MenuItemModel('system', 'menu.system', '', [], 'configuration');
}
/**
* @return Request
*/
public function getRequest()
public function getMenu(): MenuItemModel
{
return $this->request;
return $this->menu;
}
/**
* @return SidebarMenuEvent
*/
public function getMenu()
public function getTimesheetMenu(): ?MenuItemModel
{
return $this->event;
return $this->menu->getChild('timesheet');
}
/**
* @return MenuItemModel
*/
public function getAdminMenu()
public function getInvoiceMenu(): ?MenuItemModel
{
return $this->menu->getChild('invoice');
}
public function getReportingMenu(): ?MenuItemModel
{
return $this->menu->getChild('reporting');
}
public function getAppsMenu(): MenuItemModel
{
return $this->apps;
}
public function getAdminMenu(): MenuItemModel
{
return $this->admin;
}
/**
* @return MenuItemModel
*/
public function getSystemMenu()
public function getSystemMenu(): MenuItemModel
{
return $this->system;
}

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class CustomerMetaDefinitionEvent extends Event
{
/**
* @var Customer
*/
private $entity;
public function __construct(Customer $entity)
public function __construct(private Customer $entity)
{
$this->entity = $entity;
}
public function getEntity(): Customer

View File

@@ -10,47 +10,56 @@
namespace App\Event;
use App\Entity\User;
use App\Widget\WidgetContainerInterface;
use Symfony\Contracts\EventDispatcher\Event;
final class DashboardEvent extends Event
{
/**
* @deprecated since 1.4, will be removed with 2.0
* @var array<string>
*/
public const DASHBOARD = DashboardEvent::class;
private $widgets = [];
/**
* @var User
*/
protected $user;
/**
* @var WidgetContainerInterface[]
*/
protected $widgetRows = [];
public function __construct(User $user)
public function __construct(private User $user)
{
$this->user = $user;
}
/**
* @return array<string>
*/
public function getWidgets(): array
{
ksort($this->widgets, SORT_NUMERIC);
return $this->widgets;
}
/**
* Adding a widget here will add it to the default dashboard settings for users,
* which do not yet have their own dashboard configured.
*
* @param string $widget
* @param int|null $position
* @return void
*/
public function addWidget(string $widget, ?int $position = null): void
{
if ($position === null) {
$position = 0;
$keys = array_keys($this->widgets);
if (\count($keys) > 0) {
$position = max($keys) + 10;
}
}
while (\array_key_exists($position, $this->widgets)) {
$position++;
}
$this->widgets[$position] = $widget;
}
public function getUser(): User
{
return $this->user;
}
public function addSection(WidgetContainerInterface $container): DashboardEvent
{
$this->widgetRows[] = $container;
return $this;
}
/**
* @return WidgetContainerInterface[]
*/
public function getSections(): array
{
return $this->widgetRows;
}
}

View File

@@ -14,11 +14,8 @@ use Symfony\Contracts\EventDispatcher\Event;
class EmailEvent extends Event
{
private $email;
public function __construct(Email $email)
public function __construct(private Email $email)
{
$this->email = $email;
}
public function getEmail(): Email

View File

@@ -12,13 +12,10 @@ namespace App\Event;
use App\Repository\Query\ExportQuery;
use Symfony\Contracts\EventDispatcher\Event;
class ExportItemsQueryEvent extends Event
final class ExportItemsQueryEvent extends Event
{
private $query;
public function __construct(ExportQuery $query)
public function __construct(private ExportQuery $query)
{
$this->query = $query;
}
public function getExportQuery(): ExportQuery

View File

@@ -15,13 +15,8 @@ use Symfony\Contracts\EventDispatcher\Event;
final class InvoiceCreatedEvent extends Event
{
private $invoice;
private $model;
public function __construct(Invoice $invoice, InvoiceModel $model)
public function __construct(private Invoice $invoice, private InvoiceModel $model)
{
$this->invoice = $invoice;
$this->model = $model;
}
public function getInvoice(): Invoice

View File

@@ -1,37 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
use App\Entity\Invoice;
use Symfony\Contracts\EventDispatcher\Event;
final class InvoiceCreatedMultipleEvent extends Event
{
/**
* @param Invoice[] $invoices
*/
private $invoices;
/**
* @param Invoice[] $invoices
*/
public function __construct(array $invoices)
{
$this->invoices = $invoices;
}
/**
* @return Invoice[]
*/
public function getInvoices(): array
{
return $this->invoices;
}
}

View File

@@ -14,11 +14,8 @@ use Symfony\Contracts\EventDispatcher\Event;
final class InvoiceDeleteEvent extends Event
{
private $invoice;
public function __construct(Invoice $invoice)
public function __construct(private Invoice $invoice)
{
$this->invoice = $invoice;
}
public function getInvoice(): Invoice

View File

@@ -9,20 +9,19 @@
namespace App\Event;
use App\Entity\InvoiceDocument;
use App\Model\InvoiceDocument;
use Symfony\Contracts\EventDispatcher\Event;
final class InvoiceDocumentsEvent extends Event
{
/**
* @var InvoiceDocument[]
* @var array<InvoiceDocument>
*/
private $documents;
private array $documents;
/**
* Maximum amount of allowed invoice documents.
* @var int
*/
private $maximum = 99;
private int $maximum = 99;
/**
* @param InvoiceDocument[] $documents

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class InvoiceMetaDefinitionEvent extends Event
{
/**
* @var Invoice
*/
private $entity;
public function __construct(Invoice $entity)
public function __construct(private Invoice $entity)
{
$this->entity = $entity;
}
public function getEntity(): Invoice

View File

@@ -9,37 +9,16 @@
namespace App\Event;
use App\Entity\InvoiceDocument;
use App\Invoice\InvoiceModel;
use App\Invoice\RendererInterface;
use App\Model\InvoiceDocument;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\Event;
final class InvoicePostRenderEvent extends Event
{
/**
* @var InvoiceModel
*/
private $model;
/**
* @var InvoiceDocument
*/
private $document;
/**
* @var RendererInterface
*/
private $renderer;
/**
* @var Response
*/
private $response;
public function __construct(InvoiceModel $model, InvoiceDocument $document, RendererInterface $renderer, Response $response)
public function __construct(private InvoiceModel $model, private InvoiceDocument $document, private RendererInterface $renderer, private Response $response)
{
$this->model = $model;
$this->document = $document;
$this->renderer = $renderer;
$this->response = $response;
}
public function getModel(): InvoiceModel

View File

@@ -9,31 +9,15 @@
namespace App\Event;
use App\Entity\InvoiceDocument;
use App\Invoice\InvoiceModel;
use App\Invoice\RendererInterface;
use App\Model\InvoiceDocument;
use Symfony\Contracts\EventDispatcher\Event;
final class InvoicePreRenderEvent extends Event
{
/**
* @var InvoiceModel
*/
private $model;
/**
* @var InvoiceDocument
*/
private $document;
/**
* @var RendererInterface
*/
private $renderer;
public function __construct(InvoiceModel $model, InvoiceDocument $document, RendererInterface $renderer)
public function __construct(private InvoiceModel $model, private InvoiceDocument $document, private RendererInterface $renderer)
{
$this->model = $model;
$this->document = $document;
$this->renderer = $renderer;
}
public function getModel(): InvoiceModel

View File

@@ -10,11 +10,11 @@
namespace App\Event;
use App\Entity\User;
use App\Repository\Query\BaseQuery;
/**
* This event is triggered once per side load.
* It stores all toolbar items, which should be rendered in the upper right corner.
* This event is triggered for every action:
* - once per side load for table actions
* - once for every row item
*/
class PageActionsEvent extends ThemeEvent
{
@@ -42,6 +42,11 @@ class PageActionsEvent extends ThemeEvent
return $this->action;
}
public function getEventName(): string
{
return 'actions.' . $this->getActionName();
}
public function isView(string $view): bool
{
return $this->view === $view;
@@ -52,6 +57,16 @@ class PageActionsEvent extends ThemeEvent
return $this->isView('index');
}
/**
* Custom view can only be table listings.
*
* @return bool
*/
public function isCustomView(): bool
{
return $this->isView('custom');
}
public function getView(): string
{
return $this->view;
@@ -127,53 +142,45 @@ class PageActionsEvent extends ThemeEvent
$this->payload['actions'][$key] = null;
}
public function addSearchToggle(?BaseQuery $query = null): void
{
$label = null;
if ($query !== null) {
$label = $query->countFilter();
if ($label < 1) {
$label = null;
}
}
$this->addAction('search', ['modal' => '#modal_search', 'label' => $label, 'accesskey' => 'q']);
}
public function addQuickExport(string $url): void
{
$this->addAction('download', ['url' => $url, 'class' => 'toolbar-action']);
$this->addAction('download', ['url' => $url, 'class' => 'toolbar-action', 'title' => 'export']);
}
public function addCreate(string $url, bool $modal = true): void
{
$this->addAction('create', ['url' => $url, 'class' => ($modal ? 'modal-ajax-form' : ''), 'accesskey' => 'a']);
$this->addAction('create', ['url' => $url, 'class' => ($modal ? 'modal-ajax-form' : ''), 'title' => 'create', 'accesskey' => 'a']);
}
public function addHelp(string $url): void
/**
* Link to a configuration section.
*
* @param string $url
* @return void
*/
public function addSettings(string $url): void
{
$this->addAction('help', ['url' => $url, 'target' => '_blank', 'accesskey' => 'h']);
$this->addAction('settings', ['url' => $url, 'class' => 'modal-ajax-form', 'title' => 'settings', 'translation_domain' => 'actions', 'accesskey' => 'h']);
}
public function addBack(string $url): void
public function addConfig(string $url): void
{
$this->addAction('back', ['url' => $url, 'translation_domain' => 'actions']);
$this->addAction('settings', ['url' => $url, 'title' => 'settings', 'translation_domain' => 'actions']);
}
public function addDelete(string $url, bool $remoteConfirm = true): void
{
if ($remoteConfirm) {
$this->addAction('trash', ['url' => $url, 'class' => 'modal-ajax-form text-red']);
$this->addAction('trash', ['url' => $url, 'class' => 'modal-ajax-form text-red', 'translation_domain' => 'actions']);
} else {
$this->addAction('trash', ['url' => $url, 'class' => 'confirmation-link text-red', 'attr' => ['data-question' => 'confirm.delete']]);
$this->addAction('trash', ['url' => $url, 'class' => 'confirmation-link text-red', 'attr' => ['data-question' => 'confirm.delete'], 'translation_domain' => 'actions']);
}
}
public function addColumnToggle(string $modal): void
{
$modal = '#' . ltrim($modal, '#');
$this->addAction('visibility', ['modal' => $modal]);
$this->addAction('columns', ['modal' => $modal, 'title' => 'modal.columns.title']);
}
public function countActions(?string $submenu = null): int

View File

@@ -17,18 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class PrepareUserEvent extends Event
{
/**
* @deprecated since 1.4, will be removed with 2.0
*/
public const PREPARE = PrepareUserEvent::class;
/**
* @var User
*/
private $user;
public function __construct(User $user)
public function __construct(private User $user)
{
$this->user = $user;
}
public function getUser(): User

View File

@@ -13,20 +13,13 @@ use App\Model\ProjectBudgetStatisticModel;
final class ProjectBudgetStatisticEvent
{
private $models;
private $begin;
private $end;
/**
* @param ProjectBudgetStatisticModel[] $models
* @param \DateTime|null $begin
* @param \DateTime|null $end
*/
public function __construct(array $models, ?\DateTime $begin = null, ?\DateTime $end = null)
public function __construct(private array $models, private ?\DateTime $begin = null, private ?\DateTime $end = null)
{
$this->models = $models;
$this->begin = $begin;
$this->end = $end;
}
public function getModel(int $projectId): ?ProjectBudgetStatisticModel

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class ProjectMetaDefinitionEvent extends Event
{
/**
* @var Project
*/
private $entity;
public function __construct(Project $entity)
public function __construct(private Project $entity)
{
$this->entity = $entity;
}
public function getEntity(): Project

View File

@@ -15,23 +15,12 @@ use Symfony\Contracts\EventDispatcher\Event;
final class RecentActivityEvent extends Event
{
/**
* @var User
*/
private $user;
/**
* @var Timesheet[]
*/
private $recentActivities = [];
/**
* @param User $user
* @param Timesheet[] $recentActivities
*/
public function __construct(User $user, array $recentActivities)
public function __construct(private User $user, private array $recentActivities)
{
$this->user = $user;
$this->recentActivities = $recentActivities;
}
public function getUser(): User

View File

@@ -15,18 +15,13 @@ use Symfony\Contracts\EventDispatcher\Event;
final class ReportingEvent extends Event
{
/**
* @var User
*/
private $user;
/**
* @var ReportInterface[]
*/
private $reports = [];
public function __construct(User $user)
public function __construct(private User $user)
{
$this->user = $user;
}
public function getUser(): User

View File

@@ -16,14 +16,13 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class RevenueStatisticEvent extends Event
{
private $begin;
private $end;
private $revenue = 0.0;
/**
* @var array<string, float>
*/
private array $revenue = [];
public function __construct(?\DateTime $begin, ?\DateTime $end)
public function __construct(private ?\DateTime $begin, private ?\DateTime $end)
{
$this->begin = $begin;
$this->end = $end;
}
public function getBegin(): ?\DateTime
@@ -36,13 +35,17 @@ final class RevenueStatisticEvent extends Event
return $this->end;
}
public function getRevenue(): float
public function getRevenue(): array
{
return $this->revenue;
}
public function addRevenue(float $revenue): void
public function addRevenue(string $currency, float $revenue): void
{
$this->revenue += $revenue;
if (!\array_key_exists($currency, $this->revenue)) {
$this->revenue[$currency] = 0.0;
}
$this->revenue[$currency] += $revenue;
}
}

View File

@@ -17,30 +17,19 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class SystemConfigurationEvent extends Event
{
/**
* @deprecated since 1.4, will be removed with 2.0
*/
public const CONFIGURE = SystemConfigurationEvent::class;
/**
* @var SystemConfiguration[]
*/
protected $preferences;
/**
* @param SystemConfiguration[] $configurations
*/
public function __construct(array $configurations)
public function __construct(private array $configurations)
{
$this->preferences = $configurations;
}
/**
* @return SystemConfiguration[]
*/
public function getConfigurations()
public function getConfigurations(): array
{
return $this->preferences;
return $this->configurations;
}
/**
@@ -49,7 +38,7 @@ final class SystemConfigurationEvent extends Event
*/
public function addConfiguration(SystemConfiguration $configuration): SystemConfigurationEvent
{
$this->preferences[] = $configuration;
$this->configurations[] = $configuration;
return $this;
}

View File

@@ -22,22 +22,11 @@ class ThemeEvent extends Event
public const CONTENT_END = 'app.theme.content_end';
public const CONTENT_AFTER = 'app.theme.content_after';
/**
* @var User|null
*/
private $user;
/**
* @var string
*/
private $content = '';
/**
* @var mixed
*/
protected $payload;
private string $content = '';
protected mixed $payload;
public function __construct(?User $user = null, $payload = null)
public function __construct(private ?User $user = null, mixed $payload = null)
{
$this->user = $user;
$this->payload = $payload;
}
@@ -58,22 +47,13 @@ class ThemeEvent extends Event
return $this;
}
/**
* @return mixed
*/
public function getPayload()
public function getPayload(): mixed
{
return $this->payload;
}
/**
* @param mixed $payload
* @return ThemeEvent
*/
public function setPayload($payload)
public function setPayload(mixed $payload): void
{
$this->payload = $payload;
return $this;
}
}

View File

@@ -24,21 +24,12 @@ final class ThemeJavascriptTranslationsEvent extends Event
*
* @var array<string, array<int, string>>
*/
private $translations = [
private array $translations = [
'confirm' => ['confirm', 'messages'],
'cancel' => ['cancel', 'messages'],
'today' => ['daterangepicker.today', 'daterangepicker'],
'yesterday' => ['daterangepicker.yesterday', 'daterangepicker'],
'lastWeek' => ['daterangepicker.lastWeek', 'daterangepicker'],
'thisWeek' => ['daterangepicker.thisWeek', 'daterangepicker'],
'lastMonth' => ['daterangepicker.lastMonth', 'daterangepicker'],
'thisMonth' => ['daterangepicker.thisMonth', 'daterangepicker'],
'lastYear' => ['daterangepicker.lastYear', 'daterangepicker'],
'thisYear' => ['daterangepicker.thisYear', 'daterangepicker'],
'customRange' => ['daterangepicker.customRange', 'daterangepicker'],
'close' => ['action.close', 'messages'],
'timesheet.start.success' => ['timesheet.start.success', 'flashmessages'],
'timesheet.start.error' => ['timesheet.start.error', 'flashmessages'],
'timesheet.start.exceeded_limit' => ['timesheet.start.exceeded_limit', 'flashmessages'],
'timesheet.stop.success' => ['timesheet.stop.success', 'flashmessages'],
'timesheet.stop.error' => ['timesheet.stop.error', 'flashmessages'],
'action.update.success' => ['action.update.success', 'flashmessages'],
@@ -46,9 +37,11 @@ final class ThemeJavascriptTranslationsEvent extends Event
'action.delete.success' => ['action.delete.success', 'flashmessages'],
'action.delete.error' => ['action.delete.error', 'flashmessages'],
'confirm.delete' => ['confirm.delete', 'messages'],
'delete' => ['action.delete', 'messages'],
'delete' => ['delete', 'messages'],
'login.required' => ['login_required', 'messages'],
'modal.dirty' => ['modal.dirty', 'messages']
'modal.dirty' => ['modal.dirty', 'messages'],
'select.search.notfound' => ['search.no_results', 'messages'],
'select.search.create' => ['select.add_new', 'messages'],
];
public function getTranslations(): array

View File

@@ -17,14 +17,8 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class TimesheetMetaDefinitionEvent extends Event
{
/**
* @var Timesheet
*/
private $entity;
public function __construct(Timesheet $entity)
public function __construct(private Timesheet $entity)
{
$this->entity = $entity;
}
public function getEntity(): Timesheet

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
use App\Entity\User;
class UserDeleteEvent extends AbstractUserEvent
{
public function __construct(User $user, private ?User $replacement = null)
{
parent::__construct($user);
}
public function getReplacementUser(): ?User
{
return $this->replacement;
}
}

View File

@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
/**
* Triggered for user instances which were just deleted.
*/
final class UserDeletePostEvent extends UserDeleteEvent
{
}

View File

@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
/**
* Triggered for user instances which are about to be deleted.
*/
final class UserDeletePreEvent extends UserDeleteEvent
{
}

View File

@@ -14,12 +14,9 @@ use Symfony\Component\Mime\Email;
class UserEmailEvent extends EmailEvent
{
private $user;
public function __construct(User $user, Email $email)
public function __construct(private User $user, Email $email)
{
parent::__construct($email);
$this->user = $user;
}
public function getUser(): User

View File

@@ -23,15 +23,10 @@ final class UserPreferenceDisplayEvent extends Event
/**
* @var UserPreference[]
*/
protected $preferences = [];
/**
* @var string
*/
private $location;
private array $preferences = [];
public function __construct(string $location)
public function __construct(private string $location)
{
$this->location = $location;
}
/**

View File

@@ -18,28 +18,12 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class UserPreferenceEvent extends Event
{
/**
* @deprecated since 1.4, will be removed with 2.0
*/
public const CONFIGURE = UserPreferenceEvent::class;
/**
* @var User
*/
private $user;
/**
* @var UserPreference[]
*/
private $preferences = [];
/**
* @param User $user
* @param UserPreference[] $preferences
*/
public function __construct(User $user, array $preferences)
public function __construct(private User $user, private array $preferences)
{
$this->user = $user;
$this->preferences = $preferences;
}
/**
@@ -60,10 +44,7 @@ final class UserPreferenceEvent extends Event
return $this->preferences;
}
/**
* @param UserPreference $preference
*/
public function addPreference(UserPreference $preference)
public function addPreference(UserPreference $preference): void
{
foreach ($this->preferences as $pref) {
if (strtolower($pref->getName()) === strtolower($preference->getName())) {
@@ -74,14 +55,4 @@ final class UserPreferenceEvent extends Event
}
$this->preferences[] = $preference;
}
/**
* @param UserPreference $preference
* @deprecated since 1.4, will be removed with 2.0
*/
public function addUserPreference(UserPreference $preference)
{
@trigger_error('addUserPreference() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
$this->addPreference($preference);
}
}

View File

@@ -17,12 +17,10 @@ use Symfony\Contracts\EventDispatcher\Event;
*/
final class UserRevenueStatisticEvent extends Event
{
private $event;
private $user;
private RevenueStatisticEvent $event;
public function __construct(User $user, ?\DateTime $begin, ?\DateTime $end)
public function __construct(private User $user, ?\DateTime $begin, ?\DateTime $end)
{
$this->user = $user;
$this->event = new RevenueStatisticEvent($begin, $end);
}
@@ -36,14 +34,14 @@ final class UserRevenueStatisticEvent extends Event
return $this->event->getEnd();
}
public function getRevenue(): float
public function getRevenue(): array
{
return $this->event->getRevenue();
}
public function addRevenue(float $revenue): void
public function addRevenue(string $currency, float $revenue): void
{
$this->event->addRevenue($revenue);
$this->event->addRevenue($currency, $revenue);
}
public function getUser(): User