Skip to content

Commit

Permalink
EZP-30065: As an editor I would like content tree to use real data (#854
Browse files Browse the repository at this point in the history
)

* EZP-30065: As an editor I would like content tree to use real data

* Refactorings after code review

* fixup! Refactorings after code review
  • Loading branch information
webhdx authored and Łukasz Serwatka committed Feb 27, 2019
1 parent bf0bfcd commit 5faf812
Show file tree
Hide file tree
Showing 18 changed files with 883 additions and 3 deletions.
94 changes: 94 additions & 0 deletions src/bundle/Controller/Content/ContentTreeController.php
@@ -0,0 +1,94 @@
<?php

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

namespace EzSystems\EzPlatformAdminUiBundle\Controller\Content;

use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\Core\REST\Common\Message;
use eZ\Publish\Core\REST\Server\Controller as RestController;
use EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\LoadSubtreeRequestNode;
use EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Node;
use EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Root;
use EzSystems\EzPlatformAdminUi\UI\Module\ContentTree\NodeFactory;
use Symfony\Component\HttpFoundation\Request;

class ContentTreeController extends RestController
{
/** @var \eZ\Publish\API\Repository\LocationService */
private $locationService;

/** @var \EzSystems\EzPlatformAdminUi\UI\Module\ContentTree\NodeFactory */
private $contentTreeNodeFactory;

/**
* @param \eZ\Publish\API\Repository\LocationService $locationService
* @param \EzSystems\EzPlatformAdminUi\UI\Module\ContentTree\NodeFactory $contentTreeNodeFactory
*/
public function __construct(
LocationService $locationService,
NodeFactory $contentTreeNodeFactory
) {
$this->locationService = $locationService;
$this->contentTreeNodeFactory = $contentTreeNodeFactory;
}

/**
* @param int $parentLocationId
* @param int $limit
* @param int $offset
*
* @return \EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Node
*
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
public function loadChildrenAction(int $parentLocationId, int $limit, int $offset): Node
{
$location = $this->locationService->loadLocation($parentLocationId);

$loadSubtreeRequestNode = new LoadSubtreeRequestNode($parentLocationId, $limit, $offset);

return $this->contentTreeNodeFactory->createNode($location, $loadSubtreeRequestNode, true);
}

/**
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return \EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Root
*
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
*/
public function loadSubtreeAction(Request $request): Root
{
/** @var \EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\LoadSubtreeRequest $loadSubtreeRequest */
$loadSubtreeRequest = $this->inputDispatcher->parse(
new Message(
['Content-Type' => $request->headers->get('Content-Type')],
$request->getContent()
)
);

$locationIdList = array_column($loadSubtreeRequest->nodes, 'locationId');
$locations = $this->locationService->loadLocationList($locationIdList);

$elements = [];
foreach ($loadSubtreeRequest->nodes as $childLoadSubtreeRequestNode) {
$location = $locations[$childLoadSubtreeRequestNode->locationId];
$elements[] = $this->contentTreeNodeFactory->createNode(
$location,
$childLoadSubtreeRequestNode,
true
);
}

return new Root($elements);
}
}
@@ -0,0 +1,110 @@
<?php

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

namespace EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\Module;

use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\AbstractParser;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

