Skip to content

Commit 44f2129

Browse files
author
Bartek
authored
EZP-32157: Added option to choose SA when creating custom alias (#1583)
1 parent 94c2be8 commit 44f2129

File tree

9 files changed

+213
-18
lines changed

9 files changed

+213
-18
lines changed

src/bundle/Resources/public/js/scripts/admin.location.add.custom_url.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
const submitBtn = modal.querySelector('[type="submit"]');
77
const input = modal.querySelector('[required="required"]');
88
const checkboxes = [...modal.querySelectorAll('.ez-field-edit--ezboolean input')];
9+
const siteRootCheckbox = modal.querySelector('[name="custom_url_add[site_root]"]');
910
const toggleButtonState = () => {
1011
const hasValue = input.value.trim().length !== 0;
1112
const methodName = hasValue ? 'removeAttribute' : 'setAttribute';
@@ -22,8 +23,16 @@
2223
input.value = '';
2324
toggleButtonState();
2425
};
26+
const toggleSiteAccessSelect = (event) => {
27+
const isChecked = event.target.checked;
28+
const siteAccessSelect = modal.querySelector('[name="custom_url_add[site_access]"]');
29+
const methodName = isChecked ? 'removeAttribute' : 'setAttribute';
30+
31+
siteAccessSelect[methodName]('disabled', true);
32+
};
2533

2634
input.addEventListener('input', toggleButtonState, false);
35+
siteRootCheckbox.addEventListener('change', toggleSiteAccessSelect, false);
2736
checkboxes.forEach(checkbox => checkbox.addEventListener('change', toggleCheckbox, false));
2837
discardBtns.forEach(btn => btn.addEventListener('click', clearValues, false));
2938
}

src/bundle/Resources/translations/content_url.en.xliff

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@
4646
<target state="new">Unchecked will not redirect to the destination and the URL will stay the same.</target>
4747
<note>key: tab.urls.add.redirect.helper.unchecked</note>
4848
</trans-unit>
49+
<trans-unit id="c1277a6823f4d281355e706e54cd723b5ed4adf7" resname="tab.urls.add.root_location_id.helper_secondary">
50+
<source>If you leave this empty, the alias will be placed at main root Location.</source>
51+
<target state="new">If you leave this empty, the alias will be placed at main root Location.</target>
52+
<note>key: tab.urls.add.root_location_id.helper_secondary</note>
53+
</trans-unit>
54+
<trans-unit id="f933f01aef7b171904b5c0b1ed4327413828f96f" resname="tab.urls.add.site_access">
55+
<source>SiteAccess</source>
56+
<target state="new">SiteAccess</target>
57+
<note>key: tab.urls.add.site_access</note>
58+
</trans-unit>
4959
<trans-unit id="9ef990fca45f612ab2d3af7b21968803d76d5d77" resname="tab.urls.add.site_root">
5060
<source>Place alias at the site root</source>
5161
<target state="new">Place alias at the site root</target>

src/bundle/Resources/views/content/tab/url/modal_add_custom_url.html.twig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
{{ 'tab.urls.add.site_root.helper.no_parent_name'|trans|desc('Unchecked will create the new alias under the parent of this location') }}
3636
{% endif %}
3737
</div>
38+
39+
<span class="ez-modal--custom-url-alias__label">{{ 'tab.urls.add.site_access'|trans|desc('SiteAccess') }}</span>
40+
{{ form_widget(form.site_access) }}
41+
<div class="ez-modal--custom-url-alias__info-text">
42+
{{ 'tab.urls.add.root_location_id.helper_secondary'|trans|desc("If you leave this empty, the alias will be placed at main root Location.") }}
43+
</div>
3844
</div>
3945
<div class="modal-footer justify-content-center">
4046
<button type="button" class="btn btn-dark" data-dismiss="modal">

src/lib/Form/Data/Content/CustomUrl/CustomUrlAddData.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@ class CustomUrlAddData
2828
/** @var bool */
2929
private $siteRoot;
3030

31+
/** @var string|null */
32+
private $siteAccess;
33+
3134
public function __construct(
3235
?Location $location = null,
3336
?string $path = null,
3437
?Language $language = null,
3538
bool $redirect = true,
36-
bool $siteRoot = true
39+
bool $siteRoot = true,
40+
?string $siteAccess = null
3741
) {
3842
$this->location = $location;
3943
$this->path = $path;
4044
$this->language = $language;
4145
$this->redirect = $redirect;
4246
$this->siteRoot = $siteRoot;
47+
$this->siteAccess = $siteAccess;
4348
}
4449

