Skip to content

EZEE-3484: Create translated draft before edit if autosave is enabled #1714

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

Merged
merged 9 commits into from
Mar 9, 2021
38 changes: 38 additions & 0 deletions src/bundle/Controller/ContentEditController.php
Original file line number Diff line number Diff line change
@@ -6,11 +6,49 @@
*/
namespace EzSystems\EzPlatformAdminUiBundle\Controller;

use EzSystems\EzPlatformAdminUi\Event\ContentProxyTranslateEvent;
use EzSystems\EzPlatformAdminUi\View\ContentTranslateSuccessView;
use EzSystems\EzPlatformAdminUi\View\ContentTranslateView;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class ContentEditController extends Controller
{
/** @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface */
private $eventDispatcher;

public function __construct(
EventDispatcherInterface $eventDispatcher
) {
$this->eventDispatcher = $eventDispatcher;
}

public function proxyTranslateAction(
int $contentId,
?string $fromLanguageCode,
string $toLanguageCode
): Response {
/** @var \EzSystems\EzPlatformAdminUi\Event\ContentProxyTranslateEvent $event */
$event = $this->eventDispatcher->dispatch(
new ContentProxyTranslateEvent(
$contentId,
$fromLanguageCode,
$toLanguageCode
)
);

if ($event->hasResponse()) {
return $event->getResponse();
}

// Fallback to "translate"
return $this->redirectToRoute('ezplatform.content.translate', [
'contentId' => $contentId,
'fromLanguageCode' => $fromLanguageCode,
'toLanguageCode' => $toLanguageCode,
]);
}

/**
* @param \EzSystems\EzPlatformAdminUi\View\ContentTranslateView $view
*
2 changes: 1 addition & 1 deletion src/bundle/Controller/TranslationController.php
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ public function addAction(Request $request): Response
$language = $data->getLanguage();
$baseLanguage = $data->getBaseLanguage();

return new RedirectResponse($this->generateUrl('ezplatform.content.translate', [
return new RedirectResponse($this->generateUrl('ezplatform.content.translate.proxy', [
'contentId' => $contentInfo->id,
'fromLanguageCode' => null !== $baseLanguage ? $baseLanguage->languageCode : null,
'toLanguageCode' => $language->languageCode,
7 changes: 7 additions & 0 deletions src/bundle/Resources/config/routing.yaml
Original file line number Diff line number Diff line change
@@ -555,6 +555,13 @@ ezplatform.content.translate:
_controller: 'EzSystems\EzPlatformAdminUiBundle\Controller\ContentEditController::translateAction'
fromLanguageCode: ~

ezplatform.content.translate.proxy:
path: /content/{contentId}/translate/proxy/{toLanguageCode}/{fromLanguageCode}
methods: ['GET', 'POST']
defaults:
_controller: 'EzSystems\EzPlatformAdminUiBundle\Controller\ContentEditController::proxyTranslateAction'
fromLanguageCode: ~

ezplatform.content.check_edit_permission:
path: /content/{contentId}/check-edit-permission/{languageCode}
options:
19 changes: 11 additions & 8 deletions src/lib/Event/ContentProxyCreateEvent.php
Original file line number Diff line number Diff line change
@@ -12,33 +12,36 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\Event;

class ContentProxyCreateEvent extends Event
/**
* @internal
*/
final class ContentProxyCreateEvent extends Event
{
/** @var \Symfony\Component\HttpFoundation\Response|null */
protected $response;
private $response;

/** @var \eZ\Publish\API\Repository\Values\ContentType\ContentType */
protected $contentType;
private $contentType;

/** @var string */
protected $languageCode;
private $languageCode;

/** @var int */
protected $parentLocationId;
private $parentLocationId;

/** @var \EzSystems\EzPlatformAdminUi\Event\Options */
protected $options;
private $options;

public function __construct(
ContentType $contentType,
string $languageCode,
int $parentLocationId,
Options $options
?Options $options = null
) {
$this->contentType = $contentType;
$this->languageCode = $languageCode;
$this->parentLocationId = $parentLocationId;
$this->options = $options;
$this->options = $options ?? new Options();
}

public function getContentType(): ContentType
80 changes: 80 additions & 0 deletions src/lib/Event/ContentProxyTranslateEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\Event;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\Event;

/**
* @internal
*/
final class ContentProxyTranslateEvent extends Event
{
/** @var \Symfony\Component\HttpFoundation\Response|null */
private $response;

/** @var int */
private $contentId;

/** @var string|null */
private $fromLanguageCode;

/** @var string */
private $toLanguageCode;

/** @var \EzSystems\EzPlatformAdminUi\Event\Options */
private $options;

public function __construct(
int $contentId,
?string $fromLanguageCode,
string $toLanguageCode,
?Options $options = null
) {
$this->contentId = $contentId;
$this->fromLanguageCode = $fromLanguageCode;
$this->toLanguageCode = $toLanguageCode;
$this->options = $options ?? new Options();
}

public function getContentId(): int
{
return $this->contentId;
}

public function getFromLanguageCode(): ?string
{
return $this->fromLanguageCode;
}

public function getToLanguageCode(): string
{
return $this->toLanguageCode;
}

public function getOptions(): Options
{
return $this->options;
}

public function getResponse(): ?Response
{
return $this->response;
}

public function setResponse(Response $response): void
{
$this->response = $response;
}

public function hasResponse(): bool
{
return isset($this->response);
}
}
84 changes: 74 additions & 10 deletions src/lib/EventListener/ContentProxyCreateDraftListener.php
Original file line number Diff line number Diff line change
@@ -10,7 +10,10 @@

use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\API\Repository\Values\Content\Field;
use EzSystems\EzPlatformAdminUi\Event\ContentProxyCreateEvent;
use EzSystems\EzPlatformAdminUi\Event\ContentProxyTranslateEvent;
use EzSystems\EzPlatformAdminUi\UserSetting\Autosave as AutosaveSetting;
use EzSystems\EzPlatformUser\UserSetting\UserSettingService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -46,50 +49,111 @@ public function __construct(
public static function getSubscribedEvents(): array
{
return [
ContentProxyCreateEvent::class => 'createDraft',
ContentProxyCreateEvent::class => 'create',
ContentProxyTranslateEvent::class => 'translate',
];
}

public function createDraft(ContentProxyCreateEvent $event)
public function create(ContentProxyCreateEvent $event): void
{
$isAutosaveEnabled = $this->userSettingService->getUserSetting('autosave')->value === AutosaveSetting::ENABLED_OPTION;

if (!$isAutosaveEnabled) {
return;
}

$createContentTypeStuct = $this->contentService->newContentCreateStruct(
$options = $event->getOptions();

$createContentStruct = $this->contentService->newContentCreateStruct(
$event->getContentType(),
$event->getLanguageCode()
);

$contentDraft = $this->contentService->createContent(
$createContentTypeStuct,
$createContentStruct,
[
$this->locationService->newLocationCreateStruct($event->getParentLocationId()),
],
[]
);

if (!$event->getOptions()->get('isOnTheFly', false)) {
if ($options->get('isOnTheFly', false)) {
$response = new RedirectResponse(
$this->router->generate('ezplatform.content.draft.edit', [
$this->router->generate('ezplatform.content_on_the_fly.edit', [
'contentId' => $contentDraft->id,
'versionNo' => $contentDraft->getVersionInfo()->versionNo,
'language' => $event->getLanguageCode(),
'languageCode' => $event->getLanguageCode(),
'locationId' => $contentDraft->contentInfo->mainLocationId,
])
);
} else {
$response = new RedirectResponse(
$this->router->generate('ezplatform.content_on_the_fly.edit', [
$this->router->generate('ezplatform.content.draft.edit', [
'contentId' => $contentDraft->id,
'versionNo' => $contentDraft->getVersionInfo()->versionNo,
'languageCode' => $event->getLanguageCode(),
'locationId' => $contentDraft->contentInfo->mainLocationId,
'language' => $event->getLanguageCode(),
])
);
}

$event->setResponse($response);
}

public function translate(ContentProxyTranslateEvent $event): void
Copy link
Member

@adamwojs adamwojs Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need test coverage for this code. See #1714 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, true.

{
$isAutosaveEnabled = $this->userSettingService->getUserSetting('autosave')->value === AutosaveSetting::ENABLED_OPTION;

if (!$isAutosaveEnabled) {
return;
}

$content = $this->contentService->loadContent(
$event->getContentId(),
$event->getFromLanguageCode() !== null
? [$event->getFromLanguageCode()]
: null
);

$toLanguageCode = $event->getToLanguageCode();

$contentUpdateStruct = $this->contentService->newContentUpdateStruct();
$contentUpdateStruct->initialLanguageCode = $toLanguageCode;
$contentUpdateStruct->fields = $this->getTranslatedContentFields($content, $toLanguageCode);

$contentDraft = $this->contentService->createContentDraft($content->contentInfo);

$this->contentService->updateContent(
$contentDraft->getVersionInfo(),
$contentUpdateStruct,
[]
);

$response = new RedirectResponse(
$this->router->generate('ezplatform.content.draft.edit', [
'contentId' => $contentDraft->id,
'versionNo' => $contentDraft->getVersionInfo()->versionNo,
'language' => $toLanguageCode,
])
);

$event->setResponse($response);
}

private function getTranslatedContentFields(Content $content, string $languageCode): array
{
$contentType = $content->getContentType();

$translatableFields = array_filter($content->getFields(), static function (Field $field) use ($contentType): bool {
return $contentType->getFieldDefinition($field->fieldDefIdentifier)->isTranslatable;
});

return array_map(static function (Field $field) use ($languageCode): Field {
return new Field([
'value' => $field->value,
'fieldDefIdentifier' => $field->fieldDefIdentifier,
'fieldTypeIdentifier' => $field->fieldTypeIdentifier,
'languageCode' => $languageCode,
]);
}, $translatableFields);
}
}