partkeepr

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

commit fc1bc195fa8b5e824b3fcd48e3170709862f572d
parent fcb83f347ddf828f6b6899cb3f567d512bf41976
Author: Felicitus <felicitus@felicitus.org>
Date:   Sat, 10 Oct 2015 16:08:45 +0200

Added special handling of @local-tree-root

Diffstat:
Mapp/config/config_partkeepr.yml | 35++++++++++++++++++++++++++++-------
Asrc/PartKeepr/CategoryBundle/Action/PostAction.php | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/CategoryBundle/Services/CategoryService.php | 4++++
Asrc/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/PartKeepr/FootprintBundle/DependencyInjection/Configuration.php | 29-----------------------------
Msrc/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php | 4+---
Msrc/PartKeepr/FootprintBundle/Entity/FootprintCategory.php | 2+-
Asrc/PartKeepr/FootprintBundle/Resources/config/actions.xml | 14++++++++++++++
Asrc/PartKeepr/FootprintBundle/Tests/CategoryCreateTest.php | 23+++++++++++++++++++++++
Msrc/PartKeepr/PartBundle/Entity/PartCategory.php | 3++-
Msrc/PartKeepr/PartBundle/Resources/config/actions.xml | 5+++++
Asrc/PartKeepr/PartBundle/Tests/CategoryCreateTest.php | 24++++++++++++++++++++++++
Msrc/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php | 1+
Msrc/PartKeepr/StorageLocationBundle/Entity/StorageLocationCategory.php | 2+-
Asrc/PartKeepr/StorageLocationBundle/Resources/config/actions.xml | 14++++++++++++++
Asrc/PartKeepr/StorageLocationBundle/Tests/CategoryCreateTest.php | 24++++++++++++++++++++++++
16 files changed, 291 insertions(+), 42 deletions(-)