4550
/**
@@ -141,4 +146,16 @@ public function setSiteRoot(bool $siteRoot): self
141146

142147
return $this;
143148
}
149+
150+
public function getSiteAccess(): ?string
151+
{
152+
return $this->siteAccess;
153+
}
154+
155+
public function setSiteAccess(?string $siteAccess): self
156+
{
157+
$this->siteAccess = $siteAccess;
158+
159+
return $this;
160+
}
144161
}

src/lib/Form/EventListener/BuildPathFromRootListener.php

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use eZ\Publish\API\Repository\LocationService;
1212
use eZ\Publish\API\Repository\URLAliasService;
13+
use eZ\Publish\Core\MVC\ConfigResolverInterface;
1314
use Symfony\Component\Form\FormEvent;
1415

1516
class BuildPathFromRootListener
@@ -20,14 +21,17 @@ class BuildPathFromRootListener
2021
/** @var \eZ\Publish\API\Repository\URLAliasService */
2122
private $urlAliasService;
2223

23-
/**
24-
* @param \eZ\Publish\API\Repository\LocationService $locationService
25-
* @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
26-
*/
27-
public function __construct(LocationService $locationService, URLAliasService $urlAliasService)
28-
{
24+
/** @var \eZ\Publish\Core\MVC\ConfigResolverInterface */
25+
private $configResolver;
26+
27+
public function __construct(
28+
LocationService $locationService,
29+
URLAliasService $urlAliasService,
30+
ConfigResolverInterface $configResolver
31+
) {
2932
$this->locationService = $locationService;
3033
$this->urlAliasService = $urlAliasService;
34+
$this->configResolver = $configResolver;
3135
}
3236

3337
/**
@@ -44,10 +48,25 @@ public function onPreSubmitData(FormEvent $event)
4448
if (1 >= $location->depth) {
4549
return;
4650
}
47-
$parentLocation = $this->locationService->loadLocation($location->parentLocationId);
48-
$urlAlias = $this->urlAliasService->reverseLookup($parentLocation);
49-
$data['path'] = $urlAlias->path . '/' . $data['path'];
51+
$data['path'] = $this->createPathBasedOnParentLocation($location->parentLocationId, $data['path']);
52+
$event->setData($data);
53+
} elseif (isset($data['site_root']) && true === (bool)$data['site_root'] && !empty($data['site_access'])) {
54+
$parameterName = 'content.tree_root.location_id';
55+
$defaultTreeRootLocationId = $this->configResolver->getParameter($parameterName);
56+
$treeRootLocationId = $this->configResolver->hasParameter($parameterName, null, $data['site_access'])
57+
? $this->configResolver->getParameter($parameterName, null, $data['site_access'])
58+
: $defaultTreeRootLocationId;
59+
60+
$data['path'] = $this->createPathBasedOnParentLocation((int)$treeRootLocationId, $data['path']);
5061
$event->setData($data);
5162
}
5263
}
64+
65+
private function createPathBasedOnParentLocation(int $locationId, string $path): string
66+
{
67+
$parentLocation = $this->locationService->loadLocation($locationId);
68+
$urlAlias = $this->urlAliasService->reverseLookup($parentLocation);
69+
70+
return $urlAlias->path . '/' . $path;
71+
}
5372
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader;
10+
11+
use eZ\Publish\API\Repository\Values\Content\Location;
12+
use EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver;
13+
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
14+
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
15+
16+
class SiteAccessChoiceLoader implements ChoiceLoaderInterface
17+
{
18+
/** @var \EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver */
19+
private $nonAdminSiteaccessResolver;
20+
21+
/** @var \eZ\Publish\API\Repository\Values\Content\Location|null */
22+
private $location;
23+
24+
public function __construct(
25+
NonAdminSiteaccessResolver $nonAdminSiteaccessResolver,
26+
?Location $location = null
27+
) {
28+
$this->nonAdminSiteaccessResolver = $nonAdminSiteaccessResolver;
29+
$this->location = $location;
30+
}
31+
32+
/**
33+
* Provides data in format:
34+
* [
35+
* site_access => location_id,
36+
* ...
37+
* ].
38+
*
39+
* @return int[]
40+
*/
41+
public function getChoiceList(): array
42+
{
43+
$siteAccesses = $this->location === null
44+
? $this->nonAdminSiteaccessResolver->getSiteaccesses()
45+
: $this->nonAdminSiteaccessResolver->getSiteaccessesForLocation($this->location);
46+
47+
$data = [];
48+
foreach ($siteAccesses as $siteAccess) {
49+
$data[$siteAccess] = $siteAccess;
50+
}
51+
52+
return $data;
53+
}
54+
55+
public function loadChoiceList($value = null)
56+
{
57+
$choices = $this->getChoiceList();
58+
59+
return new ArrayChoiceList($choices, $value);
60+
}
61+
62+
public function loadChoicesForValues(array $values, $value = null)
63+
{
64+
// Optimize
65+
$values = array_filter($values);
66+
if (empty($values)) {
67+
return [];
68+
}
69+
70+
return $this->loadChoiceList($value)->getChoicesForValues($values);
71+
}
72+
73+
public function loadValuesForChoices(array $choices, $value = null)
74+
{
75+
// Optimize
76+
$choices = array_filter($choices);
77+
if (empty($choices)) {
78+
return [];
79+
}
80+
81+
// If no callable is set, choices are the same as values
82+
if (null === $value) {
83+
return $choices;
84+
}
85+
86+
return $this->loadChoiceList($value)->getValuesForChoices($choices);
87+
}
88+
}

