backports murph-skeleton
This commit is contained in:
parent
ccff3b0301
commit
dbe9287314
|
@ -23,6 +23,10 @@ services:
|
|||
tags:
|
||||
- { name: kernel.event_listener, event: kernel.exception }
|
||||
|
||||
App\Core\EventListener\NodeViewListener:
|
||||
tags:
|
||||
- { name: kernel.event_listener, event: kernel.request }
|
||||
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
|
|
102
core/Entity/NodeView.php
Normal file
102
core/Entity/NodeView.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\Entity;
|
||||
|
||||
use App\Core\Entity\Site\Node;
|
||||
use App\Repository\Entity\NodeViewRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use App\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=NodeViewRepository::class)
|
||||
*/
|
||||
class NodeView implements EntityInterface
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Node::class, inversedBy="nodeViews")
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
*/
|
||||
private $node;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", options={"default"=0})
|
||||
*/
|
||||
private $views = 0;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date")
|
||||
*/
|
||||
private $date;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getNode(): ?Node
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
public function setNode(?Node $node): self
|
||||
{
|
||||
$this->node = $node;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPath(): ?string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setPath(string $path): self
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViews(): ?int
|
||||
{
|
||||
return $this->views;
|
||||
}
|
||||
|
||||
public function setViews(int $views): self
|
||||
{
|
||||
$this->views = $views;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addView(): self
|
||||
{
|
||||
++$this->views;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDate(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function setDate(\DateTimeInterface $date): self
|
||||
{
|
||||
$this->date = $date;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace App\Core\Entity\Site;
|
|||
|
||||
use App\Core\Doctrine\Timestampable;
|
||||
use App\Core\Entity\EntityInterface;
|
||||
use App\Core\Entity\NodeView;
|
||||
use App\Core\Entity\Site\Page\Page;
|
||||
use App\Core\Repository\Site\NodeRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
@ -139,10 +140,21 @@ class Node implements EntityInterface
|
|||
*/
|
||||
protected $contentType;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default"=0})
|
||||
*/
|
||||
private $enableViewCounter = false;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=NodeView::class, mappedBy="node", orphanRemoval=true)
|
||||
*/
|
||||
private $nodeViews;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->children = new ArrayCollection();
|
||||
$this->aliasNodes = new ArrayCollection();
|
||||
$this->nodeViews = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
|
@ -548,4 +560,46 @@ class Node implements EntityInterface
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEnableViewCounter(): ?bool
|
||||
{
|
||||
return $this->enableViewCounter;
|
||||
}
|
||||
|
||||
public function setEnableViewCounter(bool $enableViewCounter): self
|
||||
{
|
||||
$this->enableViewCounter = $enableViewCounter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|NodeView[]
|
||||
*/
|
||||
public function getNodeViews(): Collection
|
||||
{
|
||||
return $this->nodeViews;
|
||||
}
|
||||
|
||||
public function addNodeView(NodeView $nodeView): self
|
||||
{
|
||||
if (!$this->nodeViews->contains($nodeView)) {
|
||||
$this->nodeViews[] = $nodeView;
|
||||
$nodeView->setNode($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeNodeView(NodeView $nodeView): self
|
||||
{
|
||||
if ($this->nodeViews->removeElement($nodeView)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($nodeView->getNode() === $this) {
|
||||
$nodeView->setNode(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
68
core/EventListener/NodeViewListener.php
Normal file
68
core/EventListener/NodeViewListener.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\EventListener;
|
||||
|
||||
use App\Core\Factory\NodeViewFactory;
|
||||
use App\Core\Manager\EntityManager;
|
||||
use App\Core\Repository\NodeViewRepositoryQuery;
|
||||
use App\Core\Repository\Site\NodeRepositoryQuery;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use App\Core\Repository\Site\NodeRepository;
|
||||
|
||||
/**
|
||||
* class NodeViewListener.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
class NodeViewListener
|
||||
{
|
||||
protected NodeRepository $nodeRepository;
|
||||
protected NodeViewRepositoryQuery $nodeViewRepositoryQuery;
|
||||
protected NodeViewFactory $nodeViewFactory;
|
||||
protected EntityManager $manager;
|
||||
|
||||
public function __construct(
|
||||
NodeRepository $nodeRepository,
|
||||
NodeViewRepositoryQuery $nodeViewRepositoryQuery,
|
||||
NodeViewFactory $nodeViewFactory,
|
||||
EntityManager $manager
|
||||
) {
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->nodeViewRepositoryQuery = $nodeViewRepositoryQuery;
|
||||
$this->nodeViewFactory = $nodeViewFactory;
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
public function onKernelRequest(RequestEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
if (!$request->attributes->has('_node')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $this->nodeRepository->findOneById($request->attributes->get('_node'));
|
||||
|
||||
if (!$node || !$node->getEnableViewCounter()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nodeView = $this->nodeViewRepositoryQuery->create()
|
||||
->filterByRequest($request)
|
||||
->andWhere('.date=CURRENT_DATE()')
|
||||
->findOne()
|
||||
;
|
||||
|
||||
if (!$nodeView) {
|
||||
$nodeView = $this->nodeViewFactory->create($node, $request->getPathInfo());
|
||||
}
|
||||
|
||||
$nodeView->addView();
|
||||
|
||||
if ($nodeView->getId()) {
|
||||
$this->manager->update($nodeView);
|
||||
} else {
|
||||
$this->manager->create($nodeView);
|
||||
}
|
||||
}
|
||||
}
|
21
core/Factory/NodeViewFactory.php
Normal file
21
core/Factory/NodeViewFactory.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\Factory;
|
||||
|
||||
use App\Core\Entity\NodeView as Entity;
|
||||
use App\Core\Entity\Site\Node;
|
||||
|
||||
class NodeViewFactory implements FactoryInterface
|
||||
{
|
||||
public function create(Node $node, string $path): Entity
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity
|
||||
->setNode($node)
|
||||
->setPath($path)
|
||||
->setDate(new \DateTime())
|
||||
;
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
|
@ -60,6 +60,19 @@ class NodeType extends AbstractType
|
|||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'enableViewCounter',
|
||||
CheckboxType::class,
|
||||
[
|
||||
'label' => 'Enable view counter',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
],
|
||||
'constraints' => [
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'code',
|
||||
TextType::class,
|
||||
|
|
21
core/Repository/NodeViewRepository.php
Normal file
21
core/Repository/NodeViewRepository.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\Repository;
|
||||
|
||||
use App\Core\Entity\NodeView;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method NodeView|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method NodeView|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method NodeView[] findAll()
|
||||
* @method NodeView[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class NodeViewRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, NodeView::class);
|
||||
}
|
||||
}
|
27
core/Repository/NodeViewRepositoryQuery.php
Normal file
27
core/Repository/NodeViewRepositoryQuery.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\Repository;
|
||||
|
||||
use App\Core\Repository\NodeViewRepository as Repository;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class NodeViewRepositoryQuery extends RepositoryQuery
|
||||
{
|
||||
public function __construct(Repository $repository, PaginatorInterface $paginator)
|
||||
{
|
||||
parent::__construct($repository, 'n', $paginator);
|
||||
}
|
||||
|
||||
public function filterByRequest(Request $request)
|
||||
{
|
||||
return $this
|
||||
->andWhere('.node = :node')
|
||||
->andWhere('.path = :path')
|
||||
->setParameters([
|
||||
':node' => $request->attributes->get('_node'),
|
||||
':path' => $request->getPathInfo(),
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
|
@ -39,6 +39,8 @@
|
|||
"Never": "Jamais"
|
||||
"URL": "URL"
|
||||
"Disable URL": "Désactiver l'URL"
|
||||
"Enable view counter": "Activer le compteur de vues"
|
||||
"Stats": "Statistiques"
|
||||
"Controller": "Contrôleur"
|
||||
"Leave blank for automatic generation": "Laisser vide pour une génération automatique"
|
||||
"Leave blank to use the default one. Example: App\\Controller\\FooController::barAction": "Laisser vide pour utiliser celui par défaut. Exemple : App\\Controller\\FooController::barAction"
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
</div>
|
||||
|
||||
{{ form_row(form.disableUrl) }}
|
||||
{{ form_row(form.enableViewCounter) }}
|
||||
{{ form_row(form.code) }}
|
||||
{{ form_row(form.contentType) }}
|
||||
{{ form_row(form.controller) }}
|
||||
|
|
Loading…
Reference in a new issue