Skip to content

Commit

Permalink
Decouple and deprecate NotificationBundle
Browse files Browse the repository at this point in the history
  • Loading branch information
eerison committed Jun 8, 2022
1 parent f1bbad0 commit be6d02f
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 30 deletions.
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@
}
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"phpstan/extension-installer": true
}
},
"extra": {
"branch-alias": {
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ It's auto-generated by sonata-project/dev-kit package.
<php>
<ini name="precision" value="8" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[self]=0" />
<server name="KERNEL_CLASS" value="Sonata\PageBundle\Tests\App\AppKernel" />
</php>
</phpunit>
3 changes: 3 additions & 0 deletions src/Command/BaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
use Sonata\NotificationBundle\Backend\BackendInterface;
use Sonata\PageBundle\CmsManager\CmsPageManager;
use Sonata\PageBundle\CmsManager\DecoratorStrategyInterface;
use Sonata\PageBundle\Entity\SnapshotManager;
use Sonata\PageBundle\Listener\ExceptionListener;
use Sonata\PageBundle\Model\PageManagerInterface;
use Sonata\PageBundle\Model\Site;
use Sonata\PageBundle\Model\SiteManagerInterface;
use Sonata\PageBundle\Model\SnapshotManagerInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
Expand Down Expand Up @@ -91,6 +93,7 @@ public function getErrorListener()
* @param string $mode
*
* @return BackendInterface
* @TODO after decouple the code of this method, deprecate it.
*/
public function getNotificationBackend($mode)
{
Expand Down
45 changes: 18 additions & 27 deletions src/Command/CreateSnapshotsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Sonata\PageBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -27,52 +28,42 @@
*/
class CreateSnapshotsCommand extends BaseCommand
{
protected static $defaultName = 'sonata:page:create-snapshots';

public function configure()
{
$this->setName('sonata:page:create-snapshots');
$this->setDescription('Create a snapshots of all pages available');
$this->addOption('site', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Site id', null);
$this->addOption('site', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Site id', ['all']);
$this->addOption('base-console', null, InputOption::VALUE_OPTIONAL, 'Base symfony console command', 'php app/console');

$this->addOption('mode', null, InputOption::VALUE_OPTIONAL, 'Run the command asynchronously', 'sync');
}

public function execute(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('site')) {
$output->writeln('Please provide an <info>--site=SITE_ID</info> option or the <info>--site=all</info> directive');
$output->writeln('');

$output->writeln(sprintf(' % 5s - % -30s - %s', 'ID', 'Name', 'Url'));

foreach ($this->getSiteManager()->findBy([]) as $site) {
$output->writeln(sprintf(' % 5s - % -30s - %s', $site->getId(), $site->getName(), $site->getUrl()));
}
$sites = $this->getSites($input);

return 0;
}
foreach ($sites as $site) {
// NEXT_MAJOR: Remove this "async" condition block.
if ('async' === $input->getOption('mode')) {
@trigger_error(sprintf(
'The async mode is deprecated since sonata-project/page-bundle 3.27.0 and will be removed in 4.0'
), \E_USER_DEPRECATED);

foreach ($this->getSites($input) as $site) {
if ('all' !== $input->getOption('site')) {
if ('async' === $input->getOption('mode')) {
$output->write(sprintf('<info>%s</info> - Publish a notification command ...', $site->getName()));
} else {
$output->write(sprintf('<info>%s</info> - Generating snapshots ...', $site->getName()));
}
$output->write(sprintf('<info>%s</info> - Publish a notification command ...', $site->getName()));

$this->getNotificationBackend($input->getOption('mode'))->createAndPublish('sonata.page.create_snapshots', [
'siteId' => $site->getId(),
'mode' => $input->getOption('mode'),
]);

$output->writeln(' done!');
} else {
$p = new Process(sprintf('%s sonata:page:create-snapshots --env=%s --site=%s --mode=%s %s ', $input->getOption('base-console'), $input->getOption('env'), $site->getId(), $input->getOption('mode'), $input->getOption('no-debug') ? '--no-debug' : ''));
$p->setTimeout(0);
$p->run(static function ($type, $data) use ($output) {
$output->write($data, OutputInterface::OUTPUT_RAW);
});
continue;
}

$output->write(sprintf('<info>%s</info> - Generating snapshots ...', $site->getName()));
//TODO need to call CreateSnapshotsService!!!!

$output->writeln(' done!');
}

$output->writeln('<info>done!</info>');
Expand Down
1 change: 1 addition & 0 deletions src/Consumer/CreateSnapshotConsumer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* @final since sonata-project/page-bundle 3.26
* @deprecated it'll be removed on version 4.x
*/
class CreateSnapshotConsumer implements ConsumerInterface
{
Expand Down
16 changes: 16 additions & 0 deletions src/Service/CreateSnapshotsFromPageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Sonata\PageBundle\Service;

use Sonata\PageBundle\Model\PageInterface;
use Sonata\PageBundle\Model\SiteInterface;
use Sonata\PageBundle\Model\SnapshotInterface;

interface CreateSnapshotsFromPageInterface
{
/**
* @param iterable<PageInterface> $pages
* @return iterable<SnapshotInterface>
*/
public function createFromPages(iterable $pages): iterable;
}
75 changes: 75 additions & 0 deletions src/Service/CreateSnapshotsService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\PageBundle\Service;

use Sonata\PageBundle\Model\PageInterface;
use Sonata\PageBundle\Model\PageManagerInterface;
use Sonata\PageBundle\Model\SnapshotInterface;
use Sonata\PageBundle\Model\SnapshotManagerInterface;
use Sonata\PageBundle\Model\TransformerInterface;

final class CreateSnapshotsService implements CreateSnapshotsFromPageInterface
{
private $snapshotManager;

private $pageManager;

private $transformer;

public function __construct(
SnapshotManagerInterface $snapshotManager,
PageManagerInterface $pageManager,
TransformerInterface $transformer
) {
$this->snapshotManager = $snapshotManager;
$this->pageManager = $pageManager;
$this->transformer = $transformer;
}

/**
* @param iterable<PageInterface> $pages
*
* @return iterable<SnapshotInterface>
*/
public function createFromPages(iterable $pages): iterable
{
$entityManager = $this->snapshotManager->getEntityManager();

// start a transaction
$entityManager->beginTransaction();

foreach ($pages as $page) {
yield $this->createByPage($page);
}

// commit the changes
$entityManager->commit();
}

private function createByPage(PageInterface $page): SnapshotInterface
{
// creating snapshot
$snapshot = $this->transformer->create($page);

// update the page status
$page->setEdited(false);
$this->pageManager->save($page);

// save the snapshot
$this->snapshotManager->save($snapshot);
$this->snapshotManager->enableSnapshots([$snapshot]);

return $snapshot;
}
}
127 changes: 127 additions & 0 deletions tests/Command/CreateSnapshotsCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\PageBundle\Tests\Command;

use Sonata\NotificationBundle\Backend\BackendInterface;
use Sonata\PageBundle\Command\CreateSnapshotsCommand;
use Sonata\PageBundle\Model\Site;
use Sonata\PageBundle\Model\SiteInterface;
use Sonata\PageBundle\Model\SiteManagerInterface;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tester\CommandTester;

class CreateSnapshotsCommandTest extends KernelTestCase
{
private $siteManagerMock;
private $application;

protected function setUp(): void
{
//Mocks
$siteMock = $this->createMock(SiteInterface::class);
$siteMock
->method('getId')
->willReturn(1);
$siteMock
->method('getName')
->willReturn('foo');
$siteMock
->method('getUrl')
->willReturn('https://bar.baz');

$siteManagerMock = $this->createMock(SiteManagerInterface::class);
$siteManagerMock
->method('findBy')
->willReturn([$siteMock]);

// Setup SymfonyKernel
$kernel = self::bootKernel();
$this->application = new Application($kernel);
$this->siteManagerMock = $siteManagerMock;
}

/**
* @test
* @testdox It's creating a snapshot using "async" mode.
* @TODO REMOVE NEXT_MAJOR
*/
public function createOneSnapshotAsync(): void
{
//Mock
$backendMock = $this->createMock(BackendInterface::class);
$backendMock
->expects(static::once())
->method('createAndPublish');

//Set mock services
self::$container->set('sonata.page.manager.site', $this->siteManagerMock);
self::$container->set('sonata.notification.backend', $backendMock);

//Command
$command = $this->application->find('sonata:page:create-snapshots');
$commandTester = new CommandTester($command);

$commandTester->execute([
'command' => $command->getName(),
'--site' => [1],
'--mode' => 'async',
]);

$output = $commandTester->getDisplay();

static::assertStringContainsString('done!', $output);
}

/**
* @test
* @testdox it's using notificationBundle when mode option is equals "async"
* @testWith ["sync", 0]
* ["async", 1]
*/
public function callNotificationBackend(string $mode, int $notificationWillBeExecuted): void
{
// Mocks
$commandMock = $this->createPartialMock(CreateSnapshotsCommand::class, [
'getNotificationBackend',
'getSites',
]);
$commandMock
->expects(static::once())
->method('getSites')
->willReturn([$this->createMock(Site::class)]);
$commandMock
->expects(static::exactly($notificationWillBeExecuted))
->method('getNotificationBackend')
->willReturn($this->createMock(BackendInterface::class));

$inputMock = $this->createMock(InputInterface::class);
$inputMock
->method('getOption')
->willReturn($mode);

$outputMock = $this->createMock(OutputInterface::class);
$outputMock
->expects(static::exactly(2))
->method('writeln');

// Run code
$output = $commandMock->execute($inputMock, $outputMock);

// Assert
static::assertSame(0, $output);
}
}
4 changes: 2 additions & 2 deletions tests/Model/PageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public function testSlugify(): void
static::assertSame(Page::slugify('S§!@@#$#$alut'), 's-alut');
static::assertSame(Page::slugify('Symfony2'), 'symfony2');
static::assertSame(Page::slugify('test'), 'test');
static::assertSame(Page::slugify('c\'est bientôt l\'été'), 'c-est-bientot-l-ete');
static::assertSame(Page::slugify(urldecode('%2Fc\'est+bientôt+l\'été')), 'c-est-bientot-l-ete');
static::assertSame(Page::slugify('c\'est bientôt l\'été'), 'c-est-bientt-l-t');
static::assertSame(Page::slugify(urldecode('%2Fc\'est+bientôt+l\'été')), 'c-est-bientt-l-t');
}

public function testHeader(): void
Expand Down

0 comments on commit be6d02f

Please sign in to comment.