commit 8b11ab87fa47431557b0e99953948112f436ce02
parent 465a63503a277beb5395c09928a1d699f7c7c41a
Author: Felicitus <felicitus@felicitus.org>
Date: Sat, 12 Sep 2015 15:31:27 +0200
Refactored the category controller to use the new ADR style actions
Diffstat:
7 files changed, 157 insertions(+), 201 deletions(-)
diff --git a/app/config/config.yml b/app/config/config.yml
@@ -288,12 +288,8 @@ services:
- "@resource.footprint_category" # Resource
- [ "PUT" ] # Methods
- "/footprint_categories/{id}/move" # Path
- - "PartKeeprCategoryBundle:Category:move" # Controller
+ - "partkeepr.category.move" # Controller
- "FootprintCategoryMove" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
resource.footprint_category.collection_operation.post:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -309,12 +305,8 @@ services:
- "@resource.footprint_category" # Resource
- [ "GET" ] # Methods
- "/footprint_categories/getExtJSRootNode" # Path
- - "PartKeeprCategoryBundle:Category:getExtJSRootNode" # Controller
- - "FootprintCategoryGetRoot" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
+ - "partkeepr.category.get_root_node" # Controller
+ - "PartKeeprFootprintCategoryGetRootNode"
resource.footprint_category.item_operation.get:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -501,12 +493,8 @@ services:
- "@resource.part_category" # Resource
- [ "PUT" ] # Methods
- "/part_categories/{id}/move" # Path
- - "PartKeeprCategoryBundle:Category:move" # Controller
- - "PartCategoryMove" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
+ - "partkeepr.category.move" # Controller
+ - "PartKeeprPartCategoryMove"
resource.part_category.collection_operation.post:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -522,12 +510,8 @@ services:
- "@resource.part_category" # Resource
- [ "GET" ] # Methods
- "/part_categories/getExtJSRootNode" # Path
- - "PartKeeprCategoryBundle:Category:getExtJSRootNode" # Controller
- - "PartCategoryGetRoot" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
+ - "partkeepr.category.get_root_node" # Controller
+ - "PartKeeprPartCategoryGetRootNode"
resource.part_category.item_operation.get:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -731,12 +715,8 @@ services:
- "@resource.storage_location_category" # Resource
- [ "PUT" ] # Methods
- "/storage_location_categories/{id}/move" # Path
- - "PartKeeprCategoryBundle:Category:move" # Controller
+ - "partkeepr.category.move" # Controller
- "StorageLocationCategoryMove" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
resource.storage_location_category.collection_operation.get_root:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -746,12 +726,8 @@ services:
- "@resource.storage_location_category" # Resource
- [ "GET" ] # Methods
- "/storage_location_categories/getExtJSRootNode" # Path
- - "PartKeeprCategoryBundle:Category:getExtJSRootNode" # Controller
+ - "partkeepr.category.get_root_node" # Controller
- "StorageLocationCategoryGetRoot" # Route name
- - # Context (will be present in Hydra documentation)
- "@type": "hydra:Operation"
- "hydra:title": "A custom operation"
- "returns": "xmls:string"
resource.storage_location_category.item_operation.get:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
diff --git a/src/PartKeepr/CategoryBundle/Action/GetRootNodeAction.php b/src/PartKeepr/CategoryBundle/Action/GetRootNodeAction.php
@@ -1,27 +1,22 @@
<?php
-/*
- * This file is part of the DunglasApiBundle package.
- *
- * (c) Kévin Dunglas <dunglas@gmail.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-namespace Dunglas\ApiBundle\Action;
+namespace PartKeepr\CategoryBundle\Action;
+
+use Dunglas\ApiBundle\Action\ActionUtilTrait;
use Dunglas\ApiBundle\Api\ResourceInterface;
use Dunglas\ApiBundle\Exception\RuntimeException;
use Dunglas\ApiBundle\Model\DataProviderInterface;
use Gedmo\Tree\Entity\Repository\AbstractTreeRepository;
+use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException;
use Symfony\Bridge\Doctrine\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
+
/**
- * Default API action retrieving a collection of resources.
- *
- * @author Kévin Dunglas <dunglas@gmail.com>
+ * Returns the tree root node
*/
class GetRootNodeAction
{
use ActionUtilTrait;
+
/**
* @var DataProviderInterface
*/
@@ -37,6 +32,7 @@ class GetRootNodeAction
$this->dataProvider = $dataProvider;
$this->manager = $manager;
}
+
/**
* Retrieves a collection of resources.
*
@@ -44,12 +40,11 @@ class GetRootNodeAction
*
* @return array|\Dunglas\ApiBundle\Model\PaginatorInterface|\Traversable
*
- * @throws RuntimeException
+ * @throws RuntimeException|RootNodeNotFoundException
*/
public function __invoke(Request $request)
{
list($resourceType) = $this->extractAttributes($request);
- //return $this->dataProvider->getCollection($resourceType);
/**
* @var ResourceInterface $resourceType
@@ -59,19 +54,14 @@ class GetRootNodeAction
/**
* @var $repository AbstractTreeRepository
*/
- $rootNode = $repository->getRootNodes()[0];
+ $rootNodes = $repository->getRootNodes();
- return $rootNode;
- /*$data = $this->get('serializer')->normalize(
- $rootNode,
- 'json-ld',
- $resource->getNormalizationContext()
- );
+ if (count($rootNodes) == 0) {
+ throw new RootNodeNotFoundException();
+ }
- $responseData = array("children" => $data);
+ $rootNode = reset($rootNodes);
- return new JsonResponse(
- $responseData
- );*/
+ return $rootNode;
}
}
\ No newline at end of file
diff --git a/src/PartKeepr/CategoryBundle/Action/MoveAction.php b/src/PartKeepr/CategoryBundle/Action/MoveAction.php
@@ -0,0 +1,81 @@
+<?php
+namespace PartKeepr\CategoryBundle\Action;
+
+use Dunglas\ApiBundle\Action\ActionUtilTrait;
+use Dunglas\ApiBundle\Api\IriConverter;
+use Dunglas\ApiBundle\Exception\RuntimeException;
+use Dunglas\ApiBundle\Model\DataProviderInterface;
+use PartKeepr\CategoryBundle\Exception\MissingParentCategoryException;
+use PartKeepr\CategoryBundle\Exception\RootMayNotBeMovedException;
+use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException;
+use Symfony\Bridge\Doctrine\ManagerRegistry;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Returns the tree root node
+ */
+class MoveAction
+{
+ use ActionUtilTrait;
+
+ /**
+ * @var DataProviderInterface
+ */
+ private $dataProvider;
+
+ /**
+ * @var ManagerRegistry
+ */
+ private $registry;
+
+ /**
+ * @var IriConverter
+ */
+ private $iriConverter;
+
+ public function __construct(
+ DataProviderInterface $dataProvider,
+ IriConverter $iriConverter,
+ ManagerRegistry $registry
+ ) {
+ $this->dataProvider = $dataProvider;
+ $this->iriConverter = $iriConverter;
+ $this->registry = $registry;
+ }
+
+ /**
+ * Retrieves a collection of resources.
+ *
+ * @param Request $request
+ *
+ * @return array|\Dunglas\ApiBundle\Model\PaginatorInterface|\Traversable
+ *
+ * @throws RuntimeException|RootNodeNotFoundException
+ */
+ public function __invoke(Request $request, $id)
+ {
+ list($resourceType) = $this->extractAttributes($request);
+
+ $entity = $this->getItem($this->dataProvider, $resourceType, $id);
+
+ $parentId = $request->request->get("parent");
+
+ $parentEntity = $this->iriConverter->getItemFromIri($parentId);
+
+
+ if ($parentEntity === null) {
+ throw new MissingParentCategoryException($parentId);
+ }
+
+ if ($entity->getLevel() === 0) {
+ throw new RootMayNotBeMovedException();
+ }
+
+ $entity->setParent($parentEntity);
+
+ $this->registry->getManager()->flush();
+
+ return new Response($request->request->get("parent"));
+ }
+}+
\ No newline at end of file
diff --git a/src/PartKeepr/CategoryBundle/Controller/CategoryController.php b/src/PartKeepr/CategoryBundle/Controller/CategoryController.php
@@ -1,143 +0,0 @@
-<?php
-namespace PartKeepr\CategoryBundle\Controller;
-
-use Dunglas\ApiBundle\Api\ResourceInterface;
-use Dunglas\ApiBundle\Exception\InvalidArgumentException;
-use FOS\RestBundle\Controller\Annotations\RequestParam;
-use Gedmo\Tree\Entity\Repository\AbstractTreeRepository;
-use PartKeepr\CategoryBundle\Exception\MissingParentCategoryException;
-use PartKeepr\CategoryBundle\Exception\RootMayNotBeMovedException;
-use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException;
-use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-
-class CategoryController extends Controller
-{
- /**
- * @var ResourceInterface
- */
- private $resource;
- /**
- * Gets the Resource associated with the current Request.
- * Must be called before manipulating the resource.
- *
- * @param Request $request
- *
- * @return ResourceInterface
- *
- * @throws InvalidArgumentException
- */
- protected function getResource(Request $request)
- {
- if ($this->resource) {
- return $this->resource;
- }
- if (!$request->attributes->has('_resource')) {
- throw new InvalidArgumentException('The current request doesn\'t have an associated resource.');
- }
- $shortName = $request->attributes->get('_resource');
- if (!($this->resource = $this->get('api.resource_collection')->getResourceForShortName($shortName))) {
- throw new InvalidArgumentException(sprintf('The resource "%s" cannot be found.', $shortName));
- }
- return $this->resource;
- }
-
- /**
- * Finds an object of throws a 404 error.
- *
- * @param ResourceInterface $resource
- * @param string|int $id
- *
- * @return object
- *
- * @throws NotFoundHttpException
- */
- protected function findOrThrowNotFound(ResourceInterface $resource, $id)
- {
- $item = $this->get('api.data_provider')->getItem($resource, $id, true);
- if (!$item) {
- throw $this->createNotFoundException();
- }
- return $item;
- }
-
- /**
- * Moves a node to another node
- *
- * @RequestParam(name="parent",description="The ID of the new parent")
- * @param Request $request The request object
- * @param int $id The ID of the node to move
- *
- * @return Response
- *
- * @throws MissingParentCategoryException If the parent category is not specified or invalid
- * @throws RootMayNotBeMovedException If it is attempted to move the root category
- */
- public function moveAction(Request $request, $id)
- {
- $resource = $this->getResource($request);
- $entity = $this->findOrThrowNotFound($resource, $id);
- $parentId = $request->request->get("parent");
-
- $parentEntity = $this->get("api.iri_converter")->getItemFromIri($parentId);
-
-
- if ($parentEntity === null) {
- throw new MissingParentCategoryException($parentId);
- }
-
- if ($entity->getLevel() === 0) {
- throw new RootMayNotBeMovedException();
- }
-
- $entity->setParent($parentEntity);
-
- $this->get("doctrine")->getManager()->flush();
-
- return new Response($request->request->get("parent"));
- }
-
- /**
- * Returns the tree's root node wrapped in a virtual root node.
- *
- * This is required as ExtJS cannot replace the ID of their root node and cannot read in data one level below
- * root.
- *
- * @param Request $request
- *
- * @return JsonResponse
- */
- public function getExtJSRootNodeAction(Request $request)
- {
- $resource = $this->getResource($request);
-
- $repository = $this->getDoctrine()->getManager()->getRepository($resource->getEntityClass());
-
- /**
- * @var $repository AbstractTreeRepository
- */
- $rootNodes = $repository->getRootNodes();
-
- if (count($rootNodes) == 0) {
- throw new RootNodeNotFoundException();
- }
-
- $rootNode = reset($rootNodes);
-
- $data = $this->get('serializer')->normalize(
- $rootNode,
- 'json-ld',
- $resource->getNormalizationContext()
- );
-
- $responseData = array("children" => $data);
-
- return new JsonResponse(
- $responseData
- );
-
- }
-}
diff --git a/src/PartKeepr/CategoryBundle/DependencyInjection/PartKeeprCategoryExtension.php b/src/PartKeepr/CategoryBundle/DependencyInjection/PartKeeprCategoryExtension.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace PartKeepr\CategoryBundle\DependencyInjection;
+
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+/**
+ * This is the class that loads and manages your bundle configuration
+ *
+ * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
+ */
+class PartKeeprCategoryExtension extends Extension
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function load(array $configs, ContainerBuilder $container)
+ {
+ $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+ $loader->load('actions.xml');
+ }
+}
diff --git a/src/PartKeepr/CategoryBundle/Exception/RootNodeNotFoundException.php b/src/PartKeepr/CategoryBundle/Exception/RootNodeNotFoundException.php
@@ -0,0 +1,8 @@
+<?php
+namespace PartKeepr\CategoryBundle\Exception;
+
+
+class RootNodeNotFoundException extends \Exception
+{
+
+}
diff --git a/src/PartKeepr/CategoryBundle/Resources/config/actions.xml b/src/PartKeepr/CategoryBundle/Resources/config/actions.xml
@@ -0,0 +1,18 @@
+<?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="partkeepr.category.get_root_node" class="PartKeepr\CategoryBundle\Action\GetRootNodeAction">
+ <argument type="service" id="api.data_provider"/>
+ <argument type="service" id="doctrine"/>
+ </service>
+ <service id="partkeepr.category.move" class="PartKeepr\CategoryBundle\Action\MoveAction">
+ <argument type="service" id="api.data_provider"/>
+ <argument type="service" id="api.iri_converter" />
+ <argument type="service" id="doctrine"/>
+ </service>
+ </services>
+</container>