enhanced plugin support (#634)
- refactored admin controller and templates - plugin support for entity actions - changed column mail to email in customer table - refactored theme events
This commit is contained in:
@@ -11,12 +11,13 @@ namespace App\Twig;
|
||||
|
||||
use App\Utils\LocaleSettings;
|
||||
use DateTime;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* Date specific twig extensions
|
||||
*/
|
||||
class DateExtensions extends \Twig_Extension
|
||||
class DateExtensions extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @var LocaleSettings|null
|
||||
@@ -30,6 +31,10 @@ class DateExtensions extends \Twig_Extension
|
||||
* @var string
|
||||
*/
|
||||
protected $dateTimeFormat = null;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dateTimeTypeFormat = null;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -56,6 +61,7 @@ class DateExtensions extends \Twig_Extension
|
||||
new TwigFilter('month_name', [$this, 'monthName']),
|
||||
new TwigFilter('date_short', [$this, 'dateShort']),
|
||||
new TwigFilter('date_time', [$this, 'dateTime']),
|
||||
new TwigFilter('date_full', [$this, 'dateTimeFull']),
|
||||
new TwigFilter('date_format', [$this, 'dateFormat']),
|
||||
new TwigFilter('time', [$this, 'time']),
|
||||
new TwigFilter('hour24', [$this, 'hour24']),
|
||||
@@ -88,6 +94,28 @@ class DateExtensions extends \Twig_Extension
|
||||
return date_format($date, $this->dateTimeFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $date
|
||||
* @return string
|
||||
*/
|
||||
public function dateTimeFull(DateTime $date)
|
||||
{
|
||||
if (null === $this->dateTimeTypeFormat) {
|
||||
$this->dateTimeTypeFormat = $this->localeSettings->getDateTimeTypeFormat();
|
||||
}
|
||||
|
||||
$formatter = new \IntlDateFormatter(
|
||||
$this->localeSettings->getLocale(),
|
||||
\IntlDateFormatter::MEDIUM,
|
||||
\IntlDateFormatter::MEDIUM,
|
||||
date_default_timezone_get(),
|
||||
\IntlDateFormatter::GREGORIAN,
|
||||
$this->dateTimeTypeFormat
|
||||
);
|
||||
|
||||
return $formatter->format($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $date
|
||||
* @param string $format
|
||||
|
||||
163
src/Twig/EntityExtensions.php
Normal file
163
src/Twig/EntityExtensions.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?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\Twig;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\User;
|
||||
use App\Repository\ActivityRepository;
|
||||
use App\Repository\CustomerRepository;
|
||||
use App\Repository\ProjectRepository;
|
||||
use App\Repository\UserRepository;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* Entity specific twig extensions.
|
||||
* Should be used with caution, as they can trigger a lot of DB queries.
|
||||
*/
|
||||
class EntityExtensions extends AbstractExtension
|
||||
{
|
||||
private const UNKNOWN_NAME = '-unknown-';
|
||||
|
||||
/**
|
||||
* @var UserRepository|null
|
||||
*/
|
||||
private $users = null;
|
||||
/**
|
||||
* @var CustomerRepository|null
|
||||
*/
|
||||
private $customers = null;
|
||||
/**
|
||||
* @var ProjectRepository|null
|
||||
*/
|
||||
private $projects = null;
|
||||
/**
|
||||
* @var ActivityRepository|null
|
||||
*/
|
||||
private $activities = null;
|
||||
|
||||
/**
|
||||
* @param UserRepository $users
|
||||
* @param CustomerRepository $customers
|
||||
* @param ProjectRepository $projects
|
||||
* @param ActivityRepository $activities
|
||||
*/
|
||||
public function __construct(UserRepository $users, CustomerRepository $customers, ProjectRepository $projects, ActivityRepository $activities)
|
||||
{
|
||||
$this->users = $users;
|
||||
$this->customers = $customers;
|
||||
$this->projects = $projects;
|
||||
$this->activities = $activities;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new TwigFilter('user', [$this, 'getUser']),
|
||||
new TwigFilter('customer', [$this, 'getCustomer']),
|
||||
new TwigFilter('project', [$this, 'getProject']),
|
||||
new TwigFilter('activity', [$this, 'getActivity']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|User $user
|
||||
* @param bool $allowEmpty
|
||||
* @return User|null
|
||||
*/
|
||||
public function getUser($user, $allowEmpty = true)
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$entity = $this->users->getById($user);
|
||||
|
||||
if (null === $entity) {
|
||||
$entity = $this->users->loadUserByUsername($user);
|
||||
}
|
||||
|
||||
if (null === $entity && false === $allowEmpty) {
|
||||
$entity = new User();
|
||||
$entity->setUsername(self::UNKNOWN_NAME);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|Customer $customer
|
||||
* @param bool $allowEmpty
|
||||
* @return Customer|null
|
||||
*/
|
||||
public function getCustomer($customer, $allowEmpty = true)
|
||||
{
|
||||
if ($customer instanceof Customer) {
|
||||
return $customer;
|
||||
}
|
||||
|
||||
$entity = $this->customers->getById($customer);
|
||||
|
||||
if (null === $entity && false === $allowEmpty) {
|
||||
$entity = new Customer();
|
||||
$entity->setName(self::UNKNOWN_NAME);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|Project $project
|
||||
* @param bool $allowEmpty
|
||||
* @return Project|null
|
||||
*/
|
||||
public function getProject($project, $allowEmpty = true)
|
||||
{
|
||||
if ($project instanceof Project) {
|
||||
return $project;
|
||||
}
|
||||
|
||||
$entity = $this->projects->getById($project);
|
||||
|
||||
if (null === $entity && false === $allowEmpty) {
|
||||
$entity = new Project();
|
||||
$entity->setName(self::UNKNOWN_NAME);
|
||||
$entity->setCustomer((new Customer())->setName(self::UNKNOWN_NAME));
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|Activity $activity
|
||||
* @param bool $allowEmpty
|
||||
* @return Activity|null
|
||||
*/
|
||||
public function getActivity($activity, $allowEmpty = true)
|
||||
{
|
||||
if ($activity instanceof Activity) {
|
||||
return $activity;
|
||||
}
|
||||
|
||||
$entity = $this->activities->getById($activity);
|
||||
|
||||
if (null === $entity && false === $allowEmpty) {
|
||||
$entity = new Activity();
|
||||
$entity->setName(self::UNKNOWN_NAME);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
83
src/Twig/EventExtensions.php
Normal file
83
src/Twig/EventExtensions.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?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\Twig;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Event\ThemeEvent;
|
||||
use App\Security\CurrentUser;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class EventExtensions extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $dispatcher, CurrentUser $user)
|
||||
{
|
||||
$this->eventDispatcher = $dispatcher;
|
||||
$this->user = $user->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new TwigFunction('trigger', [$this, 'triggerEvent']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventDispatcherInterface
|
||||
*/
|
||||
protected function getDispatcher()
|
||||
{
|
||||
return $this->eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $eventName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasListener($eventName)
|
||||
{
|
||||
return $this->getDispatcher()->hasListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $eventName
|
||||
* @param mixed $payload
|
||||
* @return ThemeEvent
|
||||
*/
|
||||
public function triggerEvent(string $eventName, $payload = null)
|
||||
{
|
||||
$themeEvent = new ThemeEvent($this->user, $payload);
|
||||
|
||||
if ($this->hasListener($eventName)) {
|
||||
$this->getDispatcher()->dispatch($eventName, $themeEvent);
|
||||
}
|
||||
|
||||
return $themeEvent;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,12 +16,14 @@ use App\Utils\LocaleSettings;
|
||||
use NumberFormatter;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Intl\Intl;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
/**
|
||||
* Multiple Twig extensions: filters and functions
|
||||
*/
|
||||
class Extensions extends \Twig_Extension
|
||||
class Extensions extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @var LocaleSettings
|
||||
@@ -98,6 +100,7 @@ class Extensions extends \Twig_Extension
|
||||
'xlsx' => 'fas fa-file-excel',
|
||||
'on' => 'fas fa-toggle-on',
|
||||
'off' => 'fas fa-toggle-off',
|
||||
'audit' => 'fas fa-history',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -132,12 +135,26 @@ class Extensions extends \Twig_Extension
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('locales', [$this, 'getLocales']),
|
||||
new \Twig_SimpleFunction('is_visible_column', [$this, 'isColumnVisible']),
|
||||
new \Twig_SimpleFunction('is_datatable_configured', [$this, 'isDatatableConfigured']),
|
||||
new TwigFunction('locales', [$this, 'getLocales']),
|
||||
new TwigFunction('is_visible_column', [$this, 'isColumnVisible']),
|
||||
new TwigFunction('is_datatable_configured', [$this, 'isDatatableConfigured']),
|
||||
new TwigFunction('class_name', [$this, 'getClassName']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return null|string
|
||||
*/
|
||||
public function getClassName($object)
|
||||
{
|
||||
if (!is_object($object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return get_class($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dataTable
|
||||
* @param string $size
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
namespace App\Twig;
|
||||
|
||||
use App\Utils\Markdown;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* A twig extension to handle markdown parser.
|
||||
*/
|
||||
class MarkdownExtension extends \Twig_Extension
|
||||
class MarkdownExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* @var Markdown
|
||||
|
||||
Reference in New Issue
Block a user