partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit d6a4bd5c60690c09d0ce47d15750c850669e3bde
parent fc1bc195fa8b5e824b3fcd48e3170709862f572d
Author: Felicitus <felicitus@felicitus.org>
Date:   Sat, 10 Oct 2015 18:30:21 +0200

Removed special handling of @local-tree-root, will be done within the frontend

Diffstat:
Mapp/config/config_partkeepr.yml | 63+++++++++++++++++++++++++++------------------------------------
Dsrc/PartKeepr/CategoryBundle/Action/PostAction.php | 81-------------------------------------------------------------------------------
Asrc/PartKeepr/CategoryBundle/EventListener/RootCategoryListener.php | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/CategoryBundle/Exception/OnlySingleRootNodeAllowedException.php | 14++++++++++++++
Msrc/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php | 46++++++++++++++++++++++++++++++++++++++++------
Msrc/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php | 1-
Dsrc/PartKeepr/FootprintBundle/Resources/config/actions.xml | 14--------------
Asrc/PartKeepr/PartBundle/Action/PostAction.php | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/PartBundle/Entity/Part.php | 2+-
Msrc/PartKeepr/PartBundle/Resources/config/actions.xml | 5-----
Msrc/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php | 1-
Dsrc/PartKeepr/StorageLocationBundle/Resources/config/actions.xml | 14--------------
12 files changed, 229 insertions(+), 159 deletions(-)

