Skip to content

Commit

Permalink
EZP-30344: Improved handling Language Limitation (#934)
Browse files Browse the repository at this point in the history
* Improved handling Language Limitation

* Disabled HTTP cache for ContentController::checkEditPermissionAction

* Enabled right sidebar edit button for translated Content

Editing should be possible if Content is already translated.

* Added permission check for edit button in Sub-items

Co-authored-by: Jakub <[email protected]>
  • Loading branch information
2 people authored and alongosz committed Apr 18, 2019
1 parent 6c5b0f9 commit 1c52307
Show file tree
Hide file tree
Showing 25 changed files with 478 additions and 106 deletions.
71 changes: 69 additions & 2 deletions src/bundle/Controller/ContentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
use eZ\Publish\API\Repository\Exceptions as ApiException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\PermissionResolver;
use eZ\Publish\API\Repository\UserService;
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 eZ\Publish\API\Repository\Values\User\Limitation;
use eZ\Publish\Core\Base\Exceptions\BadStateException;
use eZ\Publish\SPI\Limitation\Target;
use EzSystems\EzPlatformAdminUi\Exception\InvalidArgumentException as AdminInvalidArgumentException;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\ContentVisibilityUpdateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentCreateData;
Expand All @@ -28,9 +31,11 @@
use EzSystems\EzPlatformAdminUi\Form\Type\Content\ContentVisibilityUpdateType;
use EzSystems\EzPlatformAdminUi\Form\Type\Content\Translation\MainTranslationUpdateType;
use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface;
use EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer;
use EzSystems\EzPlatformAdminUi\Siteaccess\SiteaccessResolverInterface;
use EzSystems\EzPlatformAdminUi\Specification\ContentIsUser;
use EzSystems\EzPlatformAdminUi\Specification\ContentType\ContentTypeIsUser;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down Expand Up @@ -69,6 +74,12 @@ class ContentController extends Controller
/** @var \eZ\Publish\API\Repository\UserService */
private $userService;

/** @var \eZ\Publish\API\Repository\PermissionResolver */
private $permissionResolver;

/** @var \EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer */
private $lookupLimitationsTransformer;

/** @var array */
private $userContentTypeIdentifier;

Expand All @@ -82,6 +93,8 @@ class ContentController extends Controller
* @param \EzSystems\EzPlatformAdminUi\Siteaccess\SiteaccessResolverInterface $siteaccessResolver
* @param \eZ\Publish\API\Repository\LocationService $locationService
* @param \eZ\Publish\API\Repository\UserService $userService
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
* @param \EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer $lookupLimitationsTransformer
* @param array $userContentTypeIdentifier
*/
public function __construct(
Expand All @@ -94,6 +107,8 @@ public function __construct(
SiteaccessResolverInterface $siteaccessResolver,
LocationService $locationService,
UserService $userService,
PermissionResolver $permissionResolver,
LookupLimitationsTransformer $lookupLimitationsTransformer,
array $userContentTypeIdentifier
) {
$this->notificationHandler = $notificationHandler;
Expand All @@ -106,6 +121,8 @@ public function __construct(
$this->locationService = $locationService;
$this->userService = $userService;
$this->userContentTypeIdentifier = $userContentTypeIdentifier;
$this->permissionResolver = $permissionResolver;
$this->lookupLimitationsTransformer = $lookupLimitationsTransformer;
}

/**
Expand Down Expand Up @@ -340,7 +357,7 @@ public function previewAction(
}

/**
* @param Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
Expand Down Expand Up @@ -388,7 +405,7 @@ public function updateMainTranslationAction(Request $request): Response
}

/**
* @param Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
Expand Down Expand Up @@ -459,6 +476,56 @@ public function updateVisibilityAction(Request $request): Response
return $result instanceof Response ? $result : $this->redirectToRoute('ezplatform.dashboard');
}

/**
* @param \eZ\Publish\API\Repository\Values\Content\Content $content
* @param string|null $languageCode
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
public function checkEditPermissionAction(Content $content, ?string $languageCode): JsonResponse
{
$targets = [];

if (null !== $languageCode) {
$targets[] = (new Target\Builder\VersionBuilder())->translateToAnyLanguageOf([$languageCode])->build();
}

$canEdit = $this->permissionResolver->canUser(
'content',
'edit',
$content,
$targets
);

$lookupLimitations = $this->permissionResolver->lookupLimitations(
'content',
'edit',
$content,
$targets,
[Limitation::LANGUAGE]
);

$editLanguagesLimitationValues = $this->lookupLimitationsTransformer->getFlattenedLimitationsValues($lookupLimitations);

$response = new JsonResponse();
$response->setData([
'canEdit' => $canEdit,
'editLanguagesLimitationValues' => $canEdit ? $editLanguagesLimitationValues : [],
]);

// Disable HTTP cache
$response->setPrivate();
$response->setMaxAge(0);
$response->setSharedMaxAge(0);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->headers->addCacheControlDirective('no-store', true);

return $response;
}

/**
* @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
* @param \eZ\Publish\API\Repository\Values\Content\Language $language
Expand Down
26 changes: 23 additions & 3 deletions src/bundle/Controller/ContentViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
use EzSystems\EzPlatformAdminUi\Form\Data\User\UserDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\User\UserEditData;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
use EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\ContentEditTranslationChoiceLoader;
use EzSystems\EzPlatformAdminUi\Form\Type\Content\ContentVisibilityUpdateType;
use EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer;
use EzSystems\EzPlatformAdminUi\Specification\Content\ContentHaveAssetRelation;
use EzSystems\EzPlatformAdminUi\Specification\Content\ContentHaveUniqueRelation;
use EzSystems\EzPlatformAdminUi\Specification\ContentIsUser;
Expand Down Expand Up @@ -91,6 +93,9 @@ class ContentViewController extends Controller
/** @var \eZ\Publish\API\Repository\PermissionResolver */
private $permissionResolver;

/** @var \EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer */
private $lookupLimitationsTransformer;

/**
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
* @param \eZ\Publish\API\Repository\LanguageService $languageService
Expand All @@ -106,6 +111,7 @@ class ContentViewController extends Controller
* @param \eZ\Publish\Core\MVC\ConfigResolverInterface $configResolver
* @param \eZ\Publish\API\Repository\Repository $repository
* @param \eZ\Publish\API\Repository\PermissionResolver $permissionResolver
* @param \EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer $lookupLimitationsTransformer
*/
public function __construct(
ContentTypeService $contentTypeService,
Expand All @@ -121,7 +127,8 @@ public function __construct(
UserLanguagePreferenceProviderInterface $userLanguagePreferenceProvider,
ConfigResolverInterface $configResolver,
Repository $repository,
PermissionResolver $permissionResolver
PermissionResolver $permissionResolver,
LookupLimitationsTransformer $lookupLimitationsTransformer
) {
$this->contentTypeService = $contentTypeService;
$this->languageService = $languageService;
Expand All @@ -135,8 +142,9 @@ public function __construct(
$this->locationService = $locationService;
$this->userLanguagePreferenceProvider = $userLanguagePreferenceProvider;
$this->configResolver = $configResolver;
$this->repository = $repository;
$this->permissionResolver = $permissionResolver;
$this->lookupLimitationsTransformer = $lookupLimitationsTransformer;
$this->repository = $repository;
}

/**
Expand Down Expand Up @@ -347,8 +355,20 @@ private function createContentEditForm(
?Language $language = null,
?Location $location = null
): FormInterface {
$languageCodes = $versionInfo->languageCodes ?? [];

return $this->formFactory->contentEdit(
new ContentEditData($contentInfo, $versionInfo, $language, $location)
new ContentEditData($contentInfo, $versionInfo, $language, $location),
null,
[
'choice_loader' => new ContentEditTranslationChoiceLoader(
$this->languageService,
$this->permissionResolver,
$contentInfo,
$this->lookupLimitationsTransformer,
$languageCodes
),
]
);
}

Expand Down
1 change: 1 addition & 0 deletions src/bundle/Resources/config/bazinga_js_translation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ active_domains:
- 'fieldtypes_edit'
- 'notifications'
- 'search'
- 'content'
8 changes: 8 additions & 0 deletions src/bundle/Resources/config/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,14 @@ ezplatform.content.translate:
_controller: 'EzPlatformAdminUiBundle:ContentEdit:translate'
fromLanguageCode: ~

ezplatform.content.check_edit_permission:
path: /content/{contentId}/check-edit-permission/{languageCode}
options:
expose: true
defaults:
_controller: 'EzPlatformAdminUiBundle:Content:checkEditPermission'
languageCode: ~

#
# Search
#
Expand Down
2 changes: 2 additions & 0 deletions src/bundle/Resources/config/services/permissions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ services:

EzSystems\EzPlatformAdminUi\Permission\PermissionCheckerInterface:
alias: EzSystems\EzPlatformAdminUi\Permission\PermissionChecker

EzSystems\EzPlatformAdminUi\Permission\LookupLimitationsTransformer: ~
43 changes: 31 additions & 12 deletions src/bundle/Resources/public/js/scripts/admin.location.view.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(function(global, doc, $, React, ReactDOM, eZ, Routing) {
(function(global, doc, $, React, ReactDOM, eZ, Routing, Translator) {
const SELECTOR_MODAL_BULK_ACTION_FAIL = '#bulk-action-failed-modal';
const listContainers = doc.querySelectorAll('.ez-sil');
const mfuContainer = doc.querySelector('#ez-mfu');
Expand Down Expand Up @@ -49,17 +49,36 @@
);
$('#version-draft-conflict-modal').modal('show');
};
fetch(checkVersionDraftLink, {
credentials: 'same-origin',
}).then((response) => {
// Status 409 means that a draft conflict has occurred and the modal must be displayed.
// Otherwise we can go to Content Item edit page.
if (response.status === 409) {
response.text().then(showModal);
} else if (response.status === 200) {
submitVersionEditForm();
}
const checkEditPermissionLink = Routing.generate('ezplatform.content.check_edit_permission', {
contentId,
languageCode: content.mainLanguageCode,
});
const errorMessage = Translator.trans(
/*@Desc("You don't have permission to edit the content")*/ 'content.edit.permission.error',
{},
'content'
);
const handleCanEditCheck = (response) => {
if (response.canEdit) {
return fetch(checkVersionDraftLink, { mode: 'same-origin', credentials: 'same-origin' });
}

throw new Error(errorMessage);
};

fetch(checkEditPermissionLink, { mode: 'same-origin', credentials: 'same-origin' })
.then(eZ.helpers.request.getJsonFromResponse)
.then(handleCanEditCheck)
.then((response) => {
// Status 409 means that a draft conflict has occurred and the modal must be displayed.
// Otherwise we can go to Content Item edit page.
if (response.status === 409) {
response.text().then(showModal);
} else if (response.status === 200) {
submitVersionEditForm();
}
})
.catch(eZ.helpers.notification.showErrorNotification);
};
const generateLink = (locationId) => Routing.generate('_ezpublishLocation', { locationId });
const setModalTableTitle = (title) => {
Expand Down Expand Up @@ -149,4 +168,4 @@
container
);
});
})(window, window.document, window.jQuery, window.React, window.ReactDOM, window.eZ, window.Routing);
})(window, window.document, window.jQuery, window.React, window.ReactDOM, window.eZ, window.Routing, window.Translator);
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
(function (global, doc, $) {
(function (global, doc, $, eZ, Translator) {
const editVersion = (event) => {
const showErrorNotification = eZ.helpers.notification.showErrorNotification;
const contentDraftEditUrl = event.currentTarget.dataset.contentDraftEditUrl;
const versionHasConflictUrl = event.currentTarget.dataset.versionHasConflictUrl;
const contentId = event.currentTarget.dataset.contentId;
const languageCode = event.currentTarget.dataset.languageCode;
const checkEditPermissionLink = global.Routing.generate('ezplatform.content.check_edit_permission', { contentId, languageCode });
const errorMessage = Translator.trans(
/*@Desc("You don't have permission to edit the content")*/ 'content.edit.permission.error',
{},
'content'
);
const handleCanEditCheck = (response) => {
if (response.canEdit) {
return fetch(versionHasConflictUrl, { mode: 'same-origin', credentials: 'same-origin' });
}

event.preventDefault();

fetch(versionHasConflictUrl, {
credentials: 'same-origin'
}).then(function (response) {
throw new Error(errorMessage);
};
const handleVersionDraftConflict = (response) => {
// Status 409 means that a draft conflict has occurred and the modal must be displayed.
// Otherwise we can go to Content Item edit page.
if (response.status === 409) {
doc.querySelector('#edit-conflicted-draft').href = contentDraftEditUrl;
$('#version-conflict-modal').modal('show');
}
if (response.status === 403) {
response.text().then(showErrorNotification);
}
if (response.status === 200) {
global.location.href = contentDraftEditUrl;
}
})
};

event.preventDefault();

fetch(checkEditPermissionLink, { mode: 'same-origin', credentials: 'same-origin' })
.then(eZ.helpers.request.getJsonFromResponse)
.then(handleCanEditCheck)
.then(handleVersionDraftConflict)
.catch(showErrorNotification);
};

[...doc.querySelectorAll('.ez-btn--content-draft-edit')].forEach(link => link.addEventListener('click', editVersion, false));
})(window, document, window.jQuery);
doc.querySelectorAll('.ez-btn--content-draft-edit').forEach((button) => button.addEventListener('click', editVersion, false));
})(window, document, window.jQuery, window.eZ, window.Translator);
Loading

0 comments on commit 1c52307

Please sign in to comment.