performance improvements (#2329)

* remove work from constructor
* refactor twig extensions
* upgrade theme
* replace sub-request with direct template rendering
This commit is contained in:
Kevin Papst
2021-02-20 23:52:01 +01:00
committed by GitHub
parent 9eb25c412e
commit 607d09aefb
40 changed files with 992 additions and 1092 deletions

View 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;
}
}

View 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;
}
}

View 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)) . ' &hellip;';
}
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);
}
}

View File

@@ -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);

View 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);
}
}

View 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);
}
}