Skip to content

Commit

Permalink
Add route to event entity
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasnatter committed Feb 3, 2021
1 parent 2f49214 commit 6ef010e
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config/forms/event_details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
<params>
<param name="headline" value="true"/>
</params>

<tag name="sulu.rlp.part"/>
</property>

<property name="routePath" type="route" mandatory="true">
<meta>
<title>sulu_admin.url</title>
</meta>
</property>

<property name="image" type="single_media_selection" colspan="12">
Expand Down
8 changes: 8 additions & 0 deletions config/packages/app_event_admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ sulu_admin:
routes:
list: 'app.get_events'
detail: 'app.get_event'

sulu_route:
mappings:
App\Entity\Event:
generator: schema
options:
route_schema: /events/{implode("-", object)}
resource_key: events
4 changes: 4 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
Sulu\Bundle\SnippetBundle\Snippet\DefaultSnippetManagerInterface: '@sulu_snippet.default_snippet.manager'
Sulu\Component\PHPCR\PathCleanupInterface: '@sulu.content.path_cleaner'
Doctrine\ORM\EntityManagerInterface: '@doctrine.orm.entity_manager'
Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface: '@sulu.repository.route'

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
Expand Down Expand Up @@ -47,3 +48,6 @@ services:

App\Content\Type\AlbumSelection:
tags: [{name: 'sulu.content.type', alias: 'album_selection'}]

App\Routing\EventRouteDefaultsProvider:
tags: [{ name: 'sulu_route.defaults_provider' }]
47 changes: 47 additions & 0 deletions src/Controller/Admin/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
use HandcraftedInTheAlps\RestRoutingBundle\Controller\Annotations\RouteResource;
use HandcraftedInTheAlps\RestRoutingBundle\Routing\ClassResourceInterface;
use Sulu\Bundle\MediaBundle\Media\Manager\MediaManagerInterface;
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface;
use Sulu\Component\Rest\AbstractRestController;
use Sulu\Component\Security\SecuredControllerInterface;
use Sulu\Component\Webspace\Manager\WebspaceManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Expand All @@ -26,17 +29,26 @@ class EventController extends AbstractRestController implements ClassResourceInt
private DoctrineListRepresentationFactory $doctrineListRepresentationFactory;
private EntityManagerInterface $entityManager;
private MediaManagerInterface $mediaManager;
private WebspaceManagerInterface $webspaceManager;
private RouteManagerInterface $routeManager;
private RouteRepositoryInterface $routeRepository;

public function __construct(
DoctrineListRepresentationFactory $doctrineListRepresentationFactory,
EntityManagerInterface $entityManager,
MediaManagerInterface $mediaManager,
WebspaceManagerInterface $webspaceManager,
RouteManagerInterface $routeManager,
RouteRepositoryInterface $routeRepository,
ViewHandlerInterface $viewHandler,
?TokenStorageInterface $tokenStorage = null
) {
$this->doctrineListRepresentationFactory = $doctrineListRepresentationFactory;
$this->entityManager = $entityManager;
$this->mediaManager = $mediaManager;
$this->webspaceManager = $webspaceManager;
$this->routeManager = $routeManager;
$this->routeRepository = $routeRepository;

parent::__construct($viewHandler, $tokenStorage);
}
Expand Down Expand Up @@ -68,6 +80,7 @@ public function putAction(Request $request, int $id): Response
}

$this->mapDataToEntity($request->request->all(), $event);
$this->updateRoutesForEntity($event);
$this->entityManager->flush();

return $this->handleView($this->view($event));
Expand All @@ -81,13 +94,17 @@ public function postAction(Request $request): Response
$this->entityManager->persist($event);
$this->entityManager->flush();

$this->updateRoutesForEntity($event);
$this->entityManager->flush();

return $this->handleView($this->view($event, 201));
}

public function deleteAction(int $id): Response
{
/** @var Event $event */
$event = $this->entityManager->getReference(Event::class, $id);
$this->removeRoutesForEntity($event);
$this->entityManager->remove($event);
$this->entityManager->flush();

Expand All @@ -102,11 +119,41 @@ protected function mapDataToEntity(array $data, Event $entity): void
$imageId = $data['image']['id'] ?? null;

$entity->setName($data['name']);
$entity->setRoutePath($data['routePath']);
$entity->setImage($imageId ? $this->mediaManager->getEntityById($imageId) : null);
$entity->setStartDate($data['startDate'] ? new \DateTimeImmutable($data['startDate']) : null);
$entity->setEndDate($data['endDate'] ? new \DateTimeImmutable($data['endDate']) : null);
}

