Skip to content

Commit

Permalink
Implement ApplicationSettings entity
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasnatter authored and alexander-schranz committed Jan 30, 2023
1 parent 8d0fea4 commit 5b7d35b
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 3 deletions.
15 changes: 15 additions & 0 deletions config/forms/application_settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" ?>
<form xmlns="http://schemas.sulu.io/template/template"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/form-1.0.xsd"
>
<key>application_settings</key>

<properties>
<property name="demobarText" type="text_line">
<meta>
<title>app.demobar_text</title>
</meta>
</property>
</properties>
</form>
5 changes: 5 additions & 0 deletions config/packages/app_application_settings_admin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sulu_admin:
resources:
application_settings:
routes:
detail: 'app.get_application_settings'
81 changes: 81 additions & 0 deletions src/Admin/ApplicationSettingsAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace App\Admin;

use App\Entity\ApplicationSettings;
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\ToolbarAction;
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface;
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection;
use Sulu\Component\Security\Authorization\PermissionTypes;
use Sulu\Component\Security\Authorization\SecurityCheckerInterface;

class ApplicationSettingsAdmin extends Admin
{
public const TAB_VIEW = 'app.application_settings';
public const FORM_VIEW = 'app.application_settings.form';

private ViewBuilderFactoryInterface $viewBuilderFactory;
private SecurityCheckerInterface $securityChecker;

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

public function configureNavigationItems(NavigationItemCollection $navigationItemCollection): void
{
if ($this->securityChecker->hasPermission(ApplicationSettings::SECURITY_CONTEXT, PermissionTypes::EDIT)) {
$categoryItem = new NavigationItem('app.application');
$categoryItem->setPosition(0);
$categoryItem->setView(static::TAB_VIEW);

$navigationItemCollection->get(Admin::SETTINGS_NAVIGATION_ITEM)->addChild($categoryItem);
}
}

public function configureViews(ViewCollection $viewCollection): void
{
if ($this->securityChecker->hasPermission(ApplicationSettings::SECURITY_CONTEXT, PermissionTypes::EDIT)) {
$viewCollection->add(
// sulu will only load the existing entity if the path of the form includes an id attribute
$this->viewBuilderFactory->createResourceTabViewBuilder(static::TAB_VIEW, '/application-settings/:id')
->setResourceKey(ApplicationSettings::RESOURCE_KEY)
->setAttributeDefault('id', '-')
);

$viewCollection->add(
$this->viewBuilderFactory->createFormViewBuilder(static::FORM_VIEW, '/details')
->setResourceKey(ApplicationSettings::RESOURCE_KEY)
->setFormKey(ApplicationSettings::FORM_KEY)
->setTabTitle('sulu_admin.details')
->addToolbarActions([new ToolbarAction('sulu_admin.save')])
->setParent(static::TAB_VIEW)
);
}
}

/**
* @return mixed[]
*/
public function getSecurityContexts(): array
{
return [
self::SULU_ADMIN_SECURITY_SYSTEM => [
'Settings' => [
ApplicationSettings::SECURITY_CONTEXT => [
PermissionTypes::VIEW,
PermissionTypes::EDIT,
],
],
],
];
}
}
86 changes: 86 additions & 0 deletions src/Controller/Admin/ApplicationSettingsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Entity\ApplicationSettings;
use Doctrine\ORM\EntityManagerInterface;
use Sulu\Component\Security\SecuredControllerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