/**
* Configuration parser for Subitems module.
*
* Example configuration:
* ```yaml
* ezpublish:
* system:
* default: # configuration per siteaccess or siteaccess group
* content_tree_module:
* load_more_limit: 30
* children_load_max_limit: 200
* tree_max_depth: 10
* ```
*/
class ContentTree extends AbstractParser
{
/**
* {@inheritdoc}
*/
public function addSemanticConfig(NodeBuilder $nodeBuilder)
{
$nodeBuilder
->arrayNode('content_tree_module')
->info('Content Tree module configuration')
->children()
->integerNode('load_more_limit')
->info('Number of children to load in expand and load more operations')
->isRequired()
->defaultValue(30)
->end()
->integerNode('children_load_max_limit')
->info('Total limit of loaded children in single node')
->isRequired()
->defaultValue(200)
->end()
->integerNode('tree_max_depth')
->info('Max depth of expanded tree')
->isRequired()
->defaultValue(10)
->end()
->arrayNode('content_type_ignore_list')
->info('List of content type identifiers to ignore in Content Tree')
->arrayPrototype()
->children()
->scalarNode('content_type_identifier')
->end()
->end()
->end()
->end()
->end();
}

/**
* {@inheritdoc}
*/
public function mapConfig(array &$scopeSettings, $currentScope, ContextualizerInterface $contextualizer): void
{
if (empty($scopeSettings['content_tree_module'])) {
return;
}

$settings = $scopeSettings['content_tree_module'];

if (array_key_exists('load_more_limit', $settings)) {
$contextualizer->setContextualParameter(
'content_tree_module.load_more_limit',
$currentScope,
$settings['load_more_limit']
);
}

if (array_key_exists('children_load_max_limit', $settings)) {
$contextualizer->setContextualParameter(
'content_tree_module.children_load_max_limit',
$currentScope,
$settings['children_load_max_limit']
);
}

if (array_key_exists('tree_max_depth', $settings)) {
$contextualizer->setContextualParameter(
'content_tree_module.tree_max_depth',
$currentScope,
$settings['tree_max_depth']
);
}

if (array_key_exists('content_type_ignore_list', $settings)) {
$contextualizer->setContextualParameter(
'content_tree_module.content_type_ignore_list',
$currentScope,
$settings['content_type_ignore_list']
);
}
}
}
1 change: 1 addition & 0 deletions src/bundle/EzPlatformAdminUiBundle.php
Expand Up @@ -66,6 +66,7 @@ private function getConfigParsers(): array
new Parser\LocationIds(),
new Parser\Module\Subitems(),
new Parser\Module\UniversalDiscoveryWidget(),
new Parser\Module\ContentTree(),
new Parser\Pagination(),
new Parser\Security(),
new Parser\UserIdentifier(),
Expand Down
7 changes: 7 additions & 0 deletions src/bundle/Resources/config/ezplatform_default_settings.yml
Expand Up @@ -53,3 +53,10 @@ parameters:

# Additional translations e.g. ['en_US', 'nb_NO']
ezsettings.default.user_preferences.additional_translations: []

# Content Tree Module
ezsettings.default.content_tree_module.load_more_limit: 30
ezsettings.default.content_tree_module.children_load_max_limit: 200
ezsettings.default.content_tree_module.tree_max_depth: 10
ezsettings.default.content_tree_module.content_type_ignore_list: []

36 changes: 33 additions & 3 deletions src/bundle/Resources/config/routing_rest.yml
@@ -1,7 +1,37 @@
#
# Bulk Operation
#

ezplatform.bulk_operation:
path: /bulk
options:
expose: true
expose: true
defaults:
_controller: 'EzPlatformAdminUiBundle:BulkOperation\BulkOperation:bulk'
methods: [POST]
_controller: 'EzPlatformAdminUiBundle:BulkOperation\BulkOperation:bulk'
methods: ['POST']

#
# Location Tree
#

ezplatform.location.tree.load_children:
# @todo change name to content tree
path: /location/tree/load-subitems/{parentLocationId}/{limit}/{offset}
methods: ['GET']
options:
expose: true
requirements:
parentLocationId: \d+
defaults:
_controller: 'EzPlatformAdminUiBundle:Content/ContentTree:loadChildren'
limit: 10
offset: 0

ezplatform.location.tree.load_subtree:
# @todo change name to content tree
path: /location/tree/load-subtree
methods: ['POST']
options:
expose: true
defaults:
_controller: 'EzPlatformAdminUiBundle:Content/ContentTree:loadSubtree'
1 change: 1 addition & 0 deletions src/bundle/Resources/config/services.yml
Expand Up @@ -8,6 +8,7 @@ imports:
- { resource: services/components.yml }
- { resource: services/dashboard.yml }
- { resource: services/modules/subitems.yml }
- { resource: services/modules/content_tree.yml }
- { resource: services/form_processors.yml }
- { resource: services/validators.yml }
- { resource: services/siteaccess.yml }
Expand Down
10 changes: 10 additions & 0 deletions src/bundle/Resources/config/services/controllers.yml
Expand Up @@ -109,3 +109,13 @@ services:
parent: EzSystems\EzPlatformAdminUiBundle\Controller\Controller
arguments:
$defaultPaginationLimit: '$pagination.content_draft_limit$'

