Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implemented page-tree mover
Browse files Browse the repository at this point in the history
wachterjohannes committed Jun 26, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 47dec00 commit fa5f580
Showing 7 changed files with 314 additions and 11 deletions.
58 changes: 58 additions & 0 deletions Command/MovePageTreeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ArticleBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Move articles from given parent-page to another.
*/
class MovePageTreeCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
public function configure()
{
$this->setName('sulu:article:page-tree:move')
->addArgument('source-segment', InputArgument::REQUIRED)
->addArgument('destination-segment', InputArgument::REQUIRED)
->addArgument('webspace-key', InputArgument::REQUIRED)
->addArgument('locale', InputArgument::REQUIRED);
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$source = $input->getArgument('source-segment');
$destination = $input->getArgument('destination-segment');
$webspaceKey = $input->getArgument('webspace-key');
$locale = $input->getArgument('locale');

$mover = $this->getContainer()->get('sulu_article.page_tree_route.mover');
$strategyPool = $this->getContainer()->get('sulu.content.resource_locator.strategy_pool');
$documentManager = $this->getContainer()->get('sulu_document_manager.document_manager');
$strategy = $strategyPool->getStrategyByWebspaceKey($webspaceKey);

$destinationUuid = $strategy->loadByResourceLocator($destination, $webspaceKey, $locale);
$document = $documentManager->find($destinationUuid, $locale);

$mover->move($source, $document);

$documentManager->flush();
}
}
1 change: 1 addition & 0 deletions DependencyInjection/SuluArticleExtension.php
Original file line number Diff line number Diff line change
@@ -163,6 +163,7 @@ public function load(array $configs, ContainerBuilder $container)
'sulu_article.page_tree_route.updater.' . $config['content_types']['page_tree_route']['page_route_cascade']
);

$loader->load('page_tree_move.xml');
if ($config['content_types']['page_tree_route']['page_route_cascade'] !== 'off') {
$loader->load('page_tree_update.xml');
}
26 changes: 26 additions & 0 deletions PageTree/PageTreeMoverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ArticleBundle\PageTree;

use Sulu\Bundle\ContentBundle\Document\BasePageDocument;

