performance improvements (#2329)
* remove work from constructor * refactor twig extensions * upgrade theme * replace sub-request with direct template rendering
This commit is contained in:
56
src/Twig/Runtime/EncoreExtension.php
Normal file
56
src/Twig/Runtime/EncoreExtension.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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\Runtime;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class EncoreExtension implements RuntimeExtensionInterface, ServiceSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $publicDir;
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container, string $projectDirectory)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->publicDir = $projectDirectory . '/public';
|
||||
}
|
||||
|
||||
public static function getSubscribedServices()
|
||||
{
|
||||
return [
|
||||
EntrypointLookupInterface::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function getEncoreEntryCssSource(string $packageName): string
|
||||
{
|
||||
$lookup = $this->container->get(EntrypointLookupInterface::class);
|
||||
$files = $lookup->getCssFiles($packageName);
|
||||
|
||||
$source = '';
|
||||
|
||||
foreach ($files as $file) {
|
||||
$source .= file_get_contents($this->publicDir . '/' . $file);
|
||||
}
|
||||
|
||||
$lookup->reset();
|
||||
|
||||
return $source;
|
||||
}
|
||||
}
|
||||
36
src/Twig/Runtime/ExporterExtension.php
Normal file
36
src/Twig/Runtime/ExporterExtension.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?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\Runtime;
|
||||
|
||||
use App\Export\ServiceExport;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class ExporterExtension implements RuntimeExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @var ServiceExport
|
||||
*/
|
||||
private $service;
|
||||
|
||||
public function __construct(ServiceExport $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
public function getTimesheetExporter(): array
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($this->service->getTimesheetExporter() as $exporter) {
|
||||
$ids[] = $exporter->getId();
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
101
src/Twig/Runtime/MarkdownExtension.php
Normal file
101
src/Twig/Runtime/MarkdownExtension.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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\Runtime;
|
||||
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Utils\Markdown;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class MarkdownExtension implements RuntimeExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @var Markdown
|
||||
*/
|
||||
private $markdown;
|
||||
/**
|
||||
* @var SystemConfiguration
|
||||
*/
|
||||
private $configuration;
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private $markdownEnabled;
|
||||
|
||||
public function __construct(Markdown $parser, SystemConfiguration $configuration)
|
||||
{
|
||||
$this->markdown = $parser;
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
private function isMarkdownEnabled(): bool
|
||||
{
|
||||
if (null === $this->markdownEnabled) {
|
||||
$this->markdownEnabled = $this->configuration->isTimesheetMarkdownEnabled();
|
||||
}
|
||||
|
||||
return $this->markdownEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the entities comment (customer, project, activity ...) into HTML.
|
||||
*
|
||||
* @param string|null $content
|
||||
* @param bool $fullLength
|
||||
* @return string
|
||||
*/
|
||||
public function commentContent(?string $content, bool $fullLength = false): string
|
||||
{
|
||||
if (empty($content)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!$fullLength && \strlen($content) > 101) {
|
||||
$content = trim(substr($content, 0, 100)) . ' …';
|
||||
}
|
||||
|
||||
if ($this->isMarkdownEnabled()) {
|
||||
$content = $this->markdown->toHtml($content, false);
|
||||
} elseif ($fullLength) {
|
||||
$content = '<p>' . nl2br($content) . '</p>';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the timesheet description content into HTML.
|
||||
*
|
||||
* @param string|null $content
|
||||
* @return string
|
||||
*/
|
||||
public function timesheetContent(?string $content): string
|
||||
{
|
||||
if (empty($content)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->isMarkdownEnabled()) {
|
||||
return $this->markdown->toHtml($content, false);
|
||||
}
|
||||
|
||||
return nl2br($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the given Markdown content into HTML
|
||||
*
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function markdownToHtml(string $content): string
|
||||
{
|
||||
return $this->markdown->toHtml($content, false);
|
||||
}
|
||||
}
|
||||
@@ -9,37 +9,40 @@
|
||||
|
||||
namespace App\Twig\Runtime;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Event\ThemeEvent;
|
||||
use App\Event\ThemeJavascriptTranslationsEvent;
|
||||
use App\Security\CurrentUser;
|
||||
use Symfony\Bridge\Twig\AppVariable;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class ThemeEventExtension implements RuntimeExtensionInterface
|
||||
final class ThemeExtension implements RuntimeExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
/**
|
||||
* @var CurrentUser
|
||||
*/
|
||||
private $user;
|
||||
|
||||
public function __construct(EventDispatcherInterface $dispatcher, CurrentUser $user)
|
||||
public function __construct(EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->eventDispatcher = $dispatcher;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Environment $environment
|
||||
* @param string $eventName
|
||||
* @param mixed|null $payload
|
||||
* @return ThemeEvent
|
||||
*/
|
||||
public function trigger(string $eventName, $payload = null): ThemeEvent
|
||||
public function trigger(Environment $environment, string $eventName, $payload = null): ThemeEvent
|
||||
{
|
||||
$themeEvent = new ThemeEvent($this->user->getUser(), $payload);
|
||||
/** @var AppVariable $app */
|
||||
$app = $environment->getGlobals()['app'];
|
||||
/** @var User $user */
|
||||
$user = $app->getUser();
|
||||
|
||||
$themeEvent = new ThemeEvent($user, $payload);
|
||||
|
||||
if ($this->eventDispatcher->hasListeners($eventName)) {
|
||||
$this->eventDispatcher->dispatch($themeEvent, $eventName);
|
||||
32
src/Twig/Runtime/TimesheetExtension.php
Normal file
32
src/Twig/Runtime/TimesheetExtension.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?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\Runtime;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class TimesheetExtension implements RuntimeExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @var TimesheetRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
public function __construct(TimesheetRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
public function activeEntries(User $user): array
|
||||
{
|
||||
return $this->repository->getActiveEntries($user);
|
||||
}
|
||||
}
|
||||
53
src/Twig/Runtime/WidgetExtension.php
Normal file
53
src/Twig/Runtime/WidgetExtension.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?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\Runtime;
|
||||
|
||||
use App\Widget\WidgetException;
|
||||
use App\Widget\WidgetInterface;
|
||||
use App\Widget\WidgetService;
|
||||
use Twig\Extension\RuntimeExtensionInterface;
|
||||
|
||||
final class WidgetExtension implements RuntimeExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @var WidgetService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
public function __construct(WidgetService $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WidgetInterface|string $widget
|
||||
* @param array $options
|
||||
* @return string
|
||||
* @throws WidgetException
|
||||
*/
|
||||
public function renderWidget($widget, array $options = [])
|
||||
{
|
||||
if (!($widget instanceof WidgetInterface) && !\is_string($widget)) {
|
||||
throw new \InvalidArgumentException('Widget must either implement WidgetInterface or be a string');
|
||||
}
|
||||
|
||||
if (\is_string($widget)) {
|
||||
if (!$this->service->hasWidget($widget)) {
|
||||
throw new \InvalidArgumentException(sprintf('Unknown widget "%s" requested', $widget));
|
||||
}
|
||||
|
||||
$widget = $this->service->getWidget($widget);
|
||||
}
|
||||
|
||||
$renderer = $this->service->findRenderer($widget);
|
||||
|
||||
return $renderer->render($widget, $options);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user