src/lib/Form/Type/Content/CustomUrl/CustomUrlAddType.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
use EzSystems\EzPlatformAdminUi\Form\EventListener\AddLanguageFieldBasedOnContentListener;
1313
use EzSystems\EzPlatformAdminUi\Form\EventListener\BuildPathFromRootListener;
1414
use EzSystems\EzPlatformAdminUi\Form\EventListener\DisableSiteRootCheckboxIfRootLocationListener;
15+
use EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\SiteAccessChoiceLoader;
1516
use EzSystems\EzPlatformAdminUi\Form\Type\Content\LocationType;
17+
use EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver;
1618
use Symfony\Component\Form\AbstractType;
1719
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
1820
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
@@ -36,22 +38,21 @@ class CustomUrlAddType extends AbstractType
3638
/** @var \EzSystems\EzPlatformAdminUi\Form\EventListener\DisableSiteRootCheckboxIfRootLocationListener */
3739
private $checkboxIfRootLocationListener;
3840

39-
/**
40-
* @param \eZ\Publish\API\Repository\LanguageService $languageService
41-
* @param \EzSystems\EzPlatformAdminUi\Form\EventListener\AddLanguageFieldBasedOnContentListener $addLanguageFieldBasedOnContentListener
42-
* @param \EzSystems\EzPlatformAdminUi\Form\EventListener\BuildPathFromRootListener $buildPathFromRootListener
43-
* @param \EzSystems\EzPlatformAdminUi\Form\EventListener\DisableSiteRootCheckboxIfRootLocationListener $checkboxIfRootLocationListener
44-
*/
41+
/** @var \EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver */
42+
private $nonAdminSiteaccessResolver;
43+
4544
public function __construct(
4645
LanguageService $languageService,
4746
AddLanguageFieldBasedOnContentListener $addLanguageFieldBasedOnContentListener,
4847
BuildPathFromRootListener $buildPathFromRootListener,
49-
DisableSiteRootCheckboxIfRootLocationListener $checkboxIfRootLocationListener
48+
DisableSiteRootCheckboxIfRootLocationListener $checkboxIfRootLocationListener,
49+
NonAdminSiteaccessResolver $nonAdminSiteaccessResolver
5050
) {
5151
$this->languageService = $languageService;
5252
$this->addLanguageFieldBasedOnContentListener = $addLanguageFieldBasedOnContentListener;
5353
$this->buildPathFromRootListener = $buildPathFromRootListener;
5454
$this->checkboxIfRootLocationListener = $checkboxIfRootLocationListener;
55+
$this->nonAdminSiteaccessResolver = $nonAdminSiteaccessResolver;
5556
}
5657

5758
/**
@@ -60,6 +61,8 @@ public function __construct(
6061
*/
6162
public function buildForm(FormBuilderInterface $builder, array $options)
6263
{
64+
$location = $options['data']->getLocation();
65+
6366
$builder
6467
->add(
6568
'location',
@@ -97,6 +100,17 @@ public function buildForm(FormBuilderInterface $builder, array $options)
97100
'label' => false,
98101
]
99102
)
103+
->add(
104+
'site_access',
105+
ChoiceType::class,
106+
[
107+
'required' => false,
108+
'choice_loader' => new SiteAccessChoiceLoader(
109+
$this->nonAdminSiteaccessResolver,
110+
$location
111+
),
112+
]
113+
)
100114
->add(
101115
'add',
102116
SubmitType::class,

src/lib/Siteaccess/AdminSiteaccessPreviewVoter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function getRootLocationIds(string $siteaccess): array
1717
{
1818
$locationIds = [];
1919
$locationIds[] = $this->configResolver->getParameter(
20-
'location_ids.content_structure',
20+
'content.tree_root.location_id',
2121
null,
2222
$siteaccess
2323
);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace EzSystems\EzPlatformAdminUi\Tests\Form\Data\Content\CustomUrl;
10+
11+
use eZ\Publish\API\Repository\Values\Content\Language;
12+
use eZ\Publish\Core\Repository\Values\Content\Location;
13+
use EzSystems\EzPlatformAdminUi\Form\Data\Content\CustomUrl\CustomUrlAddData;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class CustomUrlAddDataTest extends TestCase
17+
{
18+
public function testConstruct(): void
19+
{
20+
$location = new Location(['id' => 2]);
21+
$language = new Language(['languageCode' => 'eng-GB']);
22+
$path = '/test';
23+
$siteAccess = 'site3';
24+
25+
$data = new CustomUrlAddData($location, $path, $language, false, true, $siteAccess);
26+
27+
$this->assertSame($location, $data->getLocation());
28+
$this->assertSame($language, $data->getLanguage());
29+
$this->assertSame($path, $data->getPath());
30+
$this->assertSame($siteAccess, $data->getSiteAccess());
31+
}
32+
}

0 commit comments

Comments
 (0)