Skip to content

Commit

Permalink
IBX-7287: Introduced Autosave API (#1082)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwojs authored Jan 11, 2024
1 parent 6369d3a commit c0814c5
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 76 deletions.
5 changes: 5 additions & 0 deletions src/bundle/Resources/config/services/autosave.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ services:
autowire: true
public: false

Ibexa\AdminUi\Autosave\AutosaveService: ~

Ibexa\Contracts\AdminUi\Autosave\AutosaveServiceInterface:
alias: Ibexa\AdminUi\Autosave\AutosaveService

Ibexa\AdminUi\EventListener\ContentProxyCreateDraftListener: ~

Ibexa\AdminUi\Form\Processor\Content\AutosaveProcessor:
Expand Down
26 changes: 26 additions & 0 deletions src/contracts/Autosave/AutosaveServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

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

namespace Ibexa\Contracts\AdminUi\Autosave;

interface AutosaveServiceInterface
{
public function isEnabled(): bool;

/**
* Returns autosave interval in milliseconds.
*/
public function getInterval(): int;

public function isInProgress(): bool;

/**
* @internal
*/
public function setInProgress(bool $isInProgress): void;
}
49 changes: 49 additions & 0 deletions src/lib/Autosave/AutosaveService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

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

namespace Ibexa\AdminUi\Autosave;

use Ibexa\AdminUi\UserSetting\Autosave;
use Ibexa\AdminUi\UserSetting\AutosaveInterval;
use Ibexa\Contracts\AdminUi\Autosave\AutosaveServiceInterface;
use Ibexa\User\UserSetting\UserSettingService;

final class AutosaveService implements AutosaveServiceInterface
{
private UserSettingService $userSettingService;

private bool $inProgress = false;

public function __construct(UserSettingService $userSettingService)
{
$this->userSettingService = $userSettingService;
}

public function isEnabled(): bool
{
return $this->userSettingService->getUserSetting(Autosave::IDENTIFIER)->value === Autosave::ENABLED_OPTION;
}

/**
* Returns autosave interval in milliseconds.
*/
public function getInterval(): int
{
return (int)$this->userSettingService->getUserSetting(AutosaveInterval::IDENTIFIER)->value * 1000;
}

public function isInProgress(): bool
{
return $this->inProgress;
}

public function setInProgress(bool $isInProgress): void
{
$this->inProgress = $isInProgress;
}
}
27 changes: 9 additions & 18 deletions src/lib/EventListener/ContentProxyCreateDraftListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,36 @@

namespace Ibexa\AdminUi\EventListener;

use Ibexa\AdminUi\UserSetting\Autosave as AutosaveSetting;
use Ibexa\Contracts\AdminUi\Autosave\AutosaveServiceInterface;
use Ibexa\Contracts\AdminUi\Event\ContentProxyCreateEvent;
use Ibexa\Contracts\AdminUi\Event\ContentProxyTranslateEvent;
use Ibexa\Contracts\Core\Repository\ContentService;
use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
use Ibexa\User\UserSetting\UserSettingService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;

class ContentProxyCreateDraftListener implements EventSubscriberInterface
{
/** @var \Ibexa\Contracts\Core\Repository\ContentService */
private $contentService;
private ContentService $contentService;

/** @var \Ibexa\Contracts\Core\Repository\LocationService */
private $locationService;
private LocationService $locationService;

/** @var \Ibexa\User\UserSetting\UserSettingService */
private $userSettingService;
private AutosaveServiceInterface $autosaveService;

/** @var \Symfony\Component\Routing\RouterInterface */
private $router;
private RouterInterface $router;

public function __construct(
ContentService $contentService,
LocationService $locationService,
UserSettingService $userSettingService,
AutosaveServiceInterface $autosaveService,
RouterInterface $router
) {
$this->contentService = $contentService;
$this->locationService = $locationService;
$this->userSettingService = $userSettingService;
$this->autosaveService = $autosaveService;
$this->router = $router;
}

Expand All @@ -56,9 +51,7 @@ public static function getSubscribedEvents(): array

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

if (!$isAutosaveEnabled) {
if (!$this->autosaveService->isEnabled()) {
return;
}

Expand Down Expand Up @@ -103,9 +96,7 @@ public function create(ContentProxyCreateEvent $event): void

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

if (!$isAutosaveEnabled) {
if (!$this->autosaveService->isEnabled()) {
return;
}

Expand Down
11 changes: 9 additions & 2 deletions src/lib/Form/Processor/Content/AutosaveProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@

use Ibexa\ContentForms\Event\FormActionEvent;
use Ibexa\ContentForms\Form\Processor\ContentFormProcessor;
use Ibexa\Contracts\AdminUi\Autosave\AutosaveServiceInterface;
use Ibexa\Contracts\AdminUi\Event\AutosaveEvents;
use Ibexa\Contracts\Core\Repository\Exceptions\Exception as APIException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;

class AutosaveProcessor implements EventSubscriberInterface
{
/** @var \Ibexa\ContentForms\Form\Processor\ContentFormProcessor */
private $innerContentFormProcessor;
private AutosaveServiceInterface $autosaveService;

private ContentFormProcessor $innerContentFormProcessor;

public function __construct(
AutosaveServiceInterface $autosaveService,
ContentFormProcessor $innerContentFormProcessor
) {
$this->autosaveService = $autosaveService;
$this->innerContentFormProcessor = $innerContentFormProcessor;
}

Expand All @@ -36,10 +40,13 @@ public static function getSubscribedEvents(): array
public function processAutosave(FormActionEvent $event): void
{
try {
$this->autosaveService->setInProgress(true);
$this->innerContentFormProcessor->processSaveDraft($event);
$statusCode = Response::HTTP_OK;
} catch (APIException $exception) {
$statusCode = Response::HTTP_BAD_REQUEST;
} finally {
$this->autosaveService->setInProgress(false);
}

$event->setResponse(
Expand Down
20 changes: 7 additions & 13 deletions src/lib/UI/Config/Provider/Autosave.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,23 @@

namespace Ibexa\AdminUi\UI\Config\Provider;

use Ibexa\AdminUi\UserSetting\Autosave as AutosaveSetting;
use Ibexa\Contracts\AdminUi\Autosave\AutosaveServiceInterface;
use Ibexa\Contracts\AdminUi\UI\Config\ProviderInterface;
use Ibexa\User\UserSetting\UserSettingService;

class Autosave implements ProviderInterface
{
/** @var \Ibexa\User\UserSetting\UserSettingService */
private $userSettingService;
private AutosaveServiceInterface $autosaveService;

public function __construct(
UserSettingService $userSettingService
) {
$this->userSettingService = $userSettingService;
public function __construct(AutosaveServiceInterface $autosaveService)
{
$this->autosaveService = $autosaveService;
}

public function getConfig(): array
{
$isEnabled = $this->userSettingService->getUserSetting('autosave')->value === AutosaveSetting::ENABLED_OPTION;
$interval = (int)$this->userSettingService->getUserSetting('autosave_interval')->value * 1000;

return [
'enabled' => $isEnabled,
'interval' => $interval,
'enabled' => $this->autosaveService->isEnabled(),
'interval' => $this->autosaveService->getInterval(),
];
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/UserSetting/Autosave.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

class Autosave implements ValueDefinitionInterface, FormMapperInterface
{
public const IDENTIFIER = 'autosave';

public const ENABLED_OPTION = 'enabled';
public const DISABLED_OPTION = 'disabled';

Expand Down
2 changes: 2 additions & 0 deletions src/lib/UserSetting/AutosaveInterval.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

class AutosaveInterval implements ValueDefinitionInterface, FormMapperInterface
{
public const IDENTIFIER = 'autosave_interval';

/** @var \Symfony\Contracts\Translation\TranslatorInterface */
private $translator;

Expand Down
64 changes: 64 additions & 0 deletions tests/lib/Autosave/AutosaveServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

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

namespace Ibexa\Tests\AdminUi\Autosave;

use Ibexa\AdminUi\Autosave\AutosaveService;
use Ibexa\AdminUi\UserSetting\Autosave;
use Ibexa\AdminUi\UserSetting\AutosaveInterval;
use Ibexa\User\UserSetting\UserSetting;
use Ibexa\User\UserSetting\UserSettingService;
use PHPUnit\Framework\TestCase;

final class AutosaveServiceTest extends TestCase
{
/** @var \Ibexa\User\UserSetting\UserSettingService&\PHPUnit\Framework\MockObject\MockObject */
private UserSettingService $userSettingService;

private AutosaveService $autosaveService;

protected function setUp(): void
{
$this->userSettingService = $this->createMock(UserSettingService::class);
$this->autosaveService = new AutosaveService($this->userSettingService);
}

public function testIsEnabled(): void
{
$this->userSettingService
->method('getUserSetting')
->with(Autosave::IDENTIFIER)
->willReturn($this->createUserSettingWithValue(Autosave::ENABLED_OPTION));

self::assertTrue($this->autosaveService->isEnabled());
}

public function testGetInterval(): void
{
$this->userSettingService
->method('getUserSetting')
->with(AutosaveInterval::IDENTIFIER)
->willReturn($this->createUserSettingWithValue('30'));

self::assertEquals(30000, $this->autosaveService->getInterval());
}

public function testIsInProgress(): void
{
self::assertFalse($this->autosaveService->isInProgress());
$this->autosaveService->setInProgress(true);
self::assertTrue($this->autosaveService->isInProgress());
}

private function createUserSettingWithValue(string $value): UserSetting
{
return new UserSetting([
'value' => $value,
]);
}
}
Loading

0 comments on commit c0814c5

Please sign in to comment.