#
# REST
#

EzSystems\EzPlatformAdminUiBundle\Controller\Content\ContentTreeController:
parent: ezpublish_rest.controller.base
tags: ['controller.service_arguments']
autowire: true
autoconfigure: false
12 changes: 12 additions & 0 deletions src/bundle/Resources/config/services/modules/content_tree.yml
@@ -0,0 +1,12 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: true

EzSystems\EzPlatformAdminUi\UI\Module\ContentTree\NodeFactory:
arguments:
$displayLimit: '$content_tree_module.load_more_limit$'
$childrenLoadMaxLimit: '$content_tree_module.children_load_max_limit$'
$maxDepth: '$content_tree_module.tree_max_depth$'
$contentTypeIdentifierIgnoreList: '$content_tree_module.content_type_ignore_list$'
24 changes: 24 additions & 0 deletions src/bundle/Resources/config/services/rest.yml
Expand Up @@ -13,3 +13,27 @@ services:
parent: ezpublish_rest.output.value_object_visitor.base
tags:
- { name: ezpublish_rest.output.value_object_visitor, type: EzSystems\EzPlatformAdminUi\REST\Value\BulkOperationResponse }

#
# Content Tree
#

EzSystems\EzPlatformAdminUi\REST\Input\Parser\ContentTree\LoadSubtreeRequestNode:
parent: ezpublish_rest.input.parser
tags:
- { name: ezpublish_rest.input.parser, mediaType: application/vnd.ez.api.ContentTree.LoadSubtreeRequestNode }

EzSystems\EzPlatformAdminUi\REST\Input\Parser\ContentTree\LoadSubtreeRequest:
parent: ezpublish_rest.input.parser
tags:
- { name: ezpublish_rest.input.parser, mediaType: application/vnd.ez.api.ContentTree.LoadSubtreeRequest }
-
EzSystems\EzPlatformAdminUi\REST\Output\ValueObjectVisitor\ContentTree\Node:
parent: ezpublish_rest.output.value_object_visitor.base
tags:
- { name: ezpublish_rest.output.value_object_visitor, type: EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Node }

EzSystems\EzPlatformAdminUi\REST\Output\ValueObjectVisitor\ContentTree\Root:
parent: ezpublish_rest.output.value_object_visitor.base
tags:
- { name: ezpublish_rest.output.value_object_visitor, type: EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\Root }
36 changes: 36 additions & 0 deletions src/lib/REST/Input/Parser/ContentTree/LoadSubtreeRequest.php
@@ -0,0 +1,36 @@
<?php

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

namespace EzSystems\EzPlatformAdminUi\REST\Input\Parser\ContentTree;

use eZ\Publish\Core\REST\Common\Exceptions;
use eZ\Publish\Core\REST\Common\Input\BaseParser;
use eZ\Publish\Core\REST\Common\Input\ParsingDispatcher;
use EzSystems\EzPlatformAdminUi\REST\Value\ContentTree\LoadSubtreeRequest as LoadSubtreeRequestValue;

class LoadSubtreeRequest extends BaseParser
{
/**
* {@inheritdoc}
*/
public function parse(array $data, ParsingDispatcher $parsingDispatcher): LoadSubtreeRequestValue
{
if (!array_key_exists('nodes', $data) || !is_array($data['nodes'])) {
throw new Exceptions\Parser(
sprintf("Missing or invalid 'nodes' property for %s.", self::class)
);
}

$nodes = [];
foreach ($data['nodes'] as $node) {
$nodes[] = $parsingDispatcher->parse($node, $node['_media-type']);
}

return new LoadSubtreeRequestValue($nodes);
}
}

0 comments on commit 5faf812

Please sign in to comment.