Skip to content

Commit

Permalink
09 - Add a list representation for locations in the admin interface
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes authored and niklasnatter committed Jun 20, 2022
1 parent cfd2480 commit 5e31805
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 2 deletions.
41 changes: 41 additions & 0 deletions config/lists/locations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" ?>
<list xmlns="http://schemas.sulu.io/list-builder/list">
<key>locations</key>

<properties>
<property name="id" visibility="no" translation="sulu_admin.id">
<field-name>id</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="name" visibility="always" searchability="yes" translation="sulu_admin.name">
<field-name>name</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="street" visibility="yes" searchability="yes" translation="sulu_contact.street">
<field-name>street</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="number" visibility="yes" searchability="yes" translation="sulu_contact.number">
<field-name>number</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="postalCode" visibility="yes" searchability="yes" translation="sulu_contact.zip">
<field-name>postalCode</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="city" visibility="yes" searchability="yes" translation="sulu_contact.city">
<field-name>city</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="countryCode" visibility="yes" searchability="yes" translation="sulu_contact.country">
<field-name>countryCode</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>
</properties>
</list>
4 changes: 4 additions & 0 deletions config/packages/sulu_admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ sulu_admin:
routes:
list: app.get_event_registrations

locations:
routes:
list: app.get_locations

# Registering Selection Field Types in this section
field_type_options:
selection:
Expand Down
6 changes: 6 additions & 0 deletions config/routes_admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ app.event_registration_api:
resource: App\Controller\Admin\EventRegistrationController
prefix: /admin/api
name_prefix: app.

app.location_api:
type: rest
resource: App\Controller\Admin\LocationController
prefix: /admin/api
name_prefix: app.
51 changes: 51 additions & 0 deletions src/Admin/LocationAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace App\Admin;

use App\Entity\Location;
use Sulu\Bundle\AdminBundle\Admin\Admin;
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItem;
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItemCollection;
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface;
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection;

class LocationAdmin extends Admin
{
const LOCATION_LIST_KEY = 'locations';

const LOCATION_LIST_VIEW = 'app.locations_list';

/**
* @var ViewBuilderFactoryInterface
*/
private $viewBuilderFactory;

public function __construct(ViewBuilderFactoryInterface $viewBuilderFactory)
{
$this->viewBuilderFactory = $viewBuilderFactory;
}

public function configureNavigationItems(NavigationItemCollection $navigationItemCollection): void
{
$module = $navigationItemCollection->get('app.events');

$locations = new NavigationItem('app.locations');
$locations->setPosition(10);
$locations->setView(static::LOCATION_LIST_VIEW);

$module->addChild($locations);
}

public function configureViews(ViewCollection $viewCollection): void
{
$listView = $this->viewBuilderFactory->createListViewBuilder(self::LOCATION_LIST_VIEW, '/locations')
->setResourceKey(Location::RESOURCE_KEY)
->setListKey(self::LOCATION_LIST_KEY)
->setTitle('app.locations')
->addListAdapters(['table'])
->addToolbarActions([]);
$viewCollection->add($listView);
}
}
44 changes: 44 additions & 0 deletions src/Controller/Admin/LocationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Common\DoctrineListRepresentationFactory;
use App\Entity\Location;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sulu\Component\Rest\AbstractRestController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

/**
* @RouteResource("location")
*/
class LocationController extends AbstractRestController implements ClassResourceInterface
{
/**
* @var DoctrineListRepresentationFactory
*/
private $doctrineListRepresentationFactory;

public function __construct(
DoctrineListRepresentationFactory $doctrineListRepresentationFactory,
ViewHandlerInterface $viewHandler,
?TokenStorageInterface $tokenStorage = null
) {
$this->doctrineListRepresentationFactory = $doctrineListRepresentationFactory;

parent::__construct($viewHandler, $tokenStorage);
}

public function cgetAction(): Response
{
$listRepresentation = $this->doctrineListRepresentationFactory->createDoctrineListRepresentation(
Location::RESOURCE_KEY
);

return $this->handleView($this->view($listRepresentation));
}
}
2 changes: 2 additions & 0 deletions src/Entity/Location.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
class Location
{
const RESOURCE_KEY = 'locations';

/**
* @var int|null
*
Expand Down
49 changes: 49 additions & 0 deletions tests/Functional/Controller/Admin/LocationControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace App\Tests\Functional\Controller\Admin;

use App\Tests\Functional\Traits\LocationTrait;
use Sulu\Bundle\TestBundle\Testing\SuluTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\HttpFoundation\Response;

class LocationControllerTest extends SuluTestCase
{
use LocationTrait;

/**
* @var KernelBrowser
*/
private $client;

protected function setUp(): void
{
$this->client = $this->createAuthenticatedClient();
$this->purgeDatabase();
}

public function testCGet(): void
{
$location1 = $this->createLocation('Sulu');
$location2 = $this->createLocation('Symfony');

$this->client->request('GET', '/admin/api/locations');

$response = $this->client->getResponse();
$this->assertInstanceOf(Response::class, $response);
$result = json_decode($response->getContent() ?: '', true);
$this->assertHttpStatusCode(200, $response);

$this->assertSame(2, $result['total']);
$this->assertCount(2, $result['_embedded']['locations']);
$items = $result['_embedded']['locations'];

$this->assertSame($location1->getId(), $items[0]['id']);
$this->assertSame($location2->getId(), $items[1]['id']);

$this->assertSame($location1->getName(), $items[0]['name']);
$this->assertSame($location2->getName(), $items[1]['name']);
}
}
35 changes: 35 additions & 0 deletions tests/Functional/Traits/LocationTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Tests\Functional\Traits;

use App\Entity\Location;
use App\Repository\LocationRepository;
use Doctrine\ORM\EntityManagerInterface;

trait LocationTrait
{
public function createLocation(string $name): Location
{
$location = $this->getLocationRepository()->create();
$location->setName($name);
$location->setStreet('');
$location->setNumber('');
$location->setPostalCode('');
$location->setCity('');
$location->setCountryCode('');

static::getEntityManager()->persist($location);
static::getEntityManager()->flush();

return $location;
}

protected function getLocationRepository(): LocationRepository
{
return static::getEntityManager()->getRepository(Location::class);
}

abstract protected static function getEntityManager(): EntityManagerInterface;
}
3 changes: 2 additions & 1 deletion translations/admin.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"app.end_date": "Ende",
"app.enable_event": "Veranstaltungen aktivieren",
"app.enabled": "Aktiviert",
"app.location": "Standort"
"app.location": "Standort",
"app.locations": "Standorte"
}
3 changes: 2 additions & 1 deletion translations/admin.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"app.end_date": "Ende",
"app.enable_event": "Enable event",
"app.enabled": "Enabled",
"app.location": "Location"
"app.location": "Location",
"app.locations": "Locations"
}

0 comments on commit 5e31805

Please sign in to comment.