diff --git a/app/config/config_partkeepr.yml b/app/config/config_partkeepr.yml @@ -167,11 +167,16 @@ services: factory: [ "@api.operation_factory", "createCollectionOperation" ] arguments: [ "@resource.footprint_category", "GET" ] - resource.footprint_category.collection_operation.post: + resource.footprint_category.collection_operation.custom_post: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false factory: [ "@api.operation_factory", "createCollectionOperation" ] - arguments: [ "@resource.footprint_category", "POST" ] + 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" @@ -208,7 +213,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.post" ] ] + arguments: [ [ "@resource.footprint_category.collection_operation.get", "@resource.footprint_category.collection_operation.get_root", "@resource.footprint_category.collection_operation.custom_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" @@ -360,11 +365,16 @@ services: - "partkeepr.category.move" # Controller - "PartKeeprPartCategoryMove" - resource.part_category.collection_operation.post: + resource.part_category.collection_operation.custom_post: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false factory: [ "@api.operation_factory", "createCollectionOperation" ] - arguments: [ "@resource.part_category", "POST" ] + 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" @@ -401,7 +411,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.post" ] ] + arguments: [ [ "@resource.part_category.collection_operation.get", "@resource.part_category.collection_operation.get_root", "@resource.part_category.collection_operation.custom_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" @@ -596,6 +606,17 @@ 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 @@ -637,7 +658,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.post" ] ] + arguments: [ [ "@resource.storage_location_category.collection_operation.get", "@resource.storage_location_category.collection_operation.get_root", "@resource.storage_location_category.collection_operation.custom_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 @@ -0,0 +1,81 @@ +<?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/Services/CategoryService.php b/src/PartKeepr/CategoryBundle/Services/CategoryService.php @@ -47,6 +47,10 @@ class CategoryService return $rootNode; } + public function getEntityClass () { + return $this->entityClass; + } + /** * Creates the root node for a tree if it doesn't exist */ diff --git a/src/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php b/src/PartKeepr/CategoryBundle/Tests/AbstractCategoryCreateTest.php @@ -0,0 +1,68 @@ +<?php +namespace PartKeepr\CategoryBundle\Tests; + +use Doctrine\Common\DataFixtures\ProxyReferenceRepository; +use Dunglas\ApiBundle\Api\IriConverter; +use PartKeepr\CoreBundle\Tests\WebTestCase; + +abstract class AbstractCategoryCreateTest extends WebTestCase +{ + /** + * @var ProxyReferenceRepository + */ + protected $fixtures; + + public function setUp() + { + $this->fixtures = $this->loadFixtures( + array( + $this->getFixtureLoaderClass(), + ) + )->getReferenceRepository(); + } + + public function testRootCreateCateory () { + $client = static::makeClient(true); + + $request = array( + "parent" => "@local-tree-root", + "name" => "test" + ); + + /** + * @var $iriConverter IriConverter + */ + $iriConverter = $this->getContainer()->get("api.iri_converter"); + + $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->assertInternalType("object", $responseObject); + + $this->assertObjectHasAttribute("@id", $responseObject); + $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()); + } + + abstract public function getFixtureLoaderClass(); + + abstract public function getReferencePrefix(); + + abstract public function getResourceClass(); +} diff --git a/src/PartKeepr/FootprintBundle/DependencyInjection/Configuration.php b/src/PartKeepr/FootprintBundle/DependencyInjection/Configuration.php @@ -1,29 +0,0 @@ -<?php - -namespace PartKeepr\FootprintBundle\DependencyInjection; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; -use Symfony\Component\Config\Definition\ConfigurationInterface; - -/** - * This is the class that validates and merges configuration from your app/config files - * - * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} - */ -class Configuration implements ConfigurationInterface -{ - /** - * {@inheritdoc} - */ - public function getConfigTreeBuilder() - { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('part_keepr_footprint'); - - // Here you should define the parameters that are allowed to - // configure your bundle. See the documentation linked above for - // more information on that topic. - - return $treeBuilder; - } -} diff --git a/src/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php b/src/PartKeepr/FootprintBundle/DependencyInjection/PartKeeprFootprintExtension.php @@ -19,10 +19,8 @@ class PartKeeprFootprintExtension extends Extension */ public function load(array $configs, ContainerBuilder $container) { - $configuration = new Configuration(); - $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); + $loader->load('actions.xml'); } } diff --git a/src/PartKeepr/FootprintBundle/Entity/FootprintCategory.php b/src/PartKeepr/FootprintBundle/Entity/FootprintCategory.php @@ -46,7 +46,7 @@ class FootprintCategory extends AbstractCategory /** * Sets the parent category - * + * @Groups({"default"}) * @param AbstractCategory|null $parent */ public function setParent(AbstractCategory $parent = null) diff --git a/src/PartKeepr/FootprintBundle/Resources/config/actions.xml b/src/PartKeepr/FootprintBundle/Resources/config/actions.xml @@ -0,0 +1,14 @@ +<?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/FootprintBundle/Tests/CategoryCreateTest.php b/src/PartKeepr/FootprintBundle/Tests/CategoryCreateTest.php @@ -0,0 +1,23 @@ +<?php +namespace PartKeepr\FootprintBundle\Tests; + +use PartKeepr\CategoryBundle\Tests\AbstractCategoryCreateTest; + +class CategoryCreateTest extends AbstractCategoryCreateTest +{ + + public function getResourceClass() + { + return 'PartKeepr\FootprintBundle\Entity\FootprintCategory'; + } + + public function getFixtureLoaderClass() + { + return 'PartKeepr\FootprintBundle\DataFixtures\CategoryDataLoader'; + } + + public function getReferencePrefix() + { + return "footprintcategory"; + } +} diff --git a/src/PartKeepr/PartBundle/Entity/PartCategory.php b/src/PartKeepr/PartBundle/Entity/PartCategory.php @@ -42,10 +42,11 @@ class PartCategory extends AbstractCategory /** * Sets the parent category + * @Groups({"default"}) * * @param AbstractCategory|null $parent */ - public function setParent(AbstractCategory $parent = null) + public function setParent($parent = null) { $this->parent = $parent; } diff --git a/src/PartKeepr/PartBundle/Resources/config/actions.xml b/src/PartKeepr/PartBundle/Resources/config/actions.xml @@ -24,5 +24,10 @@ <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/PartBundle/Tests/CategoryCreateTest.php b/src/PartKeepr/PartBundle/Tests/CategoryCreateTest.php @@ -0,0 +1,24 @@ +<?php +namespace PartKeepr\PartBundle\Tests; + + +use PartKeepr\CategoryBundle\Tests\AbstractCategoryCreateTest; + +class CategoryCreateTest extends AbstractCategoryCreateTest +{ + + public function getResourceClass() + { + return 'PartKeepr\PartBundle\Entity\PartCategory'; + } + + public function getFixtureLoaderClass() + { + return 'PartKeepr\PartBundle\DataFixtures\CategoryDataLoader'; + } + + public function getReferencePrefix() + { + return "partcategory"; + } +} diff --git a/src/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php b/src/PartKeepr/StorageLocationBundle/DependencyInjection/PartKeeprStorageLocationExtension.php @@ -21,5 +21,6 @@ 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/Entity/StorageLocationCategory.php b/src/PartKeepr/StorageLocationBundle/Entity/StorageLocationCategory.php @@ -45,7 +45,7 @@ class StorageLocationCategory extends AbstractCategory /** * Sets the parent category - * + * @Groups({"default"}) * @param AbstractCategory|null $parent */ public function setParent(AbstractCategory $parent = null) diff --git a/src/PartKeepr/StorageLocationBundle/Resources/config/actions.xml b/src/PartKeepr/StorageLocationBundle/Resources/config/actions.xml @@ -0,0 +1,14 @@ +<?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> diff --git a/src/PartKeepr/StorageLocationBundle/Tests/CategoryCreateTest.php b/src/PartKeepr/StorageLocationBundle/Tests/CategoryCreateTest.php @@ -0,0 +1,24 @@ +<?php +namespace PartKeepr\StorageLocationBundle\Tests; + + +use PartKeepr\CategoryBundle\Tests\AbstractCategoryCreateTest; + +class CategoryCreateTest extends AbstractCategoryCreateTest +{ + + public function getResourceClass() + { + return 'PartKeepr\StorageLocationBundle\Entity\StorageLocationCategory'; + } + + public function getFixtureLoaderClass() + { + return 'PartKeepr\StorageLocationBundle\DataFixtures\CategoryDataLoader'; + } + + public function getReferencePrefix() + { + return "storagelocationcategory"; + } +}