Skip to content

Commit

Permalink
Merge tag '1.5.3' into develop
Browse files Browse the repository at this point in the history
1.5.3
  • Loading branch information
ambroisemaupate committed Aug 27, 2020
2 parents cd095f5 + 44720c6 commit 6bfdefe
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 4 deletions.
4 changes: 2 additions & 2 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@
# built documents.
#
# The short X.Y version.
version = '1.5.2'
version = '1.5.3'
# The full version, including alpha/beta/rc tags.
release = '1.5.2'
release = '1.5.3'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
240 changes: 238 additions & 2 deletions developer/serialization/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,256 @@
Serialization
=============

*Roadiz* CMS uses ``jms/serializer`` to perform JSON serialization over any objects, especially *Doctrine* entities.

.. code-block:: php
$response = new JsonResponse(
$this->get('serializer')->serialize(
$this->nodeSource,
$this->getNodeSource(),
'json',
SerializationContext::create()->setGroups(['nodes_sources', 'id'])
SerializationContext::create()->setGroups(['nodes_sources', 'urls', 'walker', 'children'])
),
Response::HTTP_OK,
[],
true
);
Customize existing serialized entities
--------------------------------------

Serialize nodes-sources URL
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Your can add data in your serialized data from your themes using ``EventSubscriberInterface`` listening
on ``serializer.post_serialize`` event. For example, you may want to get your *reachable* ``NodesSources`` URL in their
JSON response. Here is how to do:

.. code-block:: php
<?php
declare(strict_types=1);
namespace Themes\MyAwesomeTheme\Serialization;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\Metadata\StaticPropertyMetadata;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use Pimple\Container;
use RZ\Roadiz\Core\ContainerAwareInterface;
use RZ\Roadiz\Core\ContainerAwareTrait;
use RZ\Roadiz\Core\Entities\NodesSources;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
final class NodesSourcesUriSubscriber implements EventSubscriberInterface, ContainerAwareInterface
{
use ContainerAwareTrait;
/**
* DocumentUriSubscriber constructor.
*
* @param Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [[
'event' => 'serializer.post_serialize',
'method' => 'onPostSerialize',
]];
}
/**
* @param ObjectEvent $event
* @return void
*/
public function onPostSerialize(ObjectEvent $event)
{
$nodeSource = $event->getObject();
$visitor = $event->getVisitor();
$context = $event->getContext();
if ($context->hasAttribute('groups') &&
in_array('urls', $context->getAttribute('groups'))) {
/** @var UrlGeneratorInterface $urlGenerator */
$urlGenerator = $this->get('urlGenerator');
if ($nodeSource instanceof NodesSources &&
null !== $nodeSource->getNode() &&
null !== $nodeSource->getNode()->getNodeType() &&
$visitor instanceof SerializationVisitorInterface &&
$nodeSource->getNode()->isPublished() &&
$nodeSource->getNode()->getNodeType()->isReachable()
) {
$visitor->visitProperty(
new StaticPropertyMetadata('string', 'url', []),
$urlGenerator->generate(
RouteObjectInterface::OBJECT_BASED_ROUTE_NAME,
[
RouteObjectInterface::ROUTE_OBJECT => $nodeSource
],
UrlGeneratorInterface::ABSOLUTE_URL
)
);
}
}
}
}
Then register your ``NodesSourcesUriSubscriber`` in your theme services:

.. code-block:: php
$container->extend('serializer.subscribers', function (array $subscribers, Container $c) {
$subscribers[] = new NodesSourcesUriSubscriber($c);
return $subscribers;
});
Then your JSON response will contain the additional key ``url`` :

.. code-block:: json
{
"url": "http://myawesomesite.test/about-us"
}
You can add every piece of data in your serialized responses, even node children by injecting a *tree-walker*.

Serialize documents URL
^^^^^^^^^^^^^^^^^^^^^^^

Same way for injecting your document URL (i.e. image path, or iframe source), we need to call Roadiz document URL
generator for any Document serialized into our JSON response:

.. code-block:: php
<?php
declare(strict_types=1);
namespace Themes\MyAwesomeTheme\Serialization;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\Metadata\StaticPropertyMetadata;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use Pimple\Container;
use RZ\Roadiz\Core\ContainerAwareInterface;
use RZ\Roadiz\Core\ContainerAwareTrait;
use RZ\Roadiz\Core\Entities\Document;
use RZ\Roadiz\Core\Exceptions\InvalidEmbedId;
use RZ\Roadiz\Utils\MediaFinders\EmbedFinderFactory;
use RZ\Roadiz\Utils\UrlGenerators\DocumentUrlGenerator;
final class DocumentUriSubscriber implements EventSubscriberInterface, ContainerAwareInterface
{
use ContainerAwareTrait;
/**
* DocumentUriSubscriber constructor.
*
* @param Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [[
'event' => 'serializer.post_serialize',
'method' => 'onPostSerialize',
'class' => Document::class,
]];
}
/**
* @param ObjectEvent $event
* @return void
*/
public function onPostSerialize(ObjectEvent $event)
{
$document = $event->getObject();
$visitor = $event->getVisitor();
$context = $event->getContext();
if (null !== $this->container &&
$context->hasAttribute('groups') &&
in_array('urls', $context->getAttribute('groups'))) {
/** @var DocumentUrlGenerator $urlGenerator */
$urlGenerator = $this->get('document.url_generator')->setDocument($document);
if ($document instanceof Document &&
$visitor instanceof SerializationVisitorInterface) {
$urls = [];
if ($document->isEmbed() && $document->getEmbedId()) {
try {
/** @var EmbedFinderFactory $embedFinderFactory */
$embedFinderFactory = $this->get(EmbedFinderFactory::class);
if (null !== $document->getEmbedPlatform() &&
$embedFinderFactory->supports($document->getEmbedPlatform())) {
$embedFinder = $embedFinderFactory->createForPlatform(
$document->getEmbedPlatform(),
$document->getEmbedId()
);
if (null !== $embedFinder) {
$urls['embed'] = $embedFinder->getSource();
}
}
} catch (InvalidEmbedId $embedException) {
}
}
if ($document->isProcessable()) {
$visitor->visitProperty(
new StaticPropertyMetadata('array', 'urls', []),
array_merge($urls, [
'original' => $urlGenerator->setOptions([
'noProcess' => true,
])->getUrl(true)
], $this->getSizes($urlGenerator))
);
} else {
if ($document->hasThumbnails()) {
$thumbnail = $document->getThumbnails()->first();
if ($thumbnail instanceof Document && $thumbnail->isProcessable()) {
/** @var DocumentUrlGenerator $thumbUrlGenerator */
$thumbUrlGenerator = $this->get('document.url_generator')->setDocument($thumbnail);
$urls = array_merge($urls, $this->getSizes($thumbUrlGenerator));
}
}
$visitor->visitProperty(
new StaticPropertyMetadata('array', 'urls', []),
array_merge($urls, [
'original' => $urlGenerator->setOptions([
'noProcess' => true
])->getUrl(true),
])
);
}
}
}
}
protected function getSizes(DocumentUrlGenerator $generator): array
{
return [];
}
}
Groups
------
Expand Down

0 comments on commit 6bfdefe

Please sign in to comment.