/**
* Interface for page-tree-mover.
*/
interface PageTreeMoverInterface
{
/**
* @param string $source
* @param BasePageDocument $destination
*/
public function move($source, BasePageDocument $destination);
}
36 changes: 26 additions & 10 deletions PageTree/PageTreeUpdater.php → PageTree/PageTreeRepository.php
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
/**
* Update the route of articles synchronously.
*/
class PageTreeUpdater implements PageTreeUpdaterInterface
class PageTreeRepository implements PageTreeUpdaterInterface, PageTreeMoverInterface
{
const ROUTE_PROPERTY = 'routePath';
const TAG_NAME = 'sulu_article.article_route';
@@ -74,21 +74,33 @@ public function __construct(
*/
public function update(BasePageDocument $document)
{
$articles = $this->findLinkedArticles($document->getUuid(), $document->getLocale());
$articles = $this->findLinkedArticles('page', $document->getUuid(), $document->getLocale());
foreach ($articles as $article) {
$this->updateArticle($article, $document->getResourceSegment(), $document->getLocale());
$this->updateArticle($article, $document);
}
}

/**
* {@inheritdoc}
*/
public function move($source, BasePageDocument $document)
{
$articles = $this->findLinkedArticles('page-path', $source, $document->getLocale());
foreach ($articles as $article) {
$this->updateArticle($article, $document);
}
}

/**
* Find articles linked to the given page.
*
* @param string $uuid
* @param string $field
* @param string $value
* @param string $locale
*
* @return ArticleInterface[]
*/
private function findLinkedArticles($uuid, $locale)
private function findLinkedArticles($field, $value, $locale)
{
$where = [];
foreach ($this->metadataFactory->getStructures('article') as $metadata) {
@@ -98,11 +110,12 @@ private function findLinkedArticles($uuid, $locale)
}

$where[] = sprintf(
'([%s] = "%s" AND [%s-page] = "%s")',
'([%s] = "%s" AND [%s-%s] = "%s")',
$this->propertyEncoder->localizedSystemName('template', $locale),
$metadata->getName(),
$this->propertyEncoder->localizedContentName($property->getName(), $locale),
$uuid
$field,
$value
);
}

@@ -125,15 +138,18 @@ private function findLinkedArticles($uuid, $locale)
* Update route of given article.
*
* @param ArticleDocument $article
* @param string $resourceSegment
* @param string $locale
* @param BasePageDocument $document
*/
private function updateArticle(ArticleDocument $article, $resourceSegment, $locale)
private function updateArticle(ArticleDocument $article, BasePageDocument $document)
{
$locale = $document->getLocale();
$resourceSegment = $document->getResourceSegment();

$property = $this->getRoutePathPropertyNameByStructureType($article->getStructureType());
$propertyName = $this->propertyEncoder->localizedContentName($property->getName(), $locale);

$node = $this->documentInspector->getNode($article);
$node->setProperty($propertyName . '-page', $document->getUuid());
$node->setProperty($propertyName . '-page-path', $resourceSegment);

$suffix = $node->getPropertyValueWithDefault($propertyName . '-suffix', null);
14 changes: 14 additions & 0 deletions Resources/config/page_tree_move.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="sulu_article.page_tree_route.mover"
class="Sulu\Bundle\ArticleBundle\PageTree\PageTreeRepository">
<argument type="service" id="sulu_document_manager.document_manager"/>
<argument type="service" id="sulu_content.structure.factory"/>
<argument type="service" id="sulu_document_manager.property_encoder"/>
<argument type="service" id="sulu_document_manager.document_inspector"/>
</service>
</services>
</container>
2 changes: 1 addition & 1 deletion Resources/config/page_tree_update.xml
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
</service>

<service id="sulu_article.page_tree_route.updater.request"
class="Sulu\Bundle\ArticleBundle\PageTree\PageTreeUpdater">
class="Sulu\Bundle\ArticleBundle\PageTree\PageTreeRepository">
<argument type="service" id="sulu_document_manager.document_manager"/>
<argument type="service" id="sulu_content.structure.factory"/>
<argument type="service" id="sulu_document_manager.property_encoder"/>
188 changes: 188 additions & 0 deletions Tests/Functional/PageTree/PageTreeRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Functional\PageTree;

use Ramsey\Uuid\Uuid;
use Sulu\Bundle\ArticleBundle\PageTree\PageTreeRepository;
use Sulu\Bundle\ContentBundle\Document\PageDocument;
use Sulu\Bundle\TestBundle\Testing\SuluTestCase;
use Sulu\Component\DocumentManager\DocumentManagerInterface;

class PageTreeRepositoryTest extends SuluTestCase
{
/**
* @var DocumentManagerInterface
*/
private $documentManager;

/**
* @var PageTreeRepository
*/
private $pageTreeRepository;

/**
* @var string
*/
private $locale = 'en';

/**
* {@inheritdoc}
*/
public function setUp()
{
parent::setUp();

$this->initPhpcr();
$this->purgeDatabase();

$this->documentManager = $this->getContainer()->get('sulu_document_manager.document_manager');
$this->pageTreeRepository = new PageTreeRepository(
$this->documentManager,
$this->getContainer()->get('sulu_content.structure.factory'),
$this->getContainer()->get('sulu_document_manager.property_encoder'),
$this->getContainer()->get('sulu_document_manager.document_inspector')
);
}

public function testUpdate()
{
$pages = [
$this->createPage('Test 1', '/test-1'),
$this->createPage('Test 2', '/test-2'),
];

$articles = [
$this->createArticle($this->getPathData($pages[0], 'article-1')),
$this->createArticle($this->getPathData($pages[0], 'article-2')),
$this->createArticle($this->getPathData($pages[1], 'article-3')),
];
$this->documentManager->flush();

$pages[0]->setResourceSegment('/test-3');
$this->documentManager->persist($pages[0], $this->locale);
$this->documentManager->publish($pages[0], $this->locale);
$this->documentManager->flush();
$this->documentManager->clear();

$this->pageTreeRepository->update($pages[0]);
$this->documentManager->flush();
$this->documentManager->clear();

$result = [
$this->documentManager->find($articles[0]['id'], $this->locale),
$this->documentManager->find($articles[1]['id'], $this->locale),
$this->documentManager->find($articles[2]['id'], $this->locale),
];

$this->assertEquals('/test-3/article-1', $result[0]->getRoutePath());
$this->assertEquals('/test-3/article-2', $result[1]->getRoutePath());
$this->assertEquals('/test-2/article-3', $result[2]->getRoutePath());
}

public function testMove()
{
$pages = [
$this->createPage('Test 1', '/test-1'),
$this->createPage('Test 2', '/test-2'),
$this->createPage('Test 3', '/test-3'),
];

$articles = [
$this->createArticle($this->getPathData($pages[0], 'article-1')),
$this->createArticle($this->getPathData($pages[0], 'article-2')),
$this->createArticle($this->getPathData($pages[1], 'article-3')),
];

$this->documentManager->flush();
$this->documentManager->clear();

$this->pageTreeRepository->move('/test-1', $pages[2]);
$this->documentManager->flush();
$this->documentManager->clear();

$result = [
$this->documentManager->find($articles[0]['id'], $this->locale),
$this->documentManager->find($articles[1]['id'], $this->locale),
$this->documentManager->find($articles[2]['id'], $this->locale),
];

$this->assertEquals('/test-3/article-1', $result[0]->getRoutePath());
$this->assertEquals('/test-3/article-2', $result[1]->getRoutePath());
$this->assertEquals('/test-2/article-3', $result[2]->getRoutePath());
}

private function getPathData(PageDocument $page, $suffix)
{
return [
'page' => [
'uuid' => $page->getUuid(),
'path' => $page->getResourceSegment(),
],
'suffix' => $suffix,
'path' => $page->getResourceSegment() . '/' . $suffix,
];
}

/**
* Create a new article.
*
* @param array $routePathData
* @param string $title
*
* @return array
*/
private function createArticle(array $routePathData, $title = 'Test Article')
{
$client = $this->createAuthenticatedClient();
$client->request(
'POST',
'/api/articles?locale=' . $this->locale . '&action=publish',
[
'title' => $title,
'template' => 'page_tree_route',
'routePath' => $routePathData,
'authored' => '2016-01-01',
]
);

return json_decode($client->getResponse()->getContent(), true);
}

/**
* Create a new page.
*
* @param string $title
* @param string $resourceSegment
*
* @return PageDocument
*/
private function createPage($title = 'Test Page', $resourceSegment = '/test-page')
{
$sessionManager = $this->getContainer()->get('sulu.phpcr.session');
$page = $this->documentManager->create('page');

$uuidReflection = new \ReflectionProperty(PageDocument::class, 'uuid');
$uuidReflection->setAccessible(true);
$uuidReflection->setValue($page, Uuid::uuid4()->toString());

$page->setTitle($title);
$page->setStructureType('default');
$page->setParent($this->documentManager->find($sessionManager->getContentPath('sulu_io')));
$page->setResourceSegment($resourceSegment);

$this->documentManager->persist($page, $this->locale);
$this->documentManager->publish($page, $this->locale);
$this->documentManager->flush();

return $page;
}
}

0 comments on commit fa5f580

Please sign in to comment.