commit 9ba816194946a4a99e4d569dd73eb44ec28d8650
parent 21fecf7b66119f8d0fccc8d0e6bab4d4e2c88832
Author: Timo A. Hummel <felicitus@felicitus.org>
Date: Mon, 11 Jan 2016 16:28:46 +0100
Merge pull request #557 from partkeepr/PartKeepr-551
Fix for #551
Diffstat:
9 files changed, 201 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -1,5 +1,30 @@
# Changelog
+## PartKeepr 0.77
+
+This is mainly a bugfix release. Noteworthy bugfixes:
+
+* The HTTP Status code is now shown in exception windows for easier debugging [#549](https://github.com/partkeepr/PartKeepr/issues/549)
+* Obsolete database tables from 0.1.9 are now removed [#548](https://github.com/partkeepr/PartKeepr/issues/548)
+* Fixed drag'n'drop of parts [#540](https://github.com/partkeepr/PartKeepr/issues/540)
+* Initial stock level value is now correctly entered in the database [#534](https://github.com/partkeepr/PartKeepr/issues/534)
+* The ubuntu font is now loaded via HTTPS [#520](https://github.com/partkeepr/PartKeepr/issues/520)
+* Footprint images are now shown again [#518](https://github.com/partkeepr/PartKeepr/issues/518)
+
+For a mostly complete list of bugfixes, please refer to [GitHub](https://github.com/partkeepr/PartKeepr/issues?q=milestone%3A0.77+is%3Aclosed)
+
+## PartKeepr 0.76
+
+Noteworthy new features and bugfixes:
+
+* It is now possible to search for a manufacturer's part number [#489](https://github.com/partkeepr/PartKeepr/issues/489)
+* Re-added "used in projects", footprint, storage location and category name as in PartKeepr 0.1.9 [#514](https://github.com/partkeepr/PartKeepr/issues/514)
+* Added APC cache support
+* Setup now prompts for the authentication method to use
+* Icons are now displayed properly again in Firefox [#481](https://github.com/partkeepr/PartKeepr/issues/481)
+
+For a mostly complete list of new features and bugfixes, please refer to [GitHub](https://github.com/partkeepr/PartKeepr/issues?q=milestone%3A0.76+is%3Aclosed)
+
## PartKeepr 0.75
Noteworthy new features:
diff --git a/app/config/config_partkeepr.yml b/app/config/config_partkeepr.yml
@@ -283,11 +283,17 @@ services:
factory: [ "@api.operation_factory", "createItemOperation" ]
arguments: [ "@resource.part", "GET" ]
- resource.part.item_operation.put:
+ resource.part.item_operation.custom_put:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
public: false
factory: [ "@api.operation_factory", "createItemOperation" ]
- arguments: [ "@resource.part", "PUT" ]
+ arguments:
+ - "@resource.part"
+ - [ "PUT" ]
+ - "/parts/{id}"
+ - "partkeepr.part.put"
+ - "PartPut"
+
resource.part.item_operation.delete:
class: "Dunglas\ApiBundle\Api\Operation\Operation"
@@ -334,7 +340,7 @@ services:
tags: [ { name: "api.resource" } ]
calls:
- method: "initItemOperations"
- arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ]
+ arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.custom_put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ]
- method: "initCollectionOperations"
arguments: [ [ "@resource.part.collection_operation.get", "@resource.part.collection_operation.custom_post" ] ]
- method: "initFilters"
diff --git a/documentation/internals/NEW-RELEASE b/documentation/internals/NEW-RELEASE
@@ -2,6 +2,8 @@ The following steps describe how a new PartKeepr release is being built:
* Check if any unit tests have failed
+* Edit CHANGELOG.md within the repository
+
* Create a new GIT tag using:
git tag -s <version>
diff --git a/src/PartKeepr/PartBundle/Action/PartPutAction.php b/src/PartKeepr/PartBundle/Action/PartPutAction.php
@@ -0,0 +1,83 @@
+<?php
+namespace PartKeepr\PartBundle\Action;
+
+
+use Dunglas\ApiBundle\Action\ActionUtilTrait;
+use Dunglas\ApiBundle\Api\ResourceInterface;
+use Dunglas\ApiBundle\Exception\RuntimeException;
+use Dunglas\ApiBundle\Model\DataProviderInterface;
+use PartKeepr\AuthBundle\Exceptions\UserLimitReachedException;
+use PartKeepr\AuthBundle\Exceptions\UserProtectedException;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Serializer\SerializerInterface;
+
+class PartPutAction
+{
+ use ActionUtilTrait;
+
+ /**
+ * @var DataProviderInterface
+ */
+ private $dataProvider;
+
+ /**
+ * @var SerializerInterface
+ */
+ private $serializer;
+
+ public function __construct(
+ DataProviderInterface $dataProvider,
+ SerializerInterface $serializer
+ ) {
+ $this->dataProvider = $dataProvider;
+ $this->serializer = $serializer;
+ }
+
+ /**
+ * Create a new item.
+ *
+ * @param Request $request
+ * @param string|int $id
+ *
+ * @return mixed
+ *
+ * @throws NotFoundHttpException
+ * @throws RuntimeException
+ * @throws UserProtectedException
+ * @throws UserLimitReachedException
+ */
+ public function __invoke(Request $request, $id)
+ {
+ /**
+ * @var $resourceType ResourceInterface
+ */
+ list($resourceType, $format) = $this->extractAttributes($request);
+
+ /**
+ * Workaround to ensure stockLevels are not overwritten in a PUT request.
+ * @see https://github.com/partkeepr/PartKeepr/issues/551
+ */
+ $data = json_decode($request->getContent(), true);
+
+ if (array_key_exists("stockLevels", $data)) {
+ unset($data["stockLevels"]);
+ }
+
+ $requestData = json_encode($data);
+
+ $data = $this->getItem($this->dataProvider, $resourceType, $id);
+
+ $context = $resourceType->getDenormalizationContext();
+ $context['object_to_populate'] = $data;
+
+ $data = $this->serializer->deserialize(
+ $requestData,
+ $resourceType->getEntityClass(),
+ $format,
+ $context
+ );
+
+ return $data;
+ }
+}
diff --git a/src/PartKeepr/PartBundle/Listeners/StockLevelListener.php b/src/PartKeepr/PartBundle/Listeners/StockLevelListener.php
@@ -37,7 +37,9 @@ class StockLevelListener extends ContainerAware
}
foreach ($parts as $part) {
- $this->updateStockLevel($part, $eventArgs);
+ if ($part !== null) {
+ $this->updateStockLevel($part, $eventArgs);
+ }
}
}
diff --git a/src/PartKeepr/PartBundle/Resources/config/actions.xml b/src/PartKeepr/PartBundle/Resources/config/actions.xml
@@ -9,6 +9,10 @@
<argument type="service" id="api.serializer" />
<argument type="service" id="partkeepr.part_service" />
</service>
+ <service id="partkeepr.part.put" class="PartKeepr\PartBundle\Action\PartPutAction">
+ <argument type="service" id="api.data_provider"/>
+ <argument type="service" id="api.serializer" />
+ </service>
<service id="partkeepr.part.add_stock" class="PartKeepr\PartBundle\Action\AddStockAction">
<argument type="service" id="api.data_provider"/>
<argument type="service" id="partkeepr.userservice" />
diff --git a/src/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php b/src/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php
@@ -0,0 +1,73 @@
+<?php
+namespace PartKeepr\PartBundle\Tests\Issues;
+
+use Doctrine\Common\DataFixtures\ProxyReferenceRepository;
+use PartKeepr\CoreBundle\Tests\WebTestCase;
+use PartKeepr\PartBundle\Entity\Part;
+use PartKeepr\StockBundle\Entity\StockEntry;
+
+/**
+ * Class StockHistoryLostTest
+ *
+ * Unit test against issue #551 (stock history gets removed after saving part)
+ */
+class StockHistoryLostTest extends WebTestCase
+{
+ /**
+ * @var ProxyReferenceRepository
+ */
+ protected $fixtures;
+
+ public function setUp()
+ {
+ $this->fixtures = $this->loadFixtures(
+ array(
+ 'PartKeepr\StorageLocationBundle\DataFixtures\CategoryDataLoader',
+ 'PartKeepr\StorageLocationBundle\DataFixtures\StorageLocationLoader',
+ 'PartKeepr\PartBundle\DataFixtures\CategoryDataLoader',
+ 'PartKeepr\PartBundle\DataFixtures\PartDataLoader',
+ 'PartKeepr\AuthBundle\DataFixtures\LoadUserData',
+ 'PartKeepr\ManufacturerBundle\Tests\DataFixtures\ManufacturerDataLoader',
+ 'PartKeepr\DistributorBundle\Tests\DataFixtures\DistributorDataLoader',
+ )
+ )->getReferenceRepository();
+ }
+
+ public function testStockHistory () {
+ $client = static::makeClient(true);
+
+ /**
+ * @var $part1 Part
+ */
+ $part1 = $this->fixtures->getReference("part.1");
+
+ $stockLevel = new StockEntry();
+ $stockLevel->setPart($part1);
+ $stockLevel->setStockLevel(5);
+
+ $fosUser = $this->fixtures->getReference("user.admin");
+ $userService = $this->getContainer()->get("partkeepr.userservice");
+ $user = $userService->getProxyUser($fosUser->getUsername(), $userService->getBuiltinProvider(), true);
+
+ $stockLevel->setUser($user);
+ $part1->addStockLevel($stockLevel);
+
+ $this->getContainer()->get("doctrine.orm.default_entity_manager")->flush();
+
+ $iriCoverter = $this->getContainer()->get("api.iri_converter");
+ $iri = $iriCoverter->getIriFromItem($part1);
+
+ $client->request("GET", $iri);
+
+ $response = $client->getResponse()->getContent();
+ $responseObj = json_decode($response, true);
+ $responseObj["stockLevels"] = array();
+
+ $client->request("PUT", $iri, array(), array(), array(), json_encode($responseObj));
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $this->getContainer()->get("doctrine.orm.default_entity_manager")->refresh($part1);
+ $this->assertEquals(1, count($part1->getStockLevels()));
+ }
+}
diff --git a/src/PartKeepr/StockBundle/Entity/StockEntry.php b/src/PartKeepr/StockBundle/Entity/StockEntry.php
@@ -166,7 +166,7 @@ class StockEntry extends BaseEntity
*
* @param Part $part The part to set
*/
- public function setPart(Part $part)
+ public function setPart(Part $part = null)
{
$this->part = $part;
}
diff --git a/web/setup/js/PartKeeprSetup.js b/web/setup/js/PartKeeprSetup.js
@@ -19,7 +19,7 @@ Ext.application({
database_name: "",
database_user: "",
database_password: "",
- authentication_provider: "PartKeepr.Auth.WSSEAuthenticationProvider",
+ authentication_provider: "PartKeepr.Auth.HTTPBasicAuthenticationProvider",
locale: "en"
},
adminuser: {