-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Draft] [Example] Integrate a webspace specific setting administration interface #106
Draft
alexander-schranz
wants to merge
2
commits into
master
Choose a base branch
from
example/webspace-setting-entity
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>webspace_setting_details</key> | ||
|
||
<properties> | ||
<property name="demobarText" type="text_line"> | ||
<meta> | ||
<title>app.demobar_text</title> | ||
</meta> | ||
</property> | ||
</properties> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
sulu_admin: | ||
resources: | ||
webspace_settings: | ||
routes: | ||
detail: 'app.get_webspace_settings' |
4 changes: 2 additions & 2 deletions
4
...build/admin/main.7825759723a3c825efc7.css → ...build/admin/main.a5f695a5931373b4bce3.css
Large diffs are not rendered by default.
Oops, something went wrong.
34 changes: 17 additions & 17 deletions
34
.../build/admin/main.7825759723a3c825efc7.js → .../build/admin/main.a5f695a5931373b4bce3.js
Large diffs are not rendered by default.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
...ld/admin/main.7825759723a3c825efc7.js.map → ...ld/admin/main.a5f695a5931373b4bce3.js.map
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Admin; | ||
|
||
use App\Entity\WebspaceSetting; | ||
use Sulu\Bundle\AdminBundle\Admin\Admin; | ||
use Sulu\Bundle\AdminBundle\Admin\View\ToolbarAction; | ||
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface; | ||
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection; | ||
use Sulu\Bundle\PageBundle\Admin\PageAdmin; | ||
use Sulu\Component\Security\Authorization\PermissionTypes; | ||
use Sulu\Component\Security\Authorization\SecurityCheckerInterface; | ||
use Sulu\Component\Webspace\Manager\WebspaceManagerInterface; | ||
use Sulu\Component\Webspace\Webspace; | ||
|
||
class WebspaceSettingAdmin extends Admin | ||
{ | ||
public const TAB_VIEW = 'app.webspace_settings'; | ||
public const FORM_VIEW = 'app.webspace_settings.form'; | ||
public const FORM_KEY = 'webspace_setting_details'; | ||
|
||
|
||
public function __construct( | ||
private WebspaceManagerInterface $webspaceManager, | ||
private ViewBuilderFactoryInterface $viewBuilderFactory, | ||
private SecurityCheckerInterface $securityChecker | ||
) { | ||
} | ||
|
||
public function configureViews(ViewCollection $viewCollection): void | ||
{ | ||
if ($this->hasSomeWebspaceSettingPermission()) { | ||
$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, '/webspace-settings/:id') | ||
->setResourceKey(WebspaceSetting::RESOURCE_KEY) | ||
->setTabTitle('app.webspace_settings') | ||
->setParent(PageAdmin::WEBSPACE_TABS_VIEW) | ||
->setOption('routerAttributesToFormRequest', ['webspace']) | ||
->setTabOrder(8096) | ||
->setAttributeDefault('id', '-') | ||
); | ||
|
||
$viewCollection->add( | ||
$this->viewBuilderFactory->createFormViewBuilder(static::FORM_VIEW, '/details') | ||
->setResourceKey(WebspaceSetting::RESOURCE_KEY) | ||
->setFormKey(self::FORM_KEY) | ||
->setTabTitle('sulu_admin.details') | ||
->addToolbarActions([new ToolbarAction('sulu_admin.save')]) | ||
->addRouterAttributesToFormRequest(['webspace']) | ||
->setParent(static::TAB_VIEW) | ||
); | ||
} | ||
} | ||
|
||
public function getSecurityContexts(): array | ||
{ | ||
$webspaceContexts = []; | ||
/* @var Webspace $webspace */ | ||
foreach ($this->webspaceManager->getWebspaceCollection() as $webspace) { | ||
$securityContextKey = self::getWebspaceSettingSecurityContext($webspace->getKey()); | ||
$webspaceContexts[$securityContextKey] = $this->getSecurityContextPermissions(); | ||
} | ||
|
||
return [ | ||
self::SULU_ADMIN_SECURITY_SYSTEM => [ | ||
'Webspaces' => $webspaceContexts, | ||
], | ||
]; | ||
} | ||
|
||
public function getSecurityContextsWithPlaceholder(): array | ||
{ | ||
return [ | ||
self::SULU_ADMIN_SECURITY_SYSTEM => [ | ||
'Webspaces' => [ | ||
self::getWebspaceSettingSecurityContext('#webspace#') => $this->getSecurityContextPermissions(), | ||
], | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Returns security context for settings in given webspace. | ||
* | ||
* @final | ||
* | ||
* @param string $webspaceKey | ||
* | ||
* @return string | ||
*/ | ||
public static function getWebspaceSettingSecurityContext($webspaceKey): string | ||
{ | ||
return \sprintf('%s%s.%s', PageAdmin::SECURITY_CONTEXT_PREFIX, $webspaceKey, 'settings'); | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
private function getSecurityContextPermissions(): array | ||
{ | ||
return [ | ||
PermissionTypes::VIEW, | ||
PermissionTypes::EDIT, | ||
]; | ||
} | ||
|
||
private function hasSomeWebspaceSettingPermission(): bool | ||
{ | ||
foreach ($this->webspaceManager->getWebspaceCollection()->getWebspaces() as $webspace) { | ||
$hasWebspaceAnalyticsPermission = $this->securityChecker->hasPermission( | ||
self::getWebspaceSettingSecurityContext($webspace->getKey()), | ||
PermissionTypes::EDIT | ||
); | ||
|
||
if ($hasWebspaceAnalyticsPermission) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Controller\Admin; | ||
|
||
use App\Admin\WebspaceSettingAdmin; | ||
use App\Entity\WebspaceSetting; | ||
use Doctrine\ORM\EntityManagerInterface; | ||
use Sulu\Component\Security\SecuredControllerInterface; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
|
||
/** | ||
* @phpstan-type WebspaceSettingsData array{ | ||
* demobarText: string|null, | ||
* } | ||
*/ | ||
class WebspaceSettingController extends AbstractController implements SecuredControllerInterface | ||
{ | ||
public function __construct( | ||
private EntityManagerInterface $entityManager, | ||
private RequestStack $requestStack, | ||
) { | ||
} | ||
|
||
/** | ||
* @Route("/admin/api/webspace-settings/{id}", methods={"GET"}, name="app.get_webspace_settings") | ||
*/ | ||
public function getAction(Request $request): Response | ||
{ | ||
$webspace = $request->query->get('webspace'); | ||
|
||
$webspaceSetting = $this->entityManager->getRepository(WebspaceSetting::class)->findOneBy([ | ||
'webspace' => $webspace, | ||
]); | ||
|
||
return $this->json($this->getDataForEntity($webspaceSetting ?: new WebspaceSetting($webspace))); | ||
} | ||
|
||
/** | ||
* @Route("/admin/api/webspace-settings/{id}", methods={"PUT"}, name="app.put_webspace_settings") | ||
*/ | ||
public function putAction(Request $request): Response | ||
{ | ||
$webspace = $request->query->get('webspace'); | ||
|
||
$webspaceSetting = $this->entityManager->getRepository(WebspaceSetting::class)->findOneBy([ | ||
'webspace' => $webspace, | ||
]); | ||
|
||
if (!$webspaceSetting) { | ||
$webspaceSetting = new WebspaceSetting($webspace); | ||
$this->entityManager->persist($webspaceSetting); | ||
} | ||
|
||
/** @var WebspaceSettingsData $data */ | ||
$data = $request->toArray(); | ||
$this->mapDataToEntity($data, $webspaceSetting); | ||
$this->entityManager->flush(); | ||
|
||
return $this->json($this->getDataForEntity($webspaceSetting)); | ||
} | ||
|
||
/** | ||
* @return WebspaceSettingsData $data | ||
*/ | ||
protected function getDataForEntity(WebspaceSetting $entity): array | ||
{ | ||
return [ | ||
'demobarText' => $entity->getDemobarText(), | ||
]; | ||
} | ||
|
||
/** | ||
* @param WebspaceSettingsData $data | ||
*/ | ||
protected function mapDataToEntity(array $data, WebspaceSetting $entity): void | ||
{ | ||
$entity->setDemobarText($data['demobarText']); | ||
} | ||
|
||
public function getSecurityContext() | ||
{ | ||
$request = $this->requestStack->getCurrentRequest(); | ||
|
||
return WebspaceSettingAdmin::getWebspaceSettingSecurityContext($request->query->get('webspace')); | ||
} | ||
|
||
public function getLocale(Request $request): ?string | ||
{ | ||
return $request->query->get('locale'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?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_webspace_setting')] | ||
class WebspaceSetting implements AuditableInterface | ||
{ | ||
use AuditableTrait; | ||
|
||
public const RESOURCE_KEY = 'webspace_settings'; | ||
|
||
#[ORM\Id()] | ||
#[ORM\GeneratedValue()] | ||
#[ORM\Column(type: "integer")] | ||
private ?int $id = null; | ||
|
||
#[ORM\Column(type: "string", length: 32, nullable: false, unique: true)] | ||
private string $webspace; | ||
|
||
#[ORM\Column(type: "string", length: 191, nullable: true)] | ||
private ?string $demobarText = null; | ||
|
||
public function __construct(string $webspace) | ||
{ | ||
$this->webspace = $webspace; | ||
} | ||
|
||
public function getId(): ?int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function getWebspace(): string | ||
{ | ||
return $this->webspace; | ||
} | ||
|
||
public function getDemobarText(): ?string | ||
{ | ||
return $this->demobarText; | ||
} | ||
|
||
public function setDemobarText(?string $demobarText): void | ||
{ | ||
$this->demobarText = $demobarText; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace App\Twig; | ||
|
||
use App\Entity\WebspaceSetting; | ||
use Doctrine\ORM\EntityManagerInterface; | ||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFunction; | ||
|
||
class WebspaceSettingTwigExtension extends AbstractExtension | ||
{ | ||
private EntityManagerInterface $entityManager; | ||
|
||
public function __construct( | ||
EntityManagerInterface $entityManager | ||
) { | ||
$this->entityManager = $entityManager; | ||
} | ||
|
||
public function getFunctions() | ||
{ | ||
return [ | ||
new TwigFunction('load_webspace_setting', [$this, 'loadWebspaceSetting']), | ||
]; | ||
} | ||
|
||
public function loadWebspaceSetting(string $webspace): WebspaceSetting | ||
{ | ||
$applicationSettings = $this->entityManager->getRepository(WebspaceSetting::class)->findOneBy(['webspace' => $webspace]) ?? null; | ||
|
||
return $applicationSettings ?: new WebspaceSetting($webspace); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be get part of the
createResourceTabViewBuilder
asaddRouterAttributesToFormRequest
when implementedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything planed to get the webspace in createResourceTabViewBuilder?
THX for info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Builder is generally for all webspaces. To get the webspace in the endpoint which this view is for you need
$request->query->get('webspace');
. If you want to hide a tab you may could try use tabCondition but I'm not sure which data is available in the condition itself.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is different in the admin build, so I run in a permission view error because I didn't get the webspace key with
$request->query->get('webspace')
Is there any sulu js extension in the example, that is not loaded via
bin/console sulu:admin:update-build
?THX