Release 2.0.32 (#4256)
This commit is contained in:
93
src/API/Model/CalendarEvent.php
Normal file
93
src/API/Model/CalendarEvent.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?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\API\Model;
|
||||
|
||||
use App\Utils\Color;
|
||||
use JMS\Serializer\Annotation as Serializer;
|
||||
|
||||
#[Serializer\ExclusionPolicy('all')]
|
||||
final class CalendarEvent
|
||||
{
|
||||
/**
|
||||
* Calendar entry title
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'string')]
|
||||
private string $title; // @phpstan-ignore-line
|
||||
/**
|
||||
* Calendar background color
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'string')]
|
||||
private ?string $color = null; // @phpstan-ignore-line
|
||||
/**
|
||||
* Calendar text color
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'string')]
|
||||
private ?string $textColor = null;
|
||||
/**
|
||||
* If this entry is all-day long
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'boolean')]
|
||||
private bool $allDay = false; // @phpstan-ignore-line
|
||||
/**
|
||||
* Calendar entry start date
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'DateTime')]
|
||||
private \DateTimeInterface $start; // @phpstan-ignore-line
|
||||
/**
|
||||
* Calendar entry end date
|
||||
*/
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Serializer\Type(name: 'DateTime')]
|
||||
private \DateTimeInterface $end; // @phpstan-ignore-line
|
||||
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function setStart(\DateTimeInterface $start): void
|
||||
{
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
public function setEnd(\DateTimeInterface $end): void
|
||||
{
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
public function setColor(?string $color): void
|
||||
{
|
||||
$this->color = $color;
|
||||
if ($color !== null && $this->textColor === null) {
|
||||
$this->textColor = (new Color())->getFontContrastColor($color);
|
||||
}
|
||||
}
|
||||
|
||||
public function setAllDay(bool $allDay): void
|
||||
{
|
||||
$this->allDay = $allDay;
|
||||
}
|
||||
|
||||
public function setTextColor(?string $textColor): void
|
||||
{
|
||||
$this->textColor = $textColor;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ use App\Entity\User;
|
||||
use App\Event\CalendarConfigurationEvent;
|
||||
use App\Event\CalendarDragAndDropSourceEvent;
|
||||
use App\Event\CalendarGoogleSourceEvent;
|
||||
use App\Event\CalendarSourceEvent;
|
||||
use App\Event\RecentActivityEvent;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Utils\Color;
|
||||
@@ -81,6 +82,23 @@ final class CalendarService
|
||||
return new Google($apiKey, $sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<CalendarSource>
|
||||
*/
|
||||
public function getSources(User $user): array
|
||||
{
|
||||
$sources = [];
|
||||
|
||||
$event = new CalendarSourceEvent($user);
|
||||
$this->dispatcher->dispatch($event);
|
||||
|
||||
foreach ($event->getSources() as $source) {
|
||||
$sources[] = $source;
|
||||
}
|
||||
|
||||
return $sources;
|
||||
}
|
||||
|
||||
public function getConfiguration(): array
|
||||
{
|
||||
$config = [
|
||||
|
||||
58
src/Calendar/CalendarSource.php
Normal file
58
src/Calendar/CalendarSource.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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\Calendar;
|
||||
|
||||
class CalendarSource
|
||||
{
|
||||
/** @var array<string, string|bool|int> */
|
||||
private array $options = [];
|
||||
|
||||
public function __construct(private CalendarSourceType $type, private string $id, private string $uri, private ?string $color = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function getType(): CalendarSourceType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return $this->type->value;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
public function getColor(): ?string
|
||||
{
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
public function addOption(string $name, int|bool|string $value): void
|
||||
{
|
||||
$this->options[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, bool|int|string>
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
}
|
||||
18
src/Calendar/CalendarSourceType.php
Normal file
18
src/Calendar/CalendarSourceType.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?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\Calendar;
|
||||
|
||||
enum CalendarSourceType: string
|
||||
{
|
||||
case GOOGLE = 'google';
|
||||
case ICAL = 'ical';
|
||||
case JSON = 'json';
|
||||
case TIMESHEET = 'timesheet';
|
||||
}
|
||||
@@ -9,24 +9,10 @@
|
||||
|
||||
namespace App\Calendar;
|
||||
|
||||
final class GoogleSource
|
||||
final class GoogleSource extends CalendarSource
|
||||
{
|
||||
public function __construct(private string $id, private string $uri, private ?string $color = null)
|
||||
public function __construct(string $id, string $uri, ?string $color = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
public function getColor(): ?string
|
||||
{
|
||||
return $this->color;
|
||||
parent::__construct(CalendarSourceType::GOOGLE, $id, $uri, $color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
namespace App\Configuration;
|
||||
|
||||
use App\Constants;
|
||||
|
||||
final class LocaleService
|
||||
{
|
||||
public function __construct(private array $languageSettings)
|
||||
@@ -32,11 +30,6 @@ final class LocaleService
|
||||
return \in_array($language, $this->getAllLocales());
|
||||
}
|
||||
|
||||
public function getDefaultLocale(): string
|
||||
{
|
||||
return Constants::DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale specific date format, which should be used in combination with the twig filter "|date".
|
||||
*
|
||||
|
||||
@@ -17,11 +17,11 @@ class Constants
|
||||
/**
|
||||
* The current release version
|
||||
*/
|
||||
public const VERSION = '2.0.31';
|
||||
public const VERSION = '2.0.32';
|
||||
/**
|
||||
* The current release: major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
public const VERSION_ID = 20031;
|
||||
public const VERSION_ID = 20032;
|
||||
/**
|
||||
* The software name
|
||||
*/
|
||||
@@ -38,10 +38,6 @@ class Constants
|
||||
* Homepage, used in multiple views
|
||||
*/
|
||||
public const HOMEPAGE = 'https://www.kimai.org';
|
||||
/**
|
||||
* Application wide default locale
|
||||
*/
|
||||
public const DEFAULT_LOCALE = 'en';
|
||||
/**
|
||||
* Default color for Customer, Project and Activity entities
|
||||
*/
|
||||
|
||||
@@ -94,6 +94,7 @@ final class CalendarController extends AbstractController
|
||||
'config' => $config,
|
||||
'dragAndDrop' => $dragAndDrop,
|
||||
'google' => $this->calendarService->getGoogleSources($profile),
|
||||
'sources' => $this->calendarService->getSources($profile),
|
||||
'now' => $factory->createDateTime(),
|
||||
'defaultStartTime' => $defaultStart,
|
||||
'is_punch_mode' => $isPunchMode,
|
||||
|
||||
@@ -46,7 +46,7 @@ final class HomepageController extends AbstractController
|
||||
// if a user somehow managed to get a wrong locale into hos account (eg. an imported user from Kimai 1)
|
||||
// make sure that he will still see a beautiful page and not a 404
|
||||
if (!$service->isKnownLocale($userLanguage)) {
|
||||
$userLanguage = $service->getDefaultLocale();
|
||||
$userLanguage = 'en';
|
||||
}
|
||||
|
||||
$routes = [];
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Constants;
|
||||
use App\Export\Annotation as Exporter;
|
||||
use App\Utils\StringHelper;
|
||||
use App\Validator\Constraints as Constraints;
|
||||
@@ -55,7 +54,7 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
public const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
|
||||
|
||||
public const DEFAULT_ROLE = self::ROLE_USER;
|
||||
public const DEFAULT_LANGUAGE = Constants::DEFAULT_LOCALE;
|
||||
public const DEFAULT_LANGUAGE = 'en';
|
||||
public const DEFAULT_FIRST_WEEKDAY = 'monday';
|
||||
|
||||
public const AUTH_INTERNAL = 'kimai';
|
||||
@@ -169,7 +168,7 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
#[Assert\Email(mode: 'html5', groups: ['Registration', 'UserCreate', 'Profile'])]
|
||||
private ?string $email = null;
|
||||
#[ORM\Column(name: 'account', type: 'string', length: 30, nullable: true)]
|
||||
#[Assert\Length(max: 30, groups: ['Registration', 'UserCreate', 'Profile'])]
|
||||
#[Assert\Length(max: 30)]
|
||||
#[Serializer\Expose]
|
||||
#[Serializer\Groups(['Default'])]
|
||||
#[Exporter\Expose(label: 'account_number')]
|
||||
@@ -195,6 +194,7 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
* Random string sent to the user email address in order to verify it.
|
||||
*/
|
||||
#[ORM\Column(name: 'confirmation_token', type: 'string', length: 180, unique: true, nullable: true)]
|
||||
#[Assert\Length(max: 180)]
|
||||
private ?string $confirmationToken = null;
|
||||
#[ORM\Column(name: 'password_requested_at', type: 'datetime', nullable: true)]
|
||||
private ?\DateTime $passwordRequestedAt = null;
|
||||
@@ -1055,7 +1055,8 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
|
||||
public function setAccountNumber(?string $accountNumber): void
|
||||
{
|
||||
$this->accountNumber = $accountNumber;
|
||||
// @CloudRequired because SAML mapping could include a longer value
|
||||
$this->accountNumber = StringHelper::ensureMaxLength($accountNumber, 30);
|
||||
}
|
||||
|
||||
public function isSystemAccount(): bool
|
||||
|
||||
@@ -18,7 +18,7 @@ abstract class AbstractMetaDisplayEvent extends Event implements MetaDisplayEven
|
||||
/**
|
||||
* @var MetaTableTypeInterface[]
|
||||
*/
|
||||
private $fields = [];
|
||||
private array $fields = [];
|
||||
|
||||
public function __construct(private BaseQuery $query, private string $location)
|
||||
{
|
||||
|
||||
@@ -14,16 +14,9 @@ use App\Model\ActivityStatistic;
|
||||
|
||||
final class ActivityStatisticEvent extends AbstractActivityEvent
|
||||
{
|
||||
private $statistic;
|
||||
private $begin;
|
||||
private $end;
|
||||
|
||||
public function __construct(Activity $activity, ActivityStatistic $statistic, \DateTime $begin = null, \DateTime $end = null)
|
||||
public function __construct(Activity $activity, private ActivityStatistic $statistic, private ?\DateTime $begin = null, private ?\DateTime $end = null)
|
||||
{
|
||||
parent::__construct($activity);
|
||||
$this->statistic = $statistic;
|
||||
$this->begin = $begin;
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
public function getStatistic(): ActivityStatistic
|
||||
|
||||
@@ -25,7 +25,7 @@ final class CalendarConfigurationEvent extends Event
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
public function setConfiguration(array $configuration)
|
||||
public function setConfiguration(array $configuration): void
|
||||
{
|
||||
foreach ($configuration as $key => $value) {
|
||||
if (\array_key_exists($key, $this->configuration)) {
|
||||
|
||||
@@ -18,7 +18,7 @@ final class CalendarDragAndDropSourceEvent extends Event
|
||||
/**
|
||||
* @var DragAndDropSource[]
|
||||
*/
|
||||
private $sources = [];
|
||||
private array $sources = [];
|
||||
|
||||
public function __construct(private User $user, private int $maxEntries)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ final class CalendarGoogleSourceEvent extends Event
|
||||
/**
|
||||
* @var GoogleSource[]
|
||||
*/
|
||||
private $sources = [];
|
||||
private array $sources = [];
|
||||
|
||||
public function __construct(private User $user)
|
||||
{
|
||||
|
||||
44
src/Event/CalendarSourceEvent.php
Normal file
44
src/Event/CalendarSourceEvent.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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\Calendar\CalendarSource;
|
||||
use App\Entity\User;
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
final class CalendarSourceEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var CalendarSource[]
|
||||
*/
|
||||
private array $sources = [];
|
||||
|
||||
public function __construct(private User $user)
|
||||
{
|
||||
}
|
||||
|
||||
public function getUser(): User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function addSource(CalendarSource $source): void
|
||||
{
|
||||
$this->sources[] = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CalendarSource[]
|
||||
*/
|
||||
public function getSources(): array
|
||||
{
|
||||
return $this->sources;
|
||||
}
|
||||
}
|
||||
@@ -14,16 +14,9 @@ use App\Model\CustomerStatistic;
|
||||
|
||||
final class CustomerStatisticEvent extends AbstractCustomerEvent
|
||||
{
|
||||
private $statistic;
|
||||
private $begin;
|
||||
private $end;
|
||||
|
||||
public function __construct(Customer $customer, CustomerStatistic $statistic, \DateTime $begin = null, \DateTime $end = null)
|
||||
public function __construct(Customer $customer, private CustomerStatistic $statistic, private ?\DateTime $begin = null, private ?\DateTime $end = null)
|
||||
{
|
||||
parent::__construct($customer);
|
||||
$this->statistic = $statistic;
|
||||
$this->begin = $begin;
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
public function getStatistic(): CustomerStatistic
|
||||
|
||||
@@ -17,7 +17,7 @@ final class DashboardEvent extends Event
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private $widgets = [];
|
||||
private array $widgets = [];
|
||||
|
||||
public function __construct(private User $user)
|
||||
{
|
||||
|
||||
@@ -14,10 +14,6 @@ use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
final class InvoiceDocumentsEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var array<InvoiceDocument>
|
||||
*/
|
||||
private array $documents;
|
||||
/**
|
||||
* Maximum amount of allowed invoice documents.
|
||||
*/
|
||||
@@ -26,9 +22,8 @@ final class InvoiceDocumentsEvent extends Event
|
||||
/**
|
||||
* @param InvoiceDocument[] $documents
|
||||
*/
|
||||
public function __construct(array $documents)
|
||||
public function __construct(private array $documents)
|
||||
{
|
||||
$this->documents = $documents;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,9 +18,9 @@ use Symfony\Contracts\EventDispatcher\Event;
|
||||
final class PermissionSectionsEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
* @var array<PermissionSectionInterface>
|
||||
*/
|
||||
private $sections;
|
||||
private array $sections = [];
|
||||
|
||||
public function addSection(PermissionSectionInterface $section): PermissionSectionsEvent
|
||||
{
|
||||
|
||||
@@ -17,9 +17,9 @@ use Symfony\Contracts\EventDispatcher\Event;
|
||||
final class PermissionsEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, array<string>>
|
||||
*/
|
||||
private $sections = [];
|
||||
private array $sections = [];
|
||||
|
||||
/**
|
||||
* @param string $section
|
||||
|
||||
@@ -14,16 +14,9 @@ use App\Model\ProjectStatistic;
|
||||
|
||||
final class ProjectStatisticEvent extends AbstractProjectEvent
|
||||
{
|
||||
private $statistic;
|
||||
private $begin;
|
||||
private $end;
|
||||
|
||||
public function __construct(Project $project, ProjectStatistic $statistic, \DateTime $begin = null, \DateTime $end = null)
|
||||
public function __construct(Project $project, private ProjectStatistic $statistic, private ?\DateTime $begin = null, private ?\DateTime $end = null)
|
||||
{
|
||||
parent::__construct($project);
|
||||
$this->statistic = $statistic;
|
||||
$this->begin = $begin;
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
public function getStatistic(): ProjectStatistic
|
||||
|
||||
@@ -13,15 +13,9 @@ use App\Entity\Timesheet;
|
||||
|
||||
final class TimesheetDuplicatePostEvent extends AbstractTimesheetEvent
|
||||
{
|
||||
/**
|
||||
* @var Timesheet
|
||||
*/
|
||||
private $original;
|
||||
|
||||
public function __construct(Timesheet $new, Timesheet $original)
|
||||
public function __construct(Timesheet $new, private Timesheet $original)
|
||||
{
|
||||
parent::__construct($new);
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
public function getOriginalTimesheet(): Timesheet
|
||||
|
||||
@@ -13,15 +13,9 @@ use App\Entity\Timesheet;
|
||||
|
||||
final class TimesheetDuplicatePreEvent extends AbstractTimesheetEvent
|
||||
{
|
||||
/**
|
||||
* @var Timesheet
|
||||
*/
|
||||
private $original;
|
||||
|
||||
public function __construct(Timesheet $new, Timesheet $original)
|
||||
public function __construct(Timesheet $new, private Timesheet $original)
|
||||
{
|
||||
parent::__construct($new);
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
public function getOriginalTimesheet(): Timesheet
|
||||
|
||||
@@ -13,15 +13,9 @@ use App\Entity\Timesheet;
|
||||
|
||||
final class TimesheetRestartPostEvent extends AbstractTimesheetEvent
|
||||
{
|
||||
/**
|
||||
* @var Timesheet
|
||||
*/
|
||||
private $original;
|
||||
|
||||
public function __construct(Timesheet $new, Timesheet $original)
|
||||
public function __construct(Timesheet $new, private Timesheet $original)
|
||||
{
|
||||
parent::__construct($new);
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
public function getOriginalTimesheet(): Timesheet
|
||||
|
||||
@@ -13,15 +13,9 @@ use App\Entity\Timesheet;
|
||||
|
||||
final class TimesheetRestartPreEvent extends AbstractTimesheetEvent
|
||||
{
|
||||
/**
|
||||
* @var Timesheet
|
||||
*/
|
||||
private $original;
|
||||
|
||||
public function __construct(Timesheet $new, Timesheet $original)
|
||||
public function __construct(Timesheet $new, private Timesheet $original)
|
||||
{
|
||||
parent::__construct($new);
|
||||
$this->original = $original;
|
||||
}
|
||||
|
||||
public function getOriginalTimesheet(): Timesheet
|
||||
|
||||
@@ -57,7 +57,7 @@ final class RedirectToLocaleSubscriber implements EventSubscriberInterface
|
||||
|
||||
// Add the default locale at the first position of the array, because getPreferredLanguage()
|
||||
// returns the first element when no appropriate language is found
|
||||
array_unshift($allLanguages, $this->localeService->getDefaultLocale());
|
||||
array_unshift($allLanguages, 'en');
|
||||
|
||||
$preferredLanguage = $request->getPreferredLanguage(array_unique($allLanguages));
|
||||
|
||||
|
||||
@@ -130,10 +130,14 @@ final class SamlProvider
|
||||
}
|
||||
if ($part[0] === '$') {
|
||||
$key = substr($part, 1);
|
||||
if (!isset($attributes[$key])) {
|
||||
if (!\array_key_exists($key, $attributes)) {
|
||||
throw new \RuntimeException('Missing user attribute: ' . $key);
|
||||
}
|
||||
|
||||
if (!\array_key_exists(0, $attributes[$key])) {
|
||||
throw new \RuntimeException('Missing user attribute value: ' . $key);
|
||||
}
|
||||
|
||||
$results[] = $attributes[$key][0];
|
||||
} else {
|
||||
$results[] = $part;
|
||||
|
||||
@@ -43,7 +43,8 @@ final class LocaleFormatExtensions extends AbstractExtension implements LocaleAw
|
||||
new TwigFilter('day_name', [$this, 'dayName']),
|
||||
new TwigFilter('date_short', [$this, 'dateShort']),
|
||||
new TwigFilter('date_time', [$this, 'dateTime']),
|
||||
new TwigFilter('date_full', [$this, 'dateTime']), // deprecated: needs to be kept for invoice and export templates
|
||||
// cannot be deleted right now, needs to be kept for invoice and export templates
|
||||
new TwigFilter('date_full', [$this, 'dateTime'], ['deprecated' => true, 'alternative' => 'date_time']),
|
||||
new TwigFilter('date_format', [$this, 'dateFormat']),
|
||||
new TwigFilter('date_weekday', [$this, 'dateWeekday']),
|
||||
new TwigFilter('time', [$this, 'time']),
|
||||
|
||||
Reference in New Issue
Block a user