Skip to content

Commit

Permalink
feat(Log): Added Twig Log extension to generate link to entities edit…
Browse files Browse the repository at this point in the history
… pages
  • Loading branch information
ambroisemaupate committed Jun 28, 2023
1 parent 7300cc3 commit 471a571
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 85 deletions.
148 changes: 95 additions & 53 deletions lib/RoadizCoreBundle/src/Logger/DoctrineHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
use Monolog\Logger;
use RZ\Roadiz\Core\AbstractEntities\PersistableInterface;
use RZ\Roadiz\CoreBundle\Entity\Log;
use RZ\Roadiz\CoreBundle\Entity\Node;
use RZ\Roadiz\CoreBundle\Entity\NodesSources;
use RZ\Roadiz\CoreBundle\Entity\User;
use RZ\Roadiz\Documents\Models\DocumentInterface;
use RZ\Roadiz\Documents\UrlGenerators\DocumentUrlGeneratorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
Expand All @@ -22,9 +24,9 @@
*/
final class DoctrineHandler extends AbstractProcessingHandler
{
protected ManagerRegistry $managerRegistry;
protected TokenStorageInterface $tokenStorage;
protected RequestStack $requestStack;
private ManagerRegistry $managerRegistry;
private TokenStorageInterface $tokenStorage;
private RequestStack $requestStack;
private DocumentUrlGeneratorInterface $documentUrlGenerator;

public function __construct(
Expand All @@ -35,30 +37,85 @@ public function __construct(
$level = Logger::INFO,
$bubble = true
) {
parent::__construct($level, $bubble);
$this->tokenStorage = $tokenStorage;
$this->requestStack = $requestStack;
$this->managerRegistry = $managerRegistry;

parent::__construct($level, $bubble);
$this->documentUrlGenerator = $documentUrlGenerator;
}

/**
* @return TokenStorageInterface
*/
public function getTokenStorage(): TokenStorageInterface
protected function getThumbnailSourcePath(?DocumentInterface $thumbnail): ?string
{
return $this->tokenStorage;
if (null === $thumbnail) {
return null;
}
return $this->documentUrlGenerator
->setDocument($thumbnail)
->setOptions([
"fit" => "150x150",
"quality" => 70,
])
->getUrl();
}
/**
* @param TokenStorageInterface $tokenStorage
*
* @return $this
*/
public function setTokenStorage(TokenStorageInterface $tokenStorage): DoctrineHandler

protected function populateForNode(Node $value, Log $log, array &$data): void
{
$this->tokenStorage = $tokenStorage;
return $this;
$log->setEntityClass(Node::class);
$log->setEntityId($value->getId());
$data = array_merge(
$data,
[
'node_id' => $value->getId(),
'entity_title' => $value->getNodeName(),
]
);
$nodeSource = $value->getNodeSources()->first() ?: null;
if (null !== $nodeSource) {
$data = array_merge(
$data,
[
'node_source_id' => $nodeSource->getId(),
'translation_id' => $nodeSource->getTranslation()->getId(),
'entity_title' => $nodeSource->getTitle() ?? $value->getNodeName(),
]
);
}

$thumbnailSrc = $this->getThumbnailSourcePath($nodeSource?->getOneDisplayableDocument());
if (null !== $thumbnailSrc) {
$data = array_merge(
$data,
[
'entity_thumbnail_src' => $thumbnailSrc,
]
);
}
}

protected function populateForNodesSources(NodesSources $value, Log $log, array &$data): void
{
$log->setEntityClass(NodesSources::class);
$log->setEntityId($value->getId());
$data = array_merge(
$data,
[
'node_source_id' => $value->getId(),
'node_id' => $value->getNode()->getId(),
'translation_id' => $value->getTranslation()->getId(),
'entity_title' => $value->getTitle(),
]
);

$thumbnail = $value->getOneDisplayableDocument();
$thumbnailSrc = $this->getThumbnailSourcePath($thumbnail);
if (null !== $thumbnailSrc) {
$data = array_merge(
$data,
[
'entity_thumbnail_src' => $thumbnailSrc,
]
);
}
}

/**
Expand All @@ -83,45 +140,33 @@ public function write(array $record): void

if (\is_array($context)) {
foreach ($context as $key => $value) {
if ($value instanceof NodesSources) {
$log->setEntityClass(NodesSources::class);
$log->setEntityId($value->getId());
$data = array_merge(
$data,
[
'node_source_id' => $value->getId(),
'node_id' => $value->getNode()->getId(),
'translation_id' => $value->getTranslation()->getId(),
'entity_title' => $value->getTitle(),
]
);

$thumbnail = $value->getOneDisplayableDocument();
if (null !== $thumbnail) {
$thumbnailSrc = $this->documentUrlGenerator
->setDocument($thumbnail)
->setOptions([
"fit" => "150x150",
"quality" => 70,
])
->getUrl();

$data = array_merge(
$data,
[
'entity_thumbnail_src' => $thumbnailSrc,
]
);
}
if ($value instanceof Node) {
$this->populateForNode($value, $log, $data);
} elseif ($value instanceof NodesSources) {
$this->populateForNodesSources($value, $log, $data);
} elseif ($key === 'entity' && $value instanceof PersistableInterface) {
$log->setEntityClass(get_class($value));
$log->setEntityId($value->getId());

$texteable = ['getTitle', 'getName', '__toString'];
foreach ($texteable as $method) {
if (method_exists($value, $method)) {
$data = array_merge(
$data,
[
'entity_title' => $value->{$method}()
]
);
break;
}
}
}
if ($value instanceof \Exception) {
$data = array_merge(
$data,
[
get_class($value) => $value->getMessage()
'exception_class' => get_class($value),
'message' => $value->getMessage()
]
);
}
Expand Down Expand Up @@ -155,10 +200,7 @@ public function write(array $record): void
/*
* Use available securityAuthorizationChecker to provide a valid user
*/
if (
null !== $this->getTokenStorage() &&
null !== $token = $this->getTokenStorage()->getToken()
) {
if (null !== $token = $this->tokenStorage->getToken()) {
$user = $token->getUser();
if ($user instanceof UserInterface) {
if ($user instanceof User) {
Expand Down
6 changes: 3 additions & 3 deletions lib/RoadizCoreBundle/src/Repository/LogRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Persistence\ManagerRegistry;
use RZ\Roadiz\CoreBundle\Entity\Log;
use RZ\Roadiz\CoreBundle\Entity\Node;
use RZ\Roadiz\CoreBundle\Entity\NodesSources;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

Expand All @@ -31,17 +32,16 @@ public function __construct(
*/
public function findLatestByNodesSources(int $maxResult = 5): Paginator
{

$subQb = $this->createQueryBuilder('slog');
$subQb->select($subQb->expr()->max('slog.id'))
->andWhere($subQb->expr()->eq('slog.entityClass', ':entityClass'))
->andWhere($subQb->expr()->in('slog.entityClass', ':entityClass'))
->addGroupBy('slog.entityId');

$qb = $this->createQueryBuilder('log');
$qb->select('log.id as id')
->andWhere($qb->expr()->in('log.id', $subQb->getQuery()->getDQL()))
->orderBy('log.datetime', 'DESC')
->setParameter(':entityClass', NodesSources::class)
->setParameter(':entityClass', [NodesSources::class, Node::class])
->setMaxResults($maxResult)
;
$ids = $qb->getQuery()
Expand Down
119 changes: 119 additions & 0 deletions lib/RoadizCoreBundle/src/TwigExtension/LogExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\TwigExtension;

use RZ\Roadiz\CoreBundle\Entity\CustomForm;
use RZ\Roadiz\CoreBundle\Entity\CustomFormField;
use RZ\Roadiz\CoreBundle\Entity\Document;
use RZ\Roadiz\CoreBundle\Entity\Log;
use RZ\Roadiz\CoreBundle\Entity\Node;
use RZ\Roadiz\CoreBundle\Entity\NodesSources;
use RZ\Roadiz\CoreBundle\Entity\Setting;
use RZ\Roadiz\CoreBundle\Entity\Tag;
use RZ\Roadiz\CoreBundle\Entity\Translation;
use RZ\Roadiz\CoreBundle\Entity\User;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

final class LogExtension extends AbstractExtension
{
private Security $security;
private UrlGeneratorInterface $urlGenerator;

public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
{
$this->security = $security;
$this->urlGenerator = $urlGenerator;
}

public function getFunctions(): array
{
return [
new TwigFunction('log_entity_edit_path', [$this, 'getEditPath'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]),
];
}

public function getEditPath(?object $log): ?string
{
if (!($log instanceof Log)) {
return null;
}

switch ($log->getEntityClass()) {
case Node::class:
case NodesSources::class:
if (
$this->security->isGranted('ROLE_ACCESS_NODES') &&
isset($log->getAdditionalData()['node_id']) &&
isset($log->getAdditionalData()['translation_id'])
) {
return $this->urlGenerator->generate('nodesEditSourcePage', [
'nodeId' => $log->getAdditionalData()['node_id'],
'translationId' => $log->getAdditionalData()['translation_id'],
]);
}
break;
case Tag::class:
if (
$this->security->isGranted('ROLE_ACCESS_TAGS')
) {
return $this->urlGenerator->generate('tagsEditPage', [
'tagId' => $log->getEntityId(),
]);
}
break;
case Document::class:
if (
$this->security->isGranted('ROLE_ACCESS_DOCUMENTS')
) {
return $this->urlGenerator->generate('documentsEditPage', [
'documentId' => $log->getEntityId(),
]);
}
break;
case User::class:
if (
$this->security->isGranted('ROLE_ACCESS_USERS')
) {
return $this->urlGenerator->generate('usersEditPage', [
'userId' => $log->getEntityId(),
]);
}
break;
case CustomForm::class:
if (
$this->security->isGranted('ROLE_ACCESS_CUSTOMFORMS')
) {
return $this->urlGenerator->generate('customFormsEditPage', [
'id' => $log->getEntityId(),
]);
}
break;
case Translation::class:
if (
$this->security->isGranted('ROLE_ACCESS_TRANSLATIONS')
) {
return $this->urlGenerator->generate('translationsEditPage', [
'translationId' => $log->getEntityId(),
]);
}
break;
case Setting::class:
if (
$this->security->isGranted('ROLE_ACCESS_SETTINGS')
) {
return $this->urlGenerator->generate('settingsEditPage', [
'settingId' => $log->getEntityId(),
]);
}
break;

}

return null;
}
}
Loading

0 comments on commit 471a571

Please sign in to comment.