Skip to content

Commit 592b243

Browse files
wachterjohannesniklasnatter
authored andcommittedOct 23, 2020
10 - Add a form to add, edit or delete locations in the admin interface
1 parent ecbd097 commit 592b243

File tree

9 files changed

+429
-2
lines changed

9 files changed

+429
-2
lines changed
 

‎config/forms/location_details.xml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" ?>
2+
<form xmlns="http://schemas.sulu.io/template/template"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/form-1.0.xsd"
5+
>
6+
<key>location_details</key>
7+
8+
<properties>
9+
<property name="name" type="text_line" mandatory="true">
10+
<meta>
11+
<title>sulu_admin.name</title>
12+
</meta>
13+
</property>
14+
15+
<property name="street" type="text_line" colspan="9">
16+
<meta>
17+
<title>sulu_contact.street</title>
18+
</meta>
19+
</property>
20+
21+
<property name="number" type="text_line" colspan="3">
22+
<meta>
23+
<title>sulu_contact.number</title>
24+
</meta>
25+
</property>
26+
27+
<property name="postalCode" type="text_line" colspan="3">
28+
<meta>
29+
<title>sulu_contact.zip</title>
30+
</meta>
31+
</property>
32+
33+
<property name="city" type="text_line" colspan="6">
34+
<meta>
35+
<title>sulu_contact.city</title>
36+
</meta>
37+
</property>
38+
39+
<property name="countryCode" type="single_select" colspan="3">
40+
<meta>
41+
<title>sulu_contact.country</title>
42+
</meta>
43+
44+
<params>
45+
<param
46+
name="values"
47+
type="expression"
48+
value="service('app.country_select').getValues()"
49+
/>
50+
</params>
51+
</property>
52+
</properties>
53+
</form>

‎config/packages/sulu_admin.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ sulu_admin:
2121
locations:
2222
routes:
2323
list: app.get_locations
24+
detail: app.get_location
2425

2526
# Registering Selection Field Types in this section
2627
field_type_options:

‎config/services.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ services:
4949
bind:
5050
$repository: '@App\Repository\EventRepository'
5151

52+
app.country_select:
53+
class: App\Service\CountryCodeSelect
54+
public: true
55+
5256
# following service definitions will be removed in the website context of sulu
5357
App\Admin\:
5458
resource: '../src/Admin'

‎src/Admin/LocationAdmin.php

+44-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Sulu\Bundle\AdminBundle\Admin\Admin;
99
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItem;
1010
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItemCollection;
11+
use Sulu\Bundle\AdminBundle\Admin\View\ToolbarAction;
1112
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface;
1213
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection;
1314

@@ -17,6 +18,10 @@ class LocationAdmin extends Admin
1718

1819
const LOCATION_LIST_VIEW = 'app.locations_list';
1920

21+
const LOCATION_ADD_FORM_VIEW = 'app.location_add_form';
22+
23+
const LOCATION_EDIT_FORM_VIEW = 'app.location_edit_form';
24+
2025
/**
2126
* @var ViewBuilderFactoryInterface
2227
*/
@@ -40,12 +45,50 @@ public function configureNavigationItems(NavigationItemCollection $navigationIte
4045

4146
public function configureViews(ViewCollection $viewCollection): void
4247
{
48+
$listToolbarActions = [
49+
new ToolbarAction('sulu_admin.add'),
50+
new ToolbarAction('sulu_admin.delete'),
51+
];
4352
$listView = $this->viewBuilderFactory->createListViewBuilder(self::LOCATION_LIST_VIEW, '/locations')
4453
->setResourceKey(Location::RESOURCE_KEY)
4554
->setListKey(self::LOCATION_LIST_KEY)
4655
->setTitle('app.locations')
4756
->addListAdapters(['table'])
48-
->addToolbarActions([]);
57+
->setAddView(static::LOCATION_ADD_FORM_VIEW)
58+
->setEditView(static::LOCATION_EDIT_FORM_VIEW)
59+
->addToolbarActions($listToolbarActions);
4960
$viewCollection->add($listView);
61+
62+
$addFormView = $this->viewBuilderFactory->createResourceTabViewBuilder(self::LOCATION_ADD_FORM_VIEW, '/locations/add')
63+
->setResourceKey('locations')
64+
->setBackView(static::LOCATION_LIST_VIEW);
65+
$viewCollection->add($addFormView);
66+
67+
$addDetailsFormView = $this->viewBuilderFactory->createFormViewBuilder(self::LOCATION_ADD_FORM_VIEW . '.details', '/details')
68+
->setResourceKey('locations')
69+
->setFormKey('location_details')
70+
->setTabTitle('sulu_admin.details')
71+
->setEditView(static::LOCATION_EDIT_FORM_VIEW)
72+
->addToolbarActions([new ToolbarAction('sulu_admin.save')])
73+
->setParent(static::LOCATION_ADD_FORM_VIEW);
74+
$viewCollection->add($addDetailsFormView);
75+
76+
$editFormView = $this->viewBuilderFactory->createResourceTabViewBuilder(static::LOCATION_EDIT_FORM_VIEW, '/locations/:id')
77+
->setResourceKey('locations')
78+
->setBackView(static::LOCATION_LIST_VIEW)
79+
->setTitleProperty('title');
80+
$viewCollection->add($editFormView);
81+
82+
$formToolbarActions = [
83+
new ToolbarAction('sulu_admin.save'),
84+
new ToolbarAction('sulu_admin.delete'),
85+
];
86+
$editDetailsFormView = $this->viewBuilderFactory->createFormViewBuilder(static::LOCATION_EDIT_FORM_VIEW . '.details', '/details')
87+
->setResourceKey('locations')
88+
->setFormKey('location_details')
89+
->setTabTitle('sulu_admin.details')
90+
->addToolbarActions($formToolbarActions)
91+
->setParent(static::LOCATION_EDIT_FORM_VIEW);
92+
$viewCollection->add($editDetailsFormView);
5093
}
5194
}

