Skip to content

Commit

Permalink
Implemented page document and API (sulu#114)
Browse files Browse the repository at this point in the history
* implemented basic page document

* added index pages to article
  • Loading branch information
wachterjohannes committed Apr 24, 2017
1 parent c61b182 commit 829848c
Show file tree
Hide file tree
Showing 31 changed files with 1,597 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Content/ArticleSelectionContentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Sulu\Component\Content\SimpleContentType;

/**
* This class provides article selection.
* Provides article_selection content-type.
*/
class ArticleSelectionContentType extends SimpleContentType
{
Expand Down
239 changes: 239 additions & 0 deletions Controller/ArticlePageController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
<?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\Controller;

use FOS\RestBundle\Routing\ClassResourceInterface;
use JMS\Serializer\SerializationContext;
use Sulu\Bundle\ArticleBundle\Admin\ArticleAdmin;
use Sulu\Bundle\ArticleBundle\Document\ArticlePageDocument;
use Sulu\Bundle\ArticleBundle\Document\Form\ArticlePageDocumentType;
use Sulu\Bundle\ArticleBundle\Exception\ParameterNotAllowedException;
use Sulu\Component\Content\Form\Exception\InvalidFormException;
use Sulu\Component\Content\Mapper\ContentMapperInterface;
use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Sulu\Component\Rest\Exception\MissingParameterException;
use Sulu\Component\Rest\RequestParametersTrait;
use Sulu\Component\Rest\RestController;
use Sulu\Component\Security\SecuredControllerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Provides API for article-pages.
*/
class ArticlePageController extends RestController implements ClassResourceInterface, SecuredControllerInterface
{
const DOCUMENT_TYPE = 'article_page';

use RequestParametersTrait;

/**
* Returns single article-page.
*
* @param string $articleUuid
* @param string $uuid
* @param Request $request
*
* @return Response
*/
public function getAction($articleUuid, $uuid, Request $request)
{
$locale = $this->getRequestParameter($request, 'locale', true);
$document = $this->getDocumentManager()->find(
$uuid,
$locale,
[
'load_ghost_content' => true,
'load_shadow_content' => false,
]
);

return $this->handleView(
$this->view($document)->setSerializationContext(
SerializationContext::create()->setSerializeNull(true)->setGroups(['defaultPage'])
)
);
}

/**
* Create article-page.
*
* @param string $articleUuid
* @param Request $request
*
* @return Response
*/
public function postAction($articleUuid, Request $request)
{
$action = $request->get('action');
$document = $this->getDocumentManager()->create(self::DOCUMENT_TYPE);
$locale = $this->getRequestParameter($request, 'locale', true);
$data = $request->request->all();

$this->persistDocument($data, $document, $locale, $articleUuid);
$this->handleActionParameter($action, $document, $locale);
$this->getDocumentManager()->flush();

return $this->handleView(
$this->view($document)->setSerializationContext(
SerializationContext::create()->setSerializeNull(true)->setGroups(['defaultPage'])
)
);
}

/**
* Update article-page.
*
* @param string $articleUuid
* @param string $uuid
* @param Request $request
*
* @return Response
*/
public function putAction($articleUuid, $uuid, Request $request)
{
$locale = $this->getRequestParameter($request, 'locale', true);
$action = $request->get('action');
$data = $request->request->all();

$document = $this->getDocumentManager()->find(
$uuid,
$locale,
[
'load_ghost_content' => false,
'load_shadow_content' => false,
]
);

$this->get('sulu_hash.request_hash_checker')->checkHash($request, $document, $document->getUuid());

$this->persistDocument($data, $document, $locale, $articleUuid);
$this->handleActionParameter($action, $document, $locale);
$this->getDocumentManager()->flush();

return $this->handleView(
$this->view($document)->setSerializationContext(
SerializationContext::create()->setSerializeNull(true)->setGroups(['defaultPage'])
)
);
}

/**
* Delete article-page.
*
* @param string $articleUuid
* @param string $uuid
*
* @return Response
*/
public function deleteAction($articleUuid, $uuid)
{
$documentManager = $this->getDocumentManager();
$document = $documentManager->find($uuid);
$documentManager->remove($document);
$documentManager->flush();

return $this->handleView($this->view(null));
}

/**
* {@inheritdoc}
*/
public function getSecurityContext()
{
return ArticleAdmin::SECURITY_CONTEXT;
}

/**
* Persists the document using the given information.
*
* @param array $data
* @param object $document
* @param string $locale
* @param string $articleUuid
*
* @throws InvalidFormException
* @throws MissingParameterException
* @throws ParameterNotAllowedException
*/
private function persistDocument($data, $document, $locale, $articleUuid)
{
if (array_key_exists('title', $data)) {
throw new ParameterNotAllowedException('title', ArticlePageDocument::class);
}
if (array_key_exists('template', $data)) {
throw new ParameterNotAllowedException('template', ArticlePageDocument::class);
}

$article = $this->getDocumentManager()->find($articleUuid, $locale);
$data['template'] = $article->getStructureType();

$form = $this->createForm(
ArticlePageDocumentType::class,
$document,
[
// disable csrf protection, since we can't produce a token, because the form is cached on the client
'csrf_protection' => false,
]
);
$form->submit($data, false);

$document->setParent($article);

if (!$form->isValid()) {
throw new InvalidFormException($form);
}

$this->getDocumentManager()->persist(
$document,
$locale,
[
'user' => $this->getUser()->getId(),
'clear_missing_content' => false,
]
);
}

/**
* Returns document-manager.
*
* @return DocumentManagerInterface
*/
protected function getDocumentManager()
{
return $this->get('sulu_document_manager.document_manager');
}

/**
* @return ContentMapperInterface
*/
protected function getMapper()
{
return $this->get('sulu.content.mapper');
}

/**
* Delegates actions by given actionParameter, which can be retrieved from the request.
*
* @param string $actionParameter
* @param object $document
* @param string $locale
*/
private function handleActionParameter($actionParameter, $document, $locale)
{
switch ($actionParameter) {
case 'publish':
$this->getDocumentManager()->publish($document, $locale);
break;
}
}
}
19 changes: 19 additions & 0 deletions DependencyInjection/SuluArticleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
namespace Sulu\Bundle\ArticleBundle\DependencyInjection;

use Sulu\Bundle\ArticleBundle\Document\ArticleDocument;
use Sulu\Bundle\ArticleBundle\Document\ArticlePageDocument;
use Sulu\Bundle\ArticleBundle\Document\Structure\ArticleBridge;
use Sulu\Bundle\ArticleBundle\Document\Structure\ArticlePageBridge;
use Sulu\Bundle\ArticleBundle\Exception\ParameterNotAllowedException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
Expand All @@ -37,6 +40,7 @@ public function prepend(ContainerBuilder $container)
'structure' => [
'type_map' => [
'article' => ArticleBridge::class,
'article_page' => ArticlePageBridge::class,
],
],
],
Expand Down Expand Up @@ -67,6 +71,7 @@ public function prepend(ContainerBuilder $container)
'search' => [
'mapping' => [
ArticleDocument::class => ['index' => 'article'],
ArticlePageDocument::class => ['index' => 'article_page'],
],
],
]
Expand All @@ -79,13 +84,27 @@ public function prepend(ContainerBuilder $container)
[
'mapping' => [
'article' => ['class' => ArticleDocument::class, 'phpcr_type' => 'sulu:article'],
'article_page' => ['class' => ArticlePageDocument::class, 'phpcr_type' => 'sulu:articlepage'],
],
'path_segments' => [
'articles' => 'articles',
],
]
);
}