/**
* @phpstan-type ApplicationSettingsData array{
* demobarText: string|null,
* }
*/
class ApplicationSettingsController extends AbstractController implements SecuredControllerInterface
{
private EntityManagerInterface $entityManager;

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

/**
* @Route("/admin/api/application-settings/{id}", methods={"GET"}, name="app.get_application_settings")
*/
public function getAction(): Response
{
$applicationSettings = $this->entityManager->getRepository(ApplicationSettings::class)->findOneBy([]);

return $this->json($this->getDataForEntity($applicationSettings ?: new ApplicationSettings()));
}

/**
* @Route("/admin/api/application-settings/{id}", methods={"PUT"}, name="app.put_application_settings")
*/
public function putAction(Request $request): Response
{
$applicationSettings = $this->entityManager->getRepository(ApplicationSettings::class)->findOneBy([]);
if (!$applicationSettings) {
$applicationSettings = new ApplicationSettings();
$this->entityManager->persist($applicationSettings);
}

/** @var ApplicationSettingsData $data */
$data = $request->toArray();
$this->mapDataToEntity($data, $applicationSettings);
$this->entityManager->flush();

return $this->json($this->getDataForEntity($applicationSettings));
}

/**
* @return ApplicationSettingsData $data
*/
protected function getDataForEntity(ApplicationSettings $entity): array
{
return [
'demobarText' => $entity->getDemobarText(),
];
}

/**
* @param ApplicationSettingsData $data
*/
protected function mapDataToEntity(array $data, ApplicationSettings $entity): void
{
$entity->setDemobarText($data['demobarText']);
}

public function getSecurityContext(): string
{
return ApplicationSettings::SECURITY_CONTEXT;
}

public function getLocale(Request $request): ?string
{
return $request->query->get('locale');
}
}
47 changes: 47 additions & 0 deletions src/Entity/ApplicationSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sulu\Component\Persistence\Model\AuditableInterface;
use Sulu\Component\Persistence\Model\AuditableTrait;

/**
* @ORM\Entity()
* @ORM\Table(name="app_application_settings")
*/
class ApplicationSettings implements AuditableInterface
{
use AuditableTrait;

public const RESOURCE_KEY = 'application_settings';
public const FORM_KEY = 'application_settings';
public const SECURITY_CONTEXT = 'sulu.settings.application_settings';

/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private ?int $id = null;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private ?string $demobarText = null;

public function getId(): ?int
{
return $this->id;
}

public function getDemobarText(): ?string
{
return $this->demobarText;
}

public function setDemobarText(?string $demobarText): void
{
$this->demobarText = $demobarText;
}
}
33 changes: 33 additions & 0 deletions src/Twig/ApplicationSettingsTwigExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Twig;

use App\Entity\ApplicationSettings;
use Doctrine\ORM\EntityManagerInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class ApplicationSettingsTwigExtension extends AbstractExtension
{
private EntityManagerInterface $entityManager;

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

public function getFunctions()
{
return [
new TwigFunction('load_application_settings', [$this, 'loadApplicationSettings']),
];
}

public function loadApplicationSettings(): ApplicationSettings
{
$applicationSettings = $this->entityManager->getRepository(ApplicationSettings::class)->findOneBy([]) ?? null;

return $applicationSettings ?: new ApplicationSettings();
}
}
1 change: 1 addition & 0 deletions templates/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
{# @see https://docs.sulu.io/en/2.2/reference/twig-extensions/functions/sulu_snippet_load_by_area.html #}
{% set webspaceSettings = sulu_snippet_load_by_area('webspace_settings') %}
{% set applicationSettings = load_application_settings() %}

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
Expand Down
2 changes: 1 addition & 1 deletion templates/includes/demobar.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</a>

<p class="demobar__title">
SULU DEMO
{{ applicationSettings.demobarText|default('SULU DEMO') }}
</p>

<a href="https://github.com/sulu/sulu-demo" target="_blank" class="demobar__github">
Expand Down
4 changes: 3 additions & 1 deletion translations/admin.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
"app.album_selection_label": "{count} {count, plural, =1 {Album} other {Alben}} ausgewählt",
"app.select_albums": "Alben auswählen",
"app.no_album_selected": "Kein Album ausgewählt",
"app.select_album": "Album auswählen"
"app.select_album": "Album auswählen",
"app.application": "Applikation",
"app.demobar_text": "Demobar Text"
}
4 changes: 3 additions & 1 deletion translations/admin.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
"app.album_selection_label": "{count} {count, plural, =1 {album} other {albums}} selected",
"app.select_albums": "Select albums",
"app.no_album_selected": "No album selected",
"app.select_album": "Select album"
"app.select_album": "Select album",
"app.application": "Application",
"app.demobar_text": "Demobar Text"
}

0 comments on commit 5b7d35b

Please sign in to comment.