‎src/Controller/Admin/LocationController.php

+85
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
use App\Common\DoctrineListRepresentationFactory;
88
use App\Entity\Location;
9+
use App\Repository\LocationRepository;
910
use FOS\RestBundle\Controller\Annotations\RouteResource;
1011
use FOS\RestBundle\Routing\ClassResourceInterface;
1112
use FOS\RestBundle\View\ViewHandlerInterface;
1213
use Sulu\Component\Rest\AbstractRestController;
14+
use Symfony\Component\HttpFoundation\Request;
1315
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1417
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1518

1619
/**
@@ -23,12 +26,19 @@ class LocationController extends AbstractRestController implements ClassResource
2326
*/
2427
private $doctrineListRepresentationFactory;
2528

29+
/**
30+
* @var LocationRepository
31+
*/
32+
private $repository;
33+
2634
public function __construct(
2735
DoctrineListRepresentationFactory $doctrineListRepresentationFactory,
36+
LocationRepository $repository,
2837
ViewHandlerInterface $viewHandler,
2938
?TokenStorageInterface $tokenStorage = null
3039
) {
3140
$this->doctrineListRepresentationFactory = $doctrineListRepresentationFactory;
41+
$this->repository = $repository;
3242

3343
parent::__construct($viewHandler, $tokenStorage);
3444
}
@@ -41,4 +51,79 @@ public function cgetAction(): Response
4151

4252
return $this->handleView($this->view($listRepresentation));
4353
}
54+
55+
public function getAction(int $id, Request $request): Response
56+
{
57+
$entity = $this->load($id);
58+
if (!$entity) {
59+
throw new NotFoundHttpException();
60+
}
61+
62+
return $this->handleView($this->view($entity));
63+
}
64+
65+
public function postAction(Request $request): Response
66+
{
67+
$entity = $this->create();
68+
69+
$this->mapDataToEntity($request->request->all(), $entity);
70+
71+
$this->save($entity);
72+
73+
return $this->handleView($this->view($entity));
74+
}
75+
76+
public function putAction(int $id, Request $request): Response
77+
{
78+
$entity = $this->load($id);
79+
if (!$entity) {
80+
throw new NotFoundHttpException();
81+
}
82+
83+
$this->mapDataToEntity($request->request->all(), $entity);
84+
85+
$this->save($entity);
86+
87+
return $this->handleView($this->view($entity));
88+
}
89+
90+
public function deleteAction(int $id): Response
91+
{
92+
$this->remove($id);
93+
94+
return $this->handleView($this->view());
95+
}
96+
97+
/**
98+
* @param string[] $data
99+
*/
100+
protected function mapDataToEntity(array $data, Location $entity): void
101+
{
102+
$entity->setName($data['name']);
103+
$entity->setStreet($data['street'] ?? '');
104+
$entity->setNumber($data['number'] ?? '');
105+
$entity->setCity($data['city'] ?? '');
106+
$entity->setPostalCode($data['postalCode'] ?? '');
107+
$entity->setCountryCode($data['countryCode'] ?? '');
108+
}
109+
110+
protected function load(int $id): ?Location
111+
{
112+
return $this->repository->findById($id);
113+
}
114+
115+
protected function create(): Location
116+
{
117+
return $this->repository->create();
118+
}
119+
120+
protected function save(Location $entity): void
121+
{
122+
$this->repository->save($entity);
123+
}
124+
125+
protected function remove(int $id): void
126+
{
127+
$this->repository->remove($id);
128+
}
44129
}

‎src/Repository/LocationRepository.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,33 @@ public function __construct(ManagerRegistry $registry)
2525

2626
public function create(): Location
2727
{
28-
$location = new Location();
28+
return new Location();
29+
}
30+
31+
public function remove(int $id): void
32+
{
33+
/** @var object $location */
34+
$location = $this->getEntityManager()->getReference(
35+
$this->getClassName(),
36+
$id
37+
);
38+
39+
$this->getEntityManager()->remove($location);
40+
$this->getEntityManager()->flush();
41+
}
2942

43+
public function save(Location $location): void
44+
{
3045
$this->getEntityManager()->persist($location);
46+
$this->getEntityManager()->flush();
47+
}
48+
49+
public function findById(int $id): ?Location
50+
{
51+
$location = $this->find($id);
52+
if (!$location) {
53+
return null;
54+
}
3155

3256
return $location;
3357
}

‎src/Service/CountryCodeSelect.php

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Service;
6+
7+
use Symfony\Component\Intl\Countries;
8+
9+
class CountryCodeSelect
10+
{
11+
/**
12+
* @return array[]
13+
*/
14+
public function getValues(): array
15+
{
16+
$values = [];
17+
18+
foreach (Countries::getNames() as $code => $title) {
19+
$values[] = [
20+
'name' => $code,
21+
'title' => $title,
22+
];
23+
}
24+
25+
return $values;
26+
}
27+
}

0 commit comments

Comments
 (0)