if ($container->hasExtension('fos_rest')) {
$container->prependExtensionConfig(
'fos_rest',
[
'exception' => [
'codes' => [
ParameterNotAllowedException::class => 400,
],
],
]
);
}
}

/**
Expand Down
19 changes: 18 additions & 1 deletion Document/ArticleDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
use Sulu\Component\Content\Document\Extension\ExtensionContainer;
use Sulu\Component\Content\Document\Structure\Structure;
use Sulu\Component\Content\Document\Structure\StructureInterface;
use Sulu\Component\DocumentManager\Behavior\Mapping\ChildrenBehavior;
use Sulu\Component\DocumentManager\Behavior\Mapping\LocalizedTitleBehavior;
use Sulu\Component\DocumentManager\Behavior\Mapping\NodeNameBehavior;
use Sulu\Component\DocumentManager\Behavior\Mapping\PathBehavior;
use Sulu\Component\DocumentManager\Behavior\Mapping\UuidBehavior;
use Sulu\Component\DocumentManager\Behavior\Path\AutoNameBehavior;
use Sulu\Component\DocumentManager\Behavior\VersionBehavior;
use Sulu\Component\DocumentManager\Collection\ChildrenCollection;
use Sulu\Component\DocumentManager\Version;

/**
Expand All @@ -48,7 +50,8 @@ class ArticleDocument implements
ExtensionBehavior,
WorkflowStageBehavior,
VersionBehavior,
AuthorBehavior
AuthorBehavior,
ChildrenBehavior
{
/**
* @var string
Expand Down Expand Up @@ -163,10 +166,16 @@ class ArticleDocument implements
*/
protected $versions = [];

/**
* @var ChildrenCollection
*/
protected $children;

public function __construct()
{
$this->structure = new Structure();
$this->extensions = new ExtensionContainer();
$this->children = new \ArrayIterator();
}

/**
Expand Down Expand Up @@ -470,4 +479,12 @@ public function setVersions($versions)
{
$this->versions = $versions;
}

/**
* {@inheritdoc}
*/
public function getChildren()
{
return $this->children;
}
}
Loading

0 comments on commit 829848c

Please sign in to comment.