protected function updateRoutesForEntity(Event $entity): void
{
// create route for all locales of the application because event entity is not localized
foreach ($this->webspaceManager->getAllLocales() as $locale) {
$this->routeManager->createOrUpdateByAttributes(
Event::class,
(string) $entity->getId(),
$locale,
$entity->getRoutePath(),
);
}
}

protected function removeRoutesForEntity(Event $entity): void
{
// remove route for all locales of the application because event entity is not localized
foreach ($this->webspaceManager->getAllLocales() as $locale) {
$routes = $this->routeRepository->findAllByEntity(
Event::class,
(string) $entity->getId(),
$locale
);

foreach ($routes as $route) {
$this->routeRepository->remove($route);
}
}
}

public function getSecurityContext(): string
{
return Event::SECURITY_CONTEXT;
Expand Down
60 changes: 60 additions & 0 deletions src/Controller/Website/EventController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace App\Controller\Website;

use App\Entity\Event;
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
use Sulu\Bundle\WebsiteBundle\Resolver\TemplateAttributeResolverInterface;
use Sulu\Component\Webspace\Manager\WebspaceManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class EventController extends AbstractController
{
public function indexAction(Event $event): Response
{
$parameters = $this->get('sulu_website.resolver.template_attribute')->resolve([
'event' => $event,
'localizations' => $this->getLocalizationsArrayForEntity($event),
]);

return $this->render('events/event.html.twig', $parameters);
}

/**
* @return array<string, array>
*/
protected function getLocalizationsArrayForEntity(Event $entity): array
{
$routes = $this->get('sulu.repository.route')->findAllByEntity(Event::class, (string) $entity->getId());

$localizations = [];
foreach ($routes as $route) {
$url = $this->get('sulu_core.webspace.webspace_manager')->findUrlByResourceLocator(
$route->getPath(),
null,
$route->getLocale()
);

$localizations[$route->getLocale()] = ['locale' => $route->getLocale(), 'url' => $url];
}

return $localizations;
}

/**
* @return string[]
*/
public static function getSubscribedServices()
{
$subscribedServices = parent::getSubscribedServices();

$subscribedServices['sulu_core.webspace.webspace_manager'] = WebspaceManagerInterface::class;
$subscribedServices['sulu.repository.route'] = RouteRepositoryInterface::class;
$subscribedServices['sulu_website.resolver.template_attribute'] = TemplateAttributeResolverInterface::class;

return $subscribedServices;
}
}
17 changes: 17 additions & 0 deletions src/Entity/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ class Event
*/
private string $name;

/**
* @ORM\Column(type="string", length=255)
*
* @Serializer\Expose()
*/
private string $routePath;

/**
* @ORM\ManyToOne(targetEntity=MediaInterface::class)
* @ORM\JoinColumn(onDelete="SET NULL")
Expand Down Expand Up @@ -69,6 +76,16 @@ public function setName(string $name): void
$this->name = $name;
}

public function getRoutePath(): string
{
return $this->routePath ?? '';
}

public function setRoutePath(string $routePath): void
{
$this->routePath = $routePath;
}

public function getImage(): ?MediaInterface
{
return $this->image;
Expand Down
40 changes: 40 additions & 0 deletions src/Routing/EventRouteDefaultsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Routing;

use App\Controller\Website\EventController;
use App\Entity\Event;
use Doctrine\ORM\EntityManagerInterface;
use Sulu\Bundle\RouteBundle\Routing\Defaults\RouteDefaultsProviderInterface;

class EventRouteDefaultsProvider implements RouteDefaultsProviderInterface
{
private EntityManagerInterface $entityManager;

public function __construct(
EntityManagerInterface $entityManager
) {
$this->entityManager = $entityManager;
}

/**
* @return mixed[]
*/
public function getByEntity($entityClass, $id, $locale, $object = null)
{
return [
'_controller' => EventController::class . '::indexAction',
'event' => $object ?: $this->entityManager->getRepository(Event::class)->find($id),
];
}

public function isPublished($entityClass, $id, $locale)
{
return true;
}

public function supports($entityClass)
{
return Event::class === $entityClass;
}
}
5 changes: 5 additions & 0 deletions templates/events/event.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends 'base.html.twig' %}

{% block contentBody %}
<h1>{{ event.name }}</h1>
{% endblock %}

0 comments on commit 6ef010e

Please sign in to comment.