Skip to content

Commit dccfe57

Browse files
committed
Initial commit
0 parents  commit dccfe57

16 files changed

+1037
-0
lines changed

Admin/SchemaOrgEventAdmin.php

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
/*
3+
* This file is part of the Sulu Schema.org Event bundle.
4+
*
5+
* (c) bitExpert AG
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace UnKonf\Sulu\SchemaOrgEventBundle\Admin;
13+
14+
use Sulu\Bundle\AdminBundle\Admin\Admin;
15+
use Sulu\Bundle\AdminBundle\Admin\View\ToolbarAction;
16+
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface;
17+
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection;
18+
use Sulu\Bundle\PageBundle\Admin\PageAdmin;
19+
use Sulu\Component\Security\Authorization\PermissionTypes;
20+
use Sulu\Component\Security\Authorization\SecurityCheckerInterface;
21+
use Sulu\Component\Security\Authorization\SecurityCondition;
22+
use UnKonf\Sulu\SchemaOrgEventBundle\Entity\Event;
23+
24+
class SchemaOrgEventAdmin extends Admin
25+
{
26+
final public const SYSTEM = 'UnKonf';
27+
final public const SECURITY_CONTEXT = 'unkonf.schemaorgevent';
28+
final public const SCHEMAORGEVENT_LIST_KEY = 'schemaorgevent';
29+
final public const SCHEMAORGEVENT_LIST_VIEW = 'app.schemaorgevent_list';
30+
31+
public function __construct(
32+
private readonly ViewBuilderFactoryInterface $viewBuilderFactory,
33+
private readonly SecurityCheckerInterface $securityChecker
34+
) {
35+
}
36+
37+
public function configureViews(ViewCollection $viewCollection): void
38+
{
39+
$securityCondition = new SecurityCondition(static::SECURITY_CONTEXT, null, null, null, self::SYSTEM);
40+
41+
$toolbarActions = [];
42+
43+
if ($this->securityChecker->hasPermission($securityCondition, PermissionTypes::ADD)) {
44+
$toolbarActions[] = new ToolbarAction('sulu_admin.add');
45+
}
46+
47+
if ($this->securityChecker->hasPermission($securityCondition, PermissionTypes::DELETE)) {
48+
$toolbarActions[] = new ToolbarAction('sulu_admin.delete');
49+
}
50+
51+
if ($this->securityChecker->hasPermission($securityCondition, PermissionTypes::VIEW)) {
52+
$viewCollection->add(
53+
$this->viewBuilderFactory
54+
->createFormOverlayListViewBuilder(static::SCHEMAORGEVENT_LIST_VIEW, '/schemaorgevent')
55+
->setResourceKey(Event::RESOURCE_KEY)
56+
->setListKey(self::SCHEMAORGEVENT_LIST_KEY)
57+
->addListAdapters(['table'])
58+
->addAdapterOptions(['table' => ['skin' => 'light']])
59+
->addRouterAttributesToListRequest(['webspace'])
60+
->addRouterAttributesToFormRequest(['webspace'])
61+
->disableSearching()
62+
->setFormKey('schemaorgevent_details')
63+
->setTabTitle('schemaorgevent.title')
64+
->setTabOrder(2048)
65+
->addToolbarActions($toolbarActions)
66+
->setParent(PageAdmin::WEBSPACE_TABS_VIEW)
67+
->addRerenderAttribute('webspace')
68+
);
69+
}
70+
}
71+
72+
public function getSecurityContexts()
73+
{
74+
return [
75+
self::SYSTEM => [
76+
'SchemaOrgEvent' => [
77+
static::SECURITY_CONTEXT => [
78+
PermissionTypes::VIEW,
79+
PermissionTypes::ADD,
80+
PermissionTypes::DELETE,
81+
],
82+
],
83+
],
84+
];
85+
}
86+
87+
public function getConfigKey(): ?string
88+
{
89+
return 'unkonf.schemaorgevent';
90+
}
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/*
3+
* This file is part of the Sulu Schema.org Event bundle.
4+
*
5+
* (c) bitExpert AG
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace UnKonf\Sulu\SchemaOrgEventBundle\Common;
13+
14+
use Sulu\Component\Rest\ListBuilder\Doctrine\DoctrineListBuilder;
15+
use Sulu\Component\Rest\ListBuilder\Doctrine\DoctrineListBuilderFactoryInterface;
16+
use Sulu\Component\Rest\ListBuilder\Doctrine\FieldDescriptor\DoctrineFieldDescriptor;
17+
use Sulu\Component\Rest\ListBuilder\ListRestHelperInterface;
18+
use Sulu\Component\Rest\ListBuilder\Metadata\FieldDescriptorFactoryInterface;
19+
use Sulu\Component\Rest\ListBuilder\PaginatedRepresentation;
20+
use Sulu\Component\Rest\RestHelperInterface;
21+
22+
class DoctrineListRepresentationFactory
23+
{
24+
public function __construct(
25+
private readonly RestHelperInterface $restHelper,
26+
private readonly ListRestHelperInterface $listRestHelper,
27+
private readonly DoctrineListBuilderFactoryInterface $listBuilderFactory,
28+
private readonly FieldDescriptorFactoryInterface $fieldDescriptorFactory,
29+
) {
30+
}
31+
32+
/**
33+
* @param array<string, string> $filters
34+
* @param array<string, string|int|null> $parameters
35+
* @param string[] $includedFields
36+
*/
37+
public function createDoctrineListRepresentation(
38+
string $resourceKey,
39+
array $filters = [],
40+
array $parameters = [],
41+
array $includedFields = [],
42+
): PaginatedRepresentation {
43+
/** @var DoctrineFieldDescriptor[] $fieldDescriptors */
44+
$fieldDescriptors = $this->fieldDescriptorFactory->getFieldDescriptors($resourceKey);
45+
46+
/** @var DoctrineListBuilder $listBuilder */
47+
$listBuilder = $this->listBuilderFactory->create($fieldDescriptors['id']->getEntityName());
48+
$this->restHelper->initializeListBuilder($listBuilder, $fieldDescriptors);
49+
50+
foreach ($parameters as $key => $value) {
51+
$listBuilder->setParameter($key, $value);
52+
}
53+
54+
foreach ($filters as $key => $value) {
55+
$listBuilder->where($fieldDescriptors[$key], $value);
56+
}
57+
58+
foreach ($includedFields as $field) {
59+
$listBuilder->addSelectField($fieldDescriptors[$field]);
60+
}
61+
62+
$items = $listBuilder->execute();
63+
64+
// sort the items to reflect the order of the given ids if the list was requested to include specific ids
65+
/** @var array<int, int>|null $requestedIds */
66+
$requestedIds = $this->listRestHelper->getIds();
67+
if (null !== $requestedIds) {
68+
$idPositions = \array_flip($requestedIds);
69+
70+
\usort($items, fn ($a, $b) => $idPositions[$a['id']] - $idPositions[$b['id']]);
71+
}
72+
73+
return new PaginatedRepresentation(
74+
$items,
75+
$resourceKey,
76+
(int) $listBuilder->getCurrentPage(),
77+
(int) $listBuilder->getLimit(),
78+
(int) $listBuilder->count(),
79+
);
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
/*
3+
* This file is part of the Sulu Schema.org Event bundle.
4+
*
5+
* (c) bitExpert AG
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace UnKonf\Sulu\SchemaOrgEventBundle\Controller\Admin;
13+
14+
use UnKonf\Sulu\SchemaOrgEventBundle\Common\DoctrineListRepresentationFactory;
15+
use UnKonf\Sulu\SchemaOrgEventBundle\Entity\Event;
16+
use UnKonf\Sulu\SchemaOrgEventBundle\Entity\Location;
17+
use UnKonf\Sulu\SchemaOrgEventBundle\Entity\Offer;
18+
use UnKonf\Sulu\SchemaOrgEventBundle\Repository\EventRepository;
19+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
20+
use Symfony\Component\HttpFoundation\Request;
21+
use Symfony\Component\HttpFoundation\Response;
22+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
23+
use Symfony\Component\Routing\Annotation\Route;
24+
25+
/**
26+
* @phpstan-type SchemaOrgEventData array{
27+
* id: int|null,
28+
* webspace_key: string|null,
29+
* name: string,
30+
* startDate: string,
31+
* endDate: string,
32+
* location_name: string,
33+
* location_street: string,
34+
* location_zipCode: string,
35+
* location_city: string,
36+
* location_country: string,
37+
* offer_name: string,
38+
* offer_price: int,
39+
* offer_currency: string,
40+
* offer_validFrom: string,
41+
* offer_url: string
42+
* }
43+
*/
44+
class SchemaOrgEventAdminController extends AbstractController
45+
{
46+
public function __construct(
47+
private readonly EventRepository $repository,
48+
private readonly DoctrineListRepresentationFactory $doctrineListRepresentationFactory,
49+
) {
50+
}
51+
52+
#[Route(path: 'schemaorgevent/{id}', name: 'app.get_schemaorgevent', methods: ['GET'])]
53+
public function getAction(int $id): Response
54+
{
55+
$entity = $this->repository->findById($id);
56+
if (!$entity instanceof Event) {
57+
throw new NotFoundHttpException();
58+
}
59+
60+
return $this->json($this->getDataForEntity($entity));
61+
}
62+
63+
#[Route(path: 'schemaorgevent/{id}', name: 'app.put_schemaorgevent', methods: ['PUT'])]
64+
public function putAction(int $id, Request $request): Response
65+
{
66+
$entity = $this->repository->findById($id);
67+
if (!$entity instanceof Event) {
68+
throw new NotFoundHttpException();
69+
}
70+
71+
/** @var SchemaOrgEventData $data */
72+
$data = $request->toArray();
73+
$this->mapDataToEntity($data, $entity);
74+
75+
$this->repository->save($entity);
76+
77+
return $this->json($this->getDataForEntity($entity));
78+
}
79+
80+
#[Route(path: 'schemaorgevent', name: 'app.post_schemaorgevent', methods: ['POST'])]
81+
public function postAction(Request $request): Response
82+
{
83+
$entity = $this->repository->create();
84+
85+
/** @var SchemaOrgEventData $data */
86+
$data = $request->toArray();
87+
$data['webspace_key'] = $request->get('webspace');
88+
$this->mapDataToEntity($data, $entity);
89+
90+
$this->repository->save($entity);
91+
92+
return $this->json($this->getDataForEntity($entity), 201);
93+
}
94+
95+
#[Route(path: 'schemaorgevent/{id}', name: 'app.delete_schemaorgevent', methods: ['DELETE'])]
96+
public function deleteAction(int $id): Response
97+
{
98+
$this->repository->remove($id);
99+
100+
return $this->json(null, 204);
101+
}
102+
103+
#[Route(path: 'schemaorgevent', name: 'app.get_schemaorgevent_list', methods: ['GET'])]
104+
public function getListAction(): Response
105+
{
106+
$listRepresentation = $this->doctrineListRepresentationFactory->createDoctrineListRepresentation(
107+
Event::RESOURCE_KEY,
108+
);
109+
110+
return $this->json($listRepresentation->toArray());
111+
}
112+
113+
/**
114+
* @param Event $entity
115+
* @return SchemaOrgEventData
116+
*/
117+
protected function getDataForEntity(Event $entity): array
118+
{
119+
return [
120+
'id' => $entity->getId(),
121+
'webspace_key' => $entity->getWebspaceKey(),
122+
'name' => $entity->getName() ?? '',
123+
'startDate' => $entity->getStartDate(),
124+
'endDate' => $entity->getEndDate(),
125+
'location_name' => $entity->getLocation()->getName(),
126+
'location_street' => $entity->getLocation()->getStreet(),
127+
'location_zipCode' => $entity->getLocation()->getZipCode(),
128+
'location_city' => $entity->getLocation()->getCity(),
129+
'location_country' => $entity->getLocation()->getCountry(),
130+
'offer_name' => $entity->getOffer()->getName(),
131+
'offer_price' => $entity->getOffer()->getPrice(),
132+
'offer_currency' => $entity->getOffer()->getCurrency(),
133+
'offer_validFrom' => $entity->getOffer()->getValidFrom(),
134+
'offer_url' => $entity->getOffer()->getUrl(),
135+
];
136+
}
137+
138+
/**
139+
* @param SchemaOrgEventData $data
140+
* @param Event $entity
141+
*/
142+
protected function mapDataToEntity(array $data, Event $entity): void
143+
{
144+
$location = new Location();
145+
$location->setName($data['location_name']);
146+
$location->setStreet($data['location_street']);
147+
$location->setZipCode($data['location_zipCode']);
148+
$location->setCity($data['location_city']);
149+
$location->setCountry($data['location_country']);
150+
151+
$offer = new Offer();
152+
$offer->setName($data['offer_name']);
153+
$offer->setPrice($data['offer_price']);
154+
$offer->setCurrency($data['offer_currency']);
155+
$offer->setValidFrom($data['offer_validFrom']);
156+
$offer->setUrl($data['offer_url']);
157+
158+
$entity->setWebspaceKey($data['webspace_key']);
159+
$entity->setName($data['name']);
160+
$entity->setStartDate($data['startDate']);
161+
$entity->setEndDate($data['endDate']);
162+
$entity->setLocation($location);
163+
$entity->setOffer($offer);
164+
}
165+
}

0 commit comments

Comments
 (0)