diff --git a/app/config/config_partkeepr.yml b/app/config/config_partkeepr.yml @@ -27,6 +27,30 @@ services: tags: - { name: doctrine.event_listener, event: onFlush } + footprint_category.root_category_listener: + class: PartKeepr\CategoryBundle\EventListener\RootCategoryListener + arguments: + - "@service_container" + - "partkeepr.footprint.category_service" + tags: + - { name: doctrine.event_listener, event: onFlush } + + part_category.root_category_listener: + class: PartKeepr\CategoryBundle\EventListener\RootCategoryListener + arguments: + - "@service_container" + - "partkeepr.part.category_service" + tags: + - { name: doctrine.event_listener, event: onFlush } + + storage_location_category.root_category_listener: + class: PartKeepr\CategoryBundle\EventListener\RootCategoryListener + arguments: + - "@service_container" + - "partkeepr.storage_location.category_service" + tags: + - { name: doctrine.event_listener, event: onFlush } + temporary_file_listener: class: PartKeepr\UploadedFileBundle\EventListener\TemporaryFileEventListener arguments: @@ -167,17 +191,6 @@ services: factory: [ "@api.operation_factory", "createCollectionOperation" ] arguments: [ "@resource.footprint_category", "GET" ] - resource.footprint_category.collection_operation.custom_post: - class: "Dunglas\ApiBundle\Api\Operation\Operation" - public: false - factory: [ "@api.operation_factory", "createCollectionOperation" ] - arguments: - - "@resource.footprint_category" # Resource - - [ "POST" ] # Methods - - "/footprint_categories" # Path - - "partkeepr.footprint_category.post" # Controller - - "PartKeeprFootprintCategoryPost" - resource.footprint_category.collection_operation.get_root: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false @@ -213,7 +226,7 @@ services: tags: [ { name: "api.resource" } ] calls: - method: "initCollectionOperations" - arguments: [ [ "@resource.footprint_category.collection_operation.get", "@resource.footprint_category.collection_operation.get_root", "@resource.footprint_category.collection_operation.custom_post" ] ] + arguments: [ [ "@resource.footprint_category.collection_operation.get", "@resource.footprint_category.collection_operation.get_root", "@resource.footprint_category.collection_operation.post" ] ] - method: "initItemOperations" arguments: [ [ "@resource.footprint_category.item_operation.get", "@resource.footprint_category.item_operation.put", "@resource.footprint_category.item_operation.delete", "@resource.footprint_category.item_operation.move" ] ] - method: "initNormalizationContext" @@ -365,17 +378,6 @@ services: - "partkeepr.category.move" # Controller - "PartKeeprPartCategoryMove" - resource.part_category.collection_operation.custom_post: - class: "Dunglas\ApiBundle\Api\Operation\Operation" - public: false - factory: [ "@api.operation_factory", "createCollectionOperation" ] - arguments: - - "@resource.part_category" # Resource - - [ "POST" ] # Methods - - "/part_categories" # Path - - "partkeepr.part_category.post" # Controller - - "PartKeeprPartCategoryPost" - resource.part_category.collection_operation.get_root: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false @@ -411,7 +413,7 @@ services: tags: [ { name: "api.resource" } ] calls: - method: "initCollectionOperations" - arguments: [ [ "@resource.part_category.collection_operation.get", "@resource.part_category.collection_operation.get_root", "@resource.part_category.collection_operation.custom_post" ] ] + arguments: [ [ "@resource.part_category.collection_operation.get", "@resource.part_category.collection_operation.get_root", "@resource.part_category.collection_operation.post" ] ] - method: "initItemOperations" arguments: [ [ "@resource.part_category.item_operation.get", "@resource.part_category.item_operation.put", "@resource.part_category.item_operation.delete", "@resource.part_category.item_operation.move" ] ] - method: "initNormalizationContext" @@ -606,17 +608,6 @@ services: - "partkeepr.category.move" # Controller - "StorageLocationCategoryMove" # Route name - resource.storage_location_category.collection_operation.custom_post: - class: "Dunglas\ApiBundle\Api\Operation\Operation" - public: false - factory: [ "@api.operation_factory", "createCollectionOperation" ] - arguments: - - "@resource.storage_location_category" # Resource - - [ "POST" ] # Methods - - "/storage_location_categories" # Path - - "partkeepr.storage_location_category.post" # Controller - - "PartKeeprStorageLocationCategoryPost" - resource.storage_location_category.collection_operation.get_root: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false @@ -658,7 +649,7 @@ services: tags: [ { name: "api.resource" } ] calls: - method: "initCollectionOperations" - arguments: [ [ "@resource.storage_location_category.collection_operation.get", "@resource.storage_location_category.collection_operation.get_root", "@resource.storage_location_category.collection_operation.custom_post" ] ] + arguments: [ [ "@resource.storage_location_category.collection_operation.get", "@resource.storage_location_category.collection_operation.get_root", "@resource.storage_location_category.collection_operation.post" ] ] - method: "initItemOperations" arguments: [ [ "@resource.storage_location_category.item_operation.get", "@resource.storage_location_category.item_operation.put", "@resource.storage_location_category.item_operation.delete", "@resource.storage_location_category.item_operation.move" ] ] - method: "initNormalizationContext" diff --git a/src/PartKeepr/CategoryBundle/Action/PostAction.php b/src/PartKeepr/CategoryBundle/Action/PostAction.php @@ -1,81 +0,0 @@ -<?php -namespace PartKeepr\CategoryBundle\Action; - - -use Dunglas\ApiBundle\Action\ActionUtilTrait; -use Dunglas\ApiBundle\Api\IriConverterInterface; -use Dunglas\ApiBundle\Api\ResourceInterface; -use Dunglas\ApiBundle\Exception\RuntimeException; -use PartKeepr\CategoryBundle\Services\CategoryService; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Serializer\SerializerInterface; - -class PostAction -{ - use ActionUtilTrait; - - /** - * @var CategoryService - */ - private $categoryService; - - /** - * @var IriConverterInterface - */ - private $iriConverter; - - /** - * @var SerializerInterface - */ - private $serializer; - - public function __construct( - CategoryService $categoryService, - IriConverterInterface $iriConverter, - SerializerInterface $serializer - ) { - $this->categoryService = $categoryService; - $this->iriConverter = $iriConverter; - $this->serializer = $serializer; - } - - /** - * Injects the specific root node ID if "@local-tree-root" was specified - * - * @param Request $request - * - * @return mixed - * - * @throws RuntimeException - */ - public function __invoke(Request $request) - { - /** - * @var $resourceType ResourceInterface - */ - list($resourceType, $format) = $this->extractAttributes($request); - - $data = $request->getContent(); - - if (is_a($resourceType->getEntityClass(), $this->categoryService->getEntityClass(), true)) { - $decodedData = json_decode($data); - - if (property_exists($decodedData, "parent") && $decodedData->parent == "@local-tree-root") { - $root = $this->categoryService->getRootNode(); - $iri = $this->iriConverter->getIriFromItem($root); - - $decodedData->parent = $iri; - } - - $data = json_encode($decodedData); - } - - return $this->serializer->deserialize( - $data, - $resourceType->getEntityClass(), - $format, - $resourceType->getDenormalizationContext() - ); - - } -} diff --git a/src/PartKeepr/CategoryBundle/EventListener/RootCategoryListener.php b/src/PartKeepr/CategoryBundle/EventListener/RootCategoryListener.php @@ -0,0 +1,56 @@ +<?php +namespace PartKeepr\CategoryBundle\EventListener; + +use Doctrine\ORM\Event\OnFlushEventArgs; +use PartKeepr\CategoryBundle\Entity\AbstractCategory; +use PartKeepr\CategoryBundle\Exception\OnlySingleRootNodeAllowedException; +use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerAware; + +class RootCategoryListener extends ContainerAware +{ + /** + * @var string + */ + private $service; + + public function __construct (Container $container, $service) { + $this->setContainer($container); + $this->service = $service; + } + /** + * Checks that only one root category exists + * + * @param OnFlushEventArgs $eventArgs The event arguments as given by Doctrine + */ + public function onFlush(OnFlushEventArgs $eventArgs) + { + $entityManager = $eventArgs->getEntityManager(); + $uow = $entityManager->getUnitOfWork(); + + foreach ($uow->getScheduledEntityInsertions() as $updated) { + + if (is_a($updated, $this->container->get($this->service)->getEntityClass())) { + $this->checkForRoot($updated); + } + } + + foreach ($uow->getScheduledEntityUpdates() as $updated) { + if (is_a($updated, $this->container->get($this->service)->getEntityClass())) { + $this->checkForRoot($updated); + } + } + } + + protected function checkForRoot (AbstractCategory $category) { + if ($category->getParent() === null) { + try { + $this->container->get($this->service)->getRootNode(); + throw new OnlySingleRootNodeAllowedException(); + } catch (RootNodeNotFoundException $e) { + + } + } + } +} diff --git a/src/PartKeepr/CategoryBundle/Exception/OnlySingleRootNodeAllowedException.php b/src/PartKeepr/CategoryBundle/Exception/OnlySingleRootNodeAllowedException.php @@ -0,0 +1,14 @@ +<?php + + +namespace PartKeepr\CategoryBundle\Exception; + + +class OnlySingleRootNodeAllowedException extends \Exception +{ + public function __construct($message = "", $code = 0, \Exception $previous = null) + { + $message = "There may be only one root node"; + parent::__construct($message, $code, $previous); + } +} diff --git a/src/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php b/src/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php @@ -21,19 +21,21 @@ abstract class AbstractCategoryCreateTest extends WebTestCase )->getReferenceRepository(); } - public function testRootCreateCateory () { + public function testCreateCategory () { $client = static::makeClient(true); - $request = array( - "parent" => "@local-tree-root", - "name" => "test" - ); + $rootCategory = $this->fixtures->getReference($this->getReferencePrefix().".root"); /** * @var $iriConverter IriConverter */ $iriConverter = $this->getContainer()->get("api.iri_converter"); + $request = array( + "parent" => $iriConverter->getIriFromItem($rootCategory), + "name" => "test" + ); + $resource = $this->getContainer()->get("api.resource_collection")->getResourceForEntity($this->getResourceClass()); $iri = $iriConverter->getIriFromResource($resource); @@ -54,12 +56,44 @@ abstract class AbstractCategoryCreateTest extends WebTestCase $this->assertObjectHasAttribute("name", $responseObject); $item = $iriConverter->getItemFromIri($responseObject->{"@id"}); - $rootCategory = $this->fixtures->getReference($this->getReferencePrefix().".root"); + $this->assertNotNull($item->getParent()); $this->assertEquals($item->getParent()->getId(), $rootCategory->getId()); } + public function testCreateRootCategory () { + $client = static::makeClient(true); + + /** + * @var $iriConverter IriConverter + */ + $iriConverter = $this->getContainer()->get("api.iri_converter"); + + $request = array( + "name" => "test" + ); + + $resource = $this->getContainer()->get("api.resource_collection")->getResourceForEntity($this->getResourceClass()); + $iri = $iriConverter->getIriFromResource($resource); + + $client->request( + 'POST', + $iri, + array(), + array(), + array('CONTENT_TYPE' => 'application/json'), + json_encode($request) + ); + + $responseObject = json_decode($client->getResponse()->getContent()); + + $this->assertObjectHasAttribute("@type", $responseObject); + $this->assertObjectHasAttribute("hydra:description", $responseObject); + + $this->assertEquals("There may be only one root node", $responseObject->{"hydra:description"}); + } + abstract public function getFixtureLoaderClass(); abstract public function getReferencePrefix(); diff --git a/src/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php b/src/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php @@ -21,6 +21,5 @@ class PartKeeprFootprintExtension extends Extension { $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $loader->load('actions.xml'); } } diff --git a/src/PartKeepr/FootprintBundle/Resources/config/actions.xml b/src/PartKeepr/FootprintBundle/Resources/config/actions.xml @@ -1,14 +0,0 @@ -<?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.footprint_category.post" class="PartKeepr\CategoryBundle\Action\PostAction"> - <argument type="service" id="partkeepr.footprint.category_service"/> - <argument type="service" id="api.iri_converter"/> - <argument type="service" id="api.serializer"/> - </service> - </services> -</container> diff --git a/src/PartKeepr/PartBundle/Action/PostAction.php b/src/PartKeepr/PartBundle/Action/PostAction.php @@ -0,0 +1,91 @@ +<?php + + +namespace PartKeepr\PartBundle\Action; + +use Dunglas\ApiBundle\Action\ActionUtilTrait; +use Dunglas\ApiBundle\Api\IriConverterInterface; +use Dunglas\ApiBundle\Api\ResourceInterface; +use Dunglas\ApiBundle\Exception\RuntimeException; +use PartKeepr\CategoryBundle\Services\CategoryService; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Serializer\SerializerInterface; + +class PostAction +{ + use ActionUtilTrait; + + /** + * @var CategoryService + */ + private $categoryService; + + /** + * @var IriConverterInterface + */ + private $iriConverter; + + /** + * @var SerializerInterface + */ + private $serializer; + + public function __construct( + CategoryService $categoryService, + IriConverterInterface $iriConverter, + SerializerInterface $serializer + ) { + $this->categoryService = $categoryService; + $this->iriConverter = $iriConverter; + $this->serializer = $serializer; + } + + /** + * Injects the specific root node ID if "@local-tree-root" was specified + * + * @param Request $request + * + * @return mixed + * + * @throws RuntimeException + */ + public function __invoke(Request $request) + { + /** + * @var $resourceType ResourceInterface + */ + list($resourceType, $format) = $this->extractAttributes($request); + + $data = $request->getContent(); + + $decodedData = json_decode($data); + + $localTreeExists = false; + if (property_exists($decodedData,"category") && $decodedData->category == "@local-tree-root") { + $localTreeExists = true; + + } + + if (property_exists($decodedData,"category") && is_object($decodedData->category) && property_exists($decodedData->category, "@id") && $decodedData->category->{"@id"} == "@local-tree-root") { + $localTreeExists = true; + } + + if ($localTreeExists === true) { + $root = $this->categoryService->getRootNode(); + $iri = $this->iriConverter->getIriFromItem($root); + + $decodedData->category = $iri; + $data = json_encode($decodedData); + } + + + + return $this->serializer->deserialize( + $data, + $resourceType->getEntityClass(), + $format, + $resourceType->getDenormalizationContext() + ); + + } +} diff --git a/src/PartKeepr/PartBundle/Entity/Part.php b/src/PartKeepr/PartBundle/Entity/Part.php @@ -582,7 +582,7 @@ class Part extends BaseEntity * * @param PartCategory $category The category */ - public function setCategory(PartCategory $category) + public function setCategory($category) { $this->category = $category; } diff --git a/src/PartKeepr/PartBundle/Resources/config/actions.xml b/src/PartKeepr/PartBundle/Resources/config/actions.xml @@ -24,10 +24,5 @@ <argument type="service" id="api.data_provider"/> <argument type="service" id="partkeepr.part_measurement_unit_service"/> </service> - <service id="partkeepr.part_category.post" class="PartKeepr\CategoryBundle\Action\PostAction"> - <argument type="service" id="partkeepr.part.category_service"/> - <argument type="service" id="api.iri_converter"/> - <argument type="service" id="api.serializer"/> - </service> </services> </container> diff --git a/src/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php b/src/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php @@ -21,6 +21,5 @@ class PartKeeprStorageLocationExtension extends Extension { $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $loader->load('actions.xml'); } } diff --git a/src/PartKeepr/StorageLocationBundle/Resources/config/actions.xml b/src/PartKeepr/StorageLocationBundle/Resources/config/actions.xml @@ -1,14 +0,0 @@ -<?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.storage_location_category.post" class="PartKeepr\CategoryBundle\Action\PostAction"> - <argument type="service" id="partkeepr.storage_location.category_service"/> - <argument type="service" id="api.iri_converter"/> - <argument type="service" id="api.serializer"/> - </service> - </services> -</container>