From 4ac2d928118b3d8a9f1497a151b832b53802d8be Mon Sep 17 00:00:00 2001 From: Maciej Kobus Date: Tue, 6 Mar 2018 09:39:27 +0100 Subject: [PATCH] EZP-28314: As a v2 Editor, I want to select a SiteAccess in the Preview mode --- src/bundle/Controller/ContentController.php | 32 +++++--- src/bundle/Resources/config/services.yml | 1 + .../Resources/config/services/components.yml | 3 + .../services/components/content/edit.yml | 9 +++ .../Resources/config/services/controllers.yml | 5 -- .../Resources/config/services/siteaccess.yml | 8 ++ .../public/js/scripts/admin.preview.js | 9 ++- src/bundle/Resources/public/scss/_alerts.scss | 9 +++ src/bundle/Resources/public/scss/_icons.scss | 6 ++ .../Resources/public/scss/_preview.scss | 23 +++++- .../Resources/public/scss/ezplatform.scss | 1 + ...dit_component_preview_unavailable.en.xliff | 16 ++++ .../component/preview_unavailable.html.twig | 10 +++ .../content_edit/content_edit.html.twig | 15 +++- .../views/content/content_preview.html.twig | 19 +++-- .../views/dashboard/tab/my_drafts.html.twig | 3 +- .../PreviewUnavailableTwigComponent.php | 66 +++++++++++++++ .../Menu/ContentEditRightSidebarBuilder.php | 79 +++++++++++++----- .../Form/Processor/PreviewFormProcessor.php | 28 ++++++- .../Siteaccess/NonAdminSiteaccessResolver.php | 65 +++++++++++++++ src/lib/Siteaccess/SiteaccessResolver.php | 80 +++++++++++++++++++ 21 files changed, 436 insertions(+), 51 deletions(-) create mode 100644 src/bundle/Resources/config/services/components/content/edit.yml create mode 100644 src/bundle/Resources/config/services/siteaccess.yml create mode 100644 src/bundle/Resources/public/scss/_alerts.scss create mode 100644 src/bundle/Resources/translations/content_edit_component_preview_unavailable.en.xliff create mode 100644 src/bundle/Resources/views/content/content_edit/component/preview_unavailable.html.twig create mode 100644 src/lib/Component/Content/PreviewUnavailableTwigComponent.php create mode 100644 src/lib/Siteaccess/NonAdminSiteaccessResolver.php create mode 100644 src/lib/Siteaccess/SiteaccessResolver.php diff --git a/src/bundle/Controller/ContentController.php b/src/bundle/Controller/ContentController.php index 90da93aa7b..86c73e5e8f 100644 --- a/src/bundle/Controller/ContentController.php +++ b/src/bundle/Controller/ContentController.php @@ -12,6 +12,7 @@ use eZ\Publish\API\Repository\LocationService; use eZ\Publish\API\Repository\Values\Content\Content; use eZ\Publish\API\Repository\Values\Content\Location; +use eZ\Publish\Core\Base\Exceptions\BadStateException; use EzSystems\EzPlatformAdminUi\Exception\InvalidArgumentException as AdminInvalidArgumentException; use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentCreateData; use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentEditData; @@ -20,6 +21,8 @@ use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory; use EzSystems\EzPlatformAdminUi\Form\SubmitHandler; use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface; +use EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver; +use EzSystems\EzPlatformAdminUi\Siteaccess\SiteaccessResolver; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -37,9 +40,6 @@ class ContentController extends Controller /** @var ContentService */ private $contentService; - /** @var LocationService */ - private $locationService; - /** @var FormFactory */ private $formFactory; @@ -52,8 +52,11 @@ class ContentController extends Controller /** @var ContentMainLocationUpdateMapper */ private $contentMainLocationUpdateMapper; - /** @var string */ - private $defaultSiteaccess; + /** @var SiteaccessResolver */ + private $siteaccessResolver; + + /** @var LocationService */ + private $locationService; /** * @param NotificationHandlerInterface $notificationHandler @@ -62,7 +65,7 @@ class ContentController extends Controller * @param SubmitHandler $submitHandler * @param TranslatorInterface $translator * @param ContentMainLocationUpdateMapper $contentMetadataUpdateMapper - * @param string $defaultSiteaccess + * @param SiteaccessResolver $siteaccessResolver * @param LocationService $locationService */ public function __construct( @@ -72,7 +75,7 @@ public function __construct( SubmitHandler $submitHandler, TranslatorInterface $translator, ContentMainLocationUpdateMapper $contentMetadataUpdateMapper, - string $defaultSiteaccess, + NonAdminSiteaccessResolver $siteaccessResolver, LocationService $locationService ) { $this->notificationHandler = $notificationHandler; @@ -81,7 +84,7 @@ public function __construct( $this->submitHandler = $submitHandler; $this->translator = $translator; $this->contentMainLocationUpdateMapper = $contentMetadataUpdateMapper; - $this->defaultSiteaccess = $defaultSiteaccess; + $this->siteaccessResolver = $siteaccessResolver; $this->locationService = $locationService; } @@ -272,12 +275,21 @@ public function previewAction( $location = $this->locationService->loadLocation($content->contentInfo->mainLocationId); } + $siteaccesses = $this->siteaccessResolver->getSiteaccessesForLocation($location, $versionNo, $languageCode); + + if (empty($siteaccesses)) { + throw new BadStateException( + 'siteaccess', + 'There is no siteaccesses available for particular content' + ); + } + return $this->render('@EzPlatformAdminUi/content/content_preview.html.twig', [ + 'location' => $location, 'content' => $content, 'language_code' => $languageCode, - 'siteaccess' => $this->defaultSiteaccess, + 'siteaccesses' => $siteaccesses, 'versionNo' => $versionNo ?? $content->getVersionInfo()->versionNo, - 'location' => $location, ]); } } diff --git a/src/bundle/Resources/config/services.yml b/src/bundle/Resources/config/services.yml index 68660726e5..48837d6d88 100644 --- a/src/bundle/Resources/config/services.yml +++ b/src/bundle/Resources/config/services.yml @@ -10,6 +10,7 @@ imports: - { resource: services/modules/subitems.yml } - { resource: services/form_processors.yml } - { resource: services/validators.yml } + - { resource: services/siteaccess.yml } parameters: diff --git a/src/bundle/Resources/config/services/components.yml b/src/bundle/Resources/config/services/components.yml index e2ccdf7f2f..77a4e388ba 100644 --- a/src/bundle/Resources/config/services/components.yml +++ b/src/bundle/Resources/config/services/components.yml @@ -1,3 +1,6 @@ +imports: + - { resource: services/components/content/edit.yml } + services: _defaults: autowire: true diff --git a/src/bundle/Resources/config/services/components/content/edit.yml b/src/bundle/Resources/config/services/components/content/edit.yml new file mode 100644 index 0000000000..5ec29cc712 --- /dev/null +++ b/src/bundle/Resources/config/services/components/content/edit.yml @@ -0,0 +1,9 @@ +services: + _defaults: + public: false + autowire: true + autoconfigure: true + + EzSystems\EzPlatformAdminUi\Component\Content\PreviewUnavailableTwigComponent: + tags: + - { name: ezplatform.admin_ui.component, group: 'content-edit-form-before' } diff --git a/src/bundle/Resources/config/services/controllers.yml b/src/bundle/Resources/config/services/controllers.yml index 13f6cdf55c..f0a0afb04f 100644 --- a/src/bundle/Resources/config/services/controllers.yml +++ b/src/bundle/Resources/config/services/controllers.yml @@ -22,11 +22,6 @@ services: arguments: $defaultPaginationLimit: '$pagination.search_limit$' - EzSystems\EzPlatformAdminUiBundle\Controller\ContentController: - parent: EzSystems\EzPlatformAdminUiBundle\Controller\Controller - arguments: - $defaultSiteaccess: '%ezpublish.siteaccess.default%' - EzSystems\EzPlatformAdminUiBundle\Controller\User\UserDeleteController: parent: EzSystems\EzPlatformAdminUiBundle\Controller\Controller diff --git a/src/bundle/Resources/config/services/siteaccess.yml b/src/bundle/Resources/config/services/siteaccess.yml new file mode 100644 index 0000000000..3dfdeee74a --- /dev/null +++ b/src/bundle/Resources/config/services/siteaccess.yml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + EzSystems\EzPlatformAdminUi\Siteaccess\SiteaccessResolver: ~ + EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver: ~ diff --git a/src/bundle/Resources/public/js/scripts/admin.preview.js b/src/bundle/Resources/public/js/scripts/admin.preview.js index 08b2ff08bd..34e511f106 100644 --- a/src/bundle/Resources/public/js/scripts/admin.preview.js +++ b/src/bundle/Resources/public/js/scripts/admin.preview.js @@ -1,8 +1,9 @@ (function (global, doc) { const CLASS_BTN_SELECTED = 'ez-preview__action--selected'; const SELECTOR_BTN_ACTION = '.ez-preview__action'; + const SELECTOR_PREVIEW_SITEACCESS_SELECT = '.ez-preview__item--siteaccess select'; const removeSelectedState = () => [...doc.querySelectorAll(SELECTOR_BTN_ACTION)].forEach(btn => btn.classList.remove(CLASS_BTN_SELECTED)); - const changePreviewMode = event => { + const changePreviewMode = (event) => { const btn = event.target.closest(SELECTOR_BTN_ACTION); const iframeWrapper = doc.querySelector('.ez-preview__iframe'); @@ -13,6 +14,12 @@ iframeWrapper.classList.remove('ez-preview__iframe--desktop', 'ez-preview__iframe--tablet', 'ez-preview__iframe--mobile'); iframeWrapper.classList.add(`ez-preview__iframe--${btn.dataset.previewMode}`) }; + const changePreviewSiteaccess = (event) => { + const iframeWrapper = doc.querySelector('.ez-preview__iframe iframe'); + const siteaccessPreviewUrl = event.target.value; + iframeWrapper.setAttribute('src', siteaccessPreviewUrl); + }; [...doc.querySelectorAll(SELECTOR_BTN_ACTION)].forEach(btn => btn.addEventListener('click', changePreviewMode, false)); + [...doc.querySelectorAll(SELECTOR_PREVIEW_SITEACCESS_SELECT)].forEach(select => select.addEventListener('change', changePreviewSiteaccess, false)); })(window, document); diff --git a/src/bundle/Resources/public/scss/_alerts.scss b/src/bundle/Resources/public/scss/_alerts.scss new file mode 100644 index 0000000000..acb4b996d6 --- /dev/null +++ b/src/bundle/Resources/public/scss/_alerts.scss @@ -0,0 +1,9 @@ +.ez-alert { + &--info { + background: $ez-secondary-ground-pale; + color: $ez-secondary-ground-medium; + padding: 0.35rem 1rem; + border: 0; + font-style: italic; + } +} diff --git a/src/bundle/Resources/public/scss/_icons.scss b/src/bundle/Resources/public/scss/_icons.scss index d74d09a974..8dd6df8ef3 100644 --- a/src/bundle/Resources/public/scss/_icons.scss +++ b/src/bundle/Resources/public/scss/_icons.scss @@ -197,3 +197,9 @@ margin-right: .5rem; } } + +.ez-alert--info { + .ez-icon-warning { + fill: $ez-secondary-ground-medium; + } +} diff --git a/src/bundle/Resources/public/scss/_preview.scss b/src/bundle/Resources/public/scss/_preview.scss index 16577869d8..7965b709c3 100644 --- a/src/bundle/Resources/public/scss/_preview.scss +++ b/src/bundle/Resources/public/scss/_preview.scss @@ -14,24 +14,43 @@ align-items: center; justify-content: space-between; line-height: 0; + flex-basis: 10%; } &--actions { - flex-basis: auto; display: flex; justify-content: center; border: 1px solid $ez-color-base-medium; border-radius: 5px; padding: .1rem; background: $ez-white; + flex-basis: 5%; + margin-right: 2rem; + } + + &--description { + flex-basis: 75%; + display: flex; + align-items: center; + } + + &--siteaccess { + flex-basis: 10%; + } + + &-label { + display: inline-block; + margin-right: .5rem; + font-size: .8rem; } &-text { text-overflow: ellipsis; width: 80%; - display: block; overflow: hidden; + display: inline-block; white-space: nowrap; + font-weight: 700; } .ez-preview__action { diff --git a/src/bundle/Resources/public/scss/ezplatform.scss b/src/bundle/Resources/public/scss/ezplatform.scss index 9c4b63c995..029f6aeba1 100644 --- a/src/bundle/Resources/public/scss/ezplatform.scss +++ b/src/bundle/Resources/public/scss/ezplatform.scss @@ -21,6 +21,7 @@ @import 'typography'; @import 'content-edit'; @import 'card'; +@import 'alerts'; @import 'pagination'; @import 'error-page'; @import 'alloyeditor-link-edit'; diff --git a/src/bundle/Resources/translations/content_edit_component_preview_unavailable.en.xliff b/src/bundle/Resources/translations/content_edit_component_preview_unavailable.en.xliff new file mode 100644 index 0000000000..02687e9c67 --- /dev/null +++ b/src/bundle/Resources/translations/content_edit_component_preview_unavailable.en.xliff @@ -0,0 +1,16 @@ + + + +
+ + The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. +
+ + + You cannot preview this translation: there is no site available for this language. Please contact the website administrator. + You cannot preview this translation: there is no site available for this language. Please contact the website administrator. + key: preview_unavailable + + +
+
diff --git a/src/bundle/Resources/views/content/content_edit/component/preview_unavailable.html.twig b/src/bundle/Resources/views/content/content_edit/component/preview_unavailable.html.twig new file mode 100644 index 0000000000..895f78a472 --- /dev/null +++ b/src/bundle/Resources/views/content/content_edit/component/preview_unavailable.html.twig @@ -0,0 +1,10 @@ +{% trans_default_domain 'content_edit_component_preview_unavailable' %} + + diff --git a/src/bundle/Resources/views/content/content_edit/content_edit.html.twig b/src/bundle/Resources/views/content/content_edit/content_edit.html.twig index 92c8bb06cd..23db9b4129 100644 --- a/src/bundle/Resources/views/content/content_edit/content_edit.html.twig +++ b/src/bundle/Resources/views/content/content_edit/content_edit.html.twig @@ -38,7 +38,12 @@ {% endblock %} {% block right_sidebar %} - {% set content_edit_sidebar_right = knp_menu_get('ezplatform_admin_ui.menu.content_edit.sidebar_right', [], {'content': content, 'content_type': contentType}) %} + {% set content_edit_sidebar_right = knp_menu_get('ezplatform_admin_ui.menu.content_edit.sidebar_right', [], { + 'content': content, + 'content_type': contentType, + 'location': location, + 'language': language + }) %} {{ knp_menu_render(content_edit_sidebar_right, {'template': '@EzPlatformAdminUi/parts/menu/sidebar_right.html.twig'}) }} {% endblock %} @@ -49,13 +54,17 @@ {% block form_before %} {{ ezplatform_admin_ui_component_group('content-edit-form-before', { 'content': content, - 'contentType': contentType + 'contentType': contentType, + 'location': location, + 'language': language }) }} {% endblock %} {% block form_after %} {{ ezplatform_admin_ui_component_group('content-edit-form-after', { 'content': content, - 'contentType': contentType + 'contentType': contentType, + 'location': location, + 'language': language }) }} {% endblock %} diff --git a/src/bundle/Resources/views/content/content_preview.html.twig b/src/bundle/Resources/views/content/content_preview.html.twig index 8affa1c62b..12b118d10e 100644 --- a/src/bundle/Resources/views/content/content_preview.html.twig +++ b/src/bundle/Resources/views/content/content_preview.html.twig @@ -15,7 +15,10 @@ - {{ 'preview'|trans|desc('Preview') }} + +
+ {{ 'previewing'|trans|desc('Previewing') }}: + {{ content.name }}
-
- {{ content.name }} -
+ {% if siteaccesses|length > 1 %} +
+ +
+ {% endif %}
- +
{% endblock %} diff --git a/src/bundle/Resources/views/dashboard/tab/my_drafts.html.twig b/src/bundle/Resources/views/dashboard/tab/my_drafts.html.twig index ae2b1d15f8..2d7aeaf236 100644 --- a/src/bundle/Resources/views/dashboard/tab/my_drafts.html.twig +++ b/src/bundle/Resources/views/dashboard/tab/my_drafts.html.twig @@ -26,7 +26,8 @@ data-content-draft-edit-url="{{ path('ez_content_draft_edit', { 'contentId': row.contentId, 'versionNo': row.version, - 'language': row.language + 'language': row.language, + 'locationId': location.id }) }}" data-version-has-conflict-url="{{ path('ezplatform.version.has_no_conflict', { 'contentId': row.contentId, diff --git a/src/lib/Component/Content/PreviewUnavailableTwigComponent.php b/src/lib/Component/Content/PreviewUnavailableTwigComponent.php new file mode 100644 index 0000000000..07595ab33b --- /dev/null +++ b/src/lib/Component/Content/PreviewUnavailableTwigComponent.php @@ -0,0 +1,66 @@ +twig = $twig; + $this->siteaccessResolver = $siteaccessResolver; + } + + /** + * @param array $parameters + * + * @return string + */ + public function render(array $parameters = []): string + { + /** @var Location $location */ + $location = $parameters['location']; + /** @var Content $content */ + $content = $parameters['content']; + /** @var Language $language */ + $language = $parameters['language']; + + $siteaccesses = $this->siteaccessResolver->getSiteaccessesForLocation( + $location, + $content->getVersionInfo()->versionNo, + $language->languageCode + ); + + if (empty($siteaccesses)) { + return $this->twig->render( + 'EzPlatformAdminUiBundle:content/content_edit/component:preview_unavailable.html.twig' + ); + } + + return ''; + } +} diff --git a/src/lib/Menu/ContentEditRightSidebarBuilder.php b/src/lib/Menu/ContentEditRightSidebarBuilder.php index d2cf780e0f..3e502a6d06 100644 --- a/src/lib/Menu/ContentEditRightSidebarBuilder.php +++ b/src/lib/Menu/ContentEditRightSidebarBuilder.php @@ -7,11 +7,16 @@ namespace EzSystems\EzPlatformAdminUi\Menu; use eZ\Publish\API\Repository\Exceptions as ApiExceptions; +use eZ\Publish\API\Repository\Values\Content\Content; +use eZ\Publish\API\Repository\Values\Content\Language; +use eZ\Publish\API\Repository\Values\Content\Location; use EzSystems\EzPlatformAdminUi\Menu\Event\ConfigureMenuEvent; +use EzSystems\EzPlatformAdminUi\Siteaccess\NonAdminSiteaccessResolver; use InvalidArgumentException; use JMS\TranslationBundle\Model\Message; use JMS\TranslationBundle\Translation\TranslationContainerInterface; use Knp\Menu\ItemInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * KnpMenuBundle Menu Builder service implementation for AdminUI Content Edit contextual sidebar menu. @@ -20,6 +25,19 @@ */ class ContentEditRightSidebarBuilder extends AbstractBuilder implements TranslationContainerInterface { + /** @var NonAdminSiteaccessResolver */ + private $siteaccessResolver; + + public function __construct( + MenuItemFactory $factory, + EventDispatcherInterface $eventDispatcher, + NonAdminSiteaccessResolver $siteaccessResolver + ) { + parent::__construct($factory, $eventDispatcher); + + $this->siteaccessResolver = $siteaccessResolver; + } + /* Menu items */ const ITEM__PUBLISH = 'content_edit__sidebar_right__publish'; const ITEM__SAVE_DRAFT = 'content_edit__sidebar_right__save_draft'; @@ -48,7 +66,14 @@ public function createStructure(array $options): ItemInterface /** @var ItemInterface|ItemInterface[] $menu */ $menu = $this->factory->createItem('root'); - $menu->setChildren([ + /** @var Location $location */ + $location = $options['location']; + /** @var Content $content */ + $content = $options['content']; + /** @var Language $language */ + $language = $options['language']; + + $items = [ self::ITEM__PUBLISH => $this->createMenuItem( self::ITEM__PUBLISH, [ @@ -69,27 +94,37 @@ public function createStructure(array $options): ItemInterface 'extras' => ['icon' => 'save'], ] ), - self::ITEM__PREVIEW => $this->createMenuItem( - self::ITEM__PREVIEW, - [ - 'attributes' => [ - 'class' => 'btn--trigger', - 'data-click' => '#ezrepoforms_content_edit_preview', - ], - 'extras' => ['icon' => 'view-desktop'], - ] - ), - self::ITEM__CANCEL => $this->createMenuItem( - self::ITEM__CANCEL, - [ - 'attributes' => [ - 'class' => 'btn--trigger', - 'data-click' => '#ezrepoforms_content_edit_cancel', - ], - 'extras' => ['icon' => 'circle-close'], - ] - ), - ]); + ]; + + $siteaccesses = $this->siteaccessResolver->getSiteaccessesForLocation( + $location, + $content->getVersionInfo()->versionNo, + $language->languageCode + ); + $items[self::ITEM__PREVIEW] = $this->createMenuItem( + self::ITEM__PREVIEW, + [ + 'attributes' => [ + 'class' => 'btn--trigger', + 'data-click' => '#ezrepoforms_content_edit_preview', + 'disabled' => empty($siteaccesses), + ], + 'extras' => ['icon' => 'view-desktop'], + ] + ); + + $items[self::ITEM__CANCEL] = $this->createMenuItem( + self::ITEM__CANCEL, + [ + 'attributes' => [ + 'class' => 'btn--trigger', + 'data-click' => '#ezrepoforms_content_edit_cancel', + ], + 'extras' => ['icon' => 'circle-close'], + ] + ); + + $menu->setChildren($items); return $menu; } diff --git a/src/lib/RepositoryForms/Form/Processor/PreviewFormProcessor.php b/src/lib/RepositoryForms/Form/Processor/PreviewFormProcessor.php index 0c6513c47e..32c1f0a24c 100644 --- a/src/lib/RepositoryForms/Form/Processor/PreviewFormProcessor.php +++ b/src/lib/RepositoryForms/Form/Processor/PreviewFormProcessor.php @@ -15,6 +15,7 @@ use eZ\Publish\API\Repository\Exceptions\ContentValidationException; use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException; use eZ\Publish\API\Repository\Exceptions\UnauthorizedException; +use eZ\Publish\API\Repository\LocationService; use eZ\Publish\API\Repository\Values\Content\Content; use eZ\Publish\API\Repository\Values\Content\ContentStruct; use EzSystems\EzPlatformAdminUi\Form\Event\ContentEditEvents; @@ -48,22 +49,28 @@ class PreviewFormProcessor implements EventSubscriberInterface /** @var TranslatorInterface */ private $translator; + /** @var LocationService */ + private $locationService; + /** * @param ContentService $contentService * @param UrlGeneratorInterface $urlGenerator * @param NotificationHandlerInterface $notificationHandler * @param TranslatorInterface $translator + * @param LocationService $locationService */ public function __construct( ContentService $contentService, UrlGeneratorInterface $urlGenerator, NotificationHandlerInterface $notificationHandler, - TranslatorInterface $translator + TranslatorInterface $translator, + LocationService $locationService ) { $this->contentService = $contentService; $this->urlGenerator = $urlGenerator; $this->notificationHandler = $notificationHandler; $this->translator = $translator; + $this->locationService = $locationService; } /** @@ -94,7 +101,7 @@ public function processPreview(FormActionEvent $event): void $url = $this->urlGenerator->generate('ezplatform.content.preview', [ 'locationId' => null !== $referrerLocation ? $referrerLocation->id - : $contentDraft->contentInfo->mainLocationId, + : $this->resolveMainLocationId($contentDraft), 'contentId' => $contentDraft->id, 'versionNo' => $contentDraft->getVersionInfo()->versionNo, 'languageCode' => $languageCode, @@ -185,4 +192,21 @@ private function resolveMainLanguageCode($data): string ? $data->mainLanguageCode : $data->contentDraft->getVersionInfo()->getContentInfo()->mainLanguageCode; } + + /** + * @param Content $contentDraft + * + * @return int + */ + private function resolveMainLocationId(Content $contentDraft) + { + $mainLocationId = $contentDraft->contentInfo->mainLocationId; + + if (null === $mainLocationId && !$contentDraft->contentInfo->published) { + $parentLocation = $this->locationService->loadParentLocationsForDraftContent($contentDraft->getVersionInfo())[0]; + $mainLocationId = $parentLocation->id; + } + + return (int) $mainLocationId; + } } diff --git a/src/lib/Siteaccess/NonAdminSiteaccessResolver.php b/src/lib/Siteaccess/NonAdminSiteaccessResolver.php new file mode 100644 index 0000000000..2903b7bc2e --- /dev/null +++ b/src/lib/Siteaccess/NonAdminSiteaccessResolver.php @@ -0,0 +1,65 @@ +siteaccessResolver = $siteaccessResolver; + $this->configResolver = $configResolver; + } + + public function getSiteaccessesForLocation( + Location $location, + int $versionNo = null, + string $languageCode = null + ): array { + return $this->filter( + $this->siteaccessResolver->getSiteaccessesForLocation($location, $versionNo, $languageCode) + ); + } + + public function getSiteaccesses(): array + { + return $this->filter($this->siteaccessResolver->getSiteaccesses()); + } + + private function filter(array $siteaccesses) + { + $siteaccessGroups = $this->configResolver->getParameter( + 'groups', + 'ezpublish', + 'siteaccess' + ); + + if (!array_key_exists('admin_group', $siteaccessGroups)) { + throw new BadStateException( + 'siteaccess', + 'Siteaccess group `admin_group` not found.' + ); + } + + return array_diff($siteaccesses, $siteaccessGroups['admin_group']); + } +} diff --git a/src/lib/Siteaccess/SiteaccessResolver.php b/src/lib/Siteaccess/SiteaccessResolver.php new file mode 100644 index 0000000000..8776f74923 --- /dev/null +++ b/src/lib/Siteaccess/SiteaccessResolver.php @@ -0,0 +1,80 @@ +configResolver = $configResolver; + $this->contentService = $contentService; + } + + public function getSiteaccessesForLocation( + Location $location, + int $versionNo = null, + string $languageCode = null + ): array { + $languageCode = $languageCode ?? $location->getContentInfo()->mainLanguageCode; + $versionInfo = $this->contentService->loadVersionInfo($location->getContentInfo(), $versionNo); + $contentLanguages = $versionInfo->languageCodes; + + $eligibleSiteaccesses = []; + foreach ($this->getSiteaccesses() as $siteaccess) { + $rootLocationId = $this->configResolver->getParameter( + 'content.tree_root.location_id', + null, + $siteaccess + ); + if (!in_array($rootLocationId, $location->path)) { + continue; + } + + $siteaccessLanguages = $this->configResolver->getParameter( + 'languages', + null, + $siteaccess + ); + if (!in_array($languageCode, $siteaccessLanguages)) { + continue; + } + + $primarySiteaccessLanguage = reset($siteaccessLanguages); + if ( + $languageCode !== $primarySiteaccessLanguage + && in_array($primarySiteaccessLanguage, $contentLanguages) + ) { + continue; + } + + $eligibleSiteaccesses[] = $siteaccess; + } + + return $eligibleSiteaccesses; + } + + public function getSiteaccesses(): array + { + return $this->configResolver->getParameter('list', 'ezpublish', 'siteaccess'); + } +}