From b001af1bbd6bcf673afd37ecf5b3739a58afd718 Mon Sep 17 00:00:00 2001 From: Daniel Bojdo Date: Mon, 5 Dec 2016 15:45:06 +0000 Subject: [PATCH] [fix] issue #2 (CustomerReference deserialisation) --- README.md | 126 ++++++++ composer.json | 16 +- examples/bootstrap.php | 9 +- phpunit.xml.dist | 18 ++ src/Model/Address.php | 44 +++ src/Model/CustomerReference.php | 11 + src/Model/Event.php | 29 ++ src/Model/ExitCode.php | 11 + src/Model/Message/AbstractResponse.php | 6 + src/Model/Message/TuDetailsResponse.php | 63 +++- ...DetailsResponseDeserialisationListener.php | 78 +++++ .../TuDetailsResponseDeserialisationTest.php | 275 ++++++++++++++++++ tests/bootstrap.php | 9 + tests/json.json | 50 ++++ 14 files changed, 739 insertions(+), 6 deletions(-) create mode 100644 README.md create mode 100644 phpunit.xml.dist create mode 100644 src/Model/Serialiser/TuDetailsResponseDeserialisationListener.php create mode 100644 tests/Model/Message/TuDetailsResponseDeserialisationTest.php create mode 100644 tests/bootstrap.php create mode 100644 tests/json.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..29c3586 --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# GLS Tracking SDK + +## Installation +### via Composer + +Add the **webit/gls-tracking** into **composer.json** + +```json +{ + "require": { + "php": ">=5.3.2", + "webit/gls-tracking": "^1.0" + } +} +``` + +## Configuration / Usage + +### API Factory preparation + +```php +use Doctrine\Common\Annotations\AnnotationRegistry; +use JMS\Serializer\EventDispatcher\EventDispatcherInterface; +use JMS\Serializer\SerializerBuilder; +use Webit\GlsTracking\Model\Serialiser\TuDetailsResponseDeserialisationListener; +use Webit\SoapApi\SoapClient\SoapClientFactory; +use Webit\GlsTracking\Api\Factory\TrackingApiFactory; +use Webit\SoapApi\Input\InputNormalizerSerializerBased; +use Webit\SoapApi\Hydrator\HydratorSerializerBased; +use Webit\GlsTracking\Api\Exception\ExceptionFactory; +use Webit\SoapApi\Util\BinaryStringHelper; +use Webit\SoapApi\SoapApiExecutorFactory; +use Webit\GlsTracking\Model\UserCredentials; + +AnnotationRegistry::registerAutoloadNamespace( + 'JMS\Serializer\Annotation', + __DIR__.'/../vendor/jms/serializer/src' +); + +$builder = SerializerBuilder::create(); +$builder->addDefaultListeners(); +$builder->configureListeners(function (EventDispatcherInterface $dispatcher) { + $dispatcher->addSubscriber(new TuDetailsResponseDeserialisationListener()); +}); +$serializer = $builder->build(); + +$clientFactory = new SoapClientFactory(); +$executorFactory = new SoapApiExecutorFactory(); +$normalizer = new InputNormalizerSerializerBased($serializer); +$hydrator = new HydratorSerializerBased($serializer, new BinaryStringHelper()); +$exceptionFactory = new ExceptionFactory(); + +$apiFactory = new TrackingApiFactory($clientFactory, $executorFactory, $normalizer, $hydrator, $exceptionFactory); + +``` + +### Tracking API + +```php + +$credentials = new UserCredentials('user', 'pass'); + +$api = $apiFactory->createTrackingApi($credentials); +$details = $api->getParcelDetails($parcelNo); + +/** @var \Webit\GlsTracking\Model\Event $event */ +printf("Details of parcel \"%s\"\n", $parcelNo); +foreach ($details->getHistory() as $event) { + printf( + "%s - Status: %s (%s), Location: %s, %s (%s)\n", + $event->getDate(), + $event->getCode(), + $event->getDescription(), + $event->getLocationName(), + $event->getCountryName(), + $event->getLocationCode() + ); +} +printf("Received by: %s\n", $details->getSignature()); + +$pod = $api->getProofOfDelivery($parcelNo); +printf("Proof of delivery filename: %s\n", $pod->getFileName()); +``` + +### Tracking Url Provider + +```php +use Webit\GlsTracking\UrlProvider\TrackingUrlProviderFactory; +$factory = new TrackingUrlProviderFactory(); + +/** @var array $config */ + +$username = 'username'; + +$urlProvider = $factory->createTrackingUrlProvider(); + +$reference = 'parcel-no'; + +$url = $urlProvider->getStandardTrackingUrl($reference, 'EN', 'EN'); + +printf("Url for tracking \"%s\" (encrypted): %s\n", $reference, $url); + +$url = $urlProvider->getEncryptedTrackingUrl($credentials, $reference, $config['language']); + +printf("Url for tracking \"%s\" (encrypted): %s\n", $reference, $url); + +$customerReference = 'customer-ref'; +$customerNo = 'customer-no'; +$url = $urlProvider->getEncryptedCustomerReferenceTrackingUrl($credentials, $customerReference, $customerNo, $config['language']); + +printf("Url for tracking \"%s\" with customer \"%s\": %s\n", $customerReference, $customerNo, $url); +``` + +### Examples + +To configure the examples: + * Copy ***examples/config.php.dist*** to ***examples/config.php*** + * Change the values accordingly + + +Run: + ```bash + php examples/details.php + php examples/url-provider.php + ``` + \ No newline at end of file diff --git a/composer.json b/composer.json index 6d0c6c9..143744b 100644 --- a/composer.json +++ b/composer.json @@ -13,10 +13,24 @@ "php": ">=5.3.3", "webit/soap-api": "~1.0" }, + "require-dev": { + "phpunit/phpunit": "^4.6.0" + }, "autoload": { "psr-4": { "Webit\\GlsTracking\\": "src/" } }, - "minimum-stability": "dev" + "autoload-dev": { + "psr-4": { + "Webit\\GlsTracking\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/examples/bootstrap.php b/examples/bootstrap.php index d48f9fe..22e4a68 100644 --- a/examples/bootstrap.php +++ b/examples/bootstrap.php @@ -2,7 +2,9 @@ require __DIR__.'/../vendor/autoload.php'; use Doctrine\Common\Annotations\AnnotationRegistry; +use JMS\Serializer\EventDispatcher\EventDispatcherInterface; use JMS\Serializer\SerializerBuilder; +use Webit\GlsTracking\Model\Serialiser\TuDetailsResponseDeserialisationListener; use Webit\SoapApi\SoapClient\SoapClientFactory; use Webit\GlsTracking\Api\Factory\TrackingApiFactory; use Webit\SoapApi\Input\InputNormalizerSerializerBased; @@ -25,7 +27,12 @@ $config = require __DIR__ .'/config.php'; -$serializer = SerializerBuilder::create()->build(); +$builder = SerializerBuilder::create(); +$builder->addDefaultListeners(); +$builder->configureListeners(function (EventDispatcherInterface $dispatcher) { + $dispatcher->addSubscriber(new TuDetailsResponseDeserialisationListener()); +}); +$serializer = $builder->build(); $clientFactory = new SoapClientFactory(); $executorFactory = new SoapApiExecutorFactory(); diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2b0f672 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + + ./tests + + + diff --git a/src/Model/Address.php b/src/Model/Address.php index e1f2188..426aeb5 100644 --- a/src/Model/Address.php +++ b/src/Model/Address.php @@ -112,6 +112,50 @@ class Address */ private $country; + /** + * Address constructor. + * @param string $name1 + * @param string $name2 + * @param string $name3 + * @param string $contactName + * @param string $street1 + * @param string $blockNo1 + * @param string $street2 + * @param string $blockNo2 + * @param string $zipCode + * @param string $city + * @param string $province + * @param string $country + */ + public function __construct( + $name1 = null, + $name2 = null, + $name3 = null, + $contactName = null, + $street1 = null, + $blockNo1 = null, + $street2 = null, + $blockNo2 = null, + $zipCode = null, + $city = null, + $province = null, + $country = null + ) { + $this->name1 = $name1; + $this->name2 = $name2; + $this->name3 = $name3; + $this->contactName = $contactName; + $this->street1 = $street1; + $this->blockNo1 = $blockNo1; + $this->street2 = $street2; + $this->blockNo2 = $blockNo2; + $this->zipCode = $zipCode; + $this->city = $city; + $this->province = $province; + $this->country = $country; + } + + /** * @return string */ diff --git a/src/Model/CustomerReference.php b/src/Model/CustomerReference.php index 6e5bee2..1fd8552 100644 --- a/src/Model/CustomerReference.php +++ b/src/Model/CustomerReference.php @@ -32,6 +32,17 @@ class CustomerReference */ private $value; + /** + * CustomerReference constructor. + * @param string $type + * @param string $value + */ + public function __construct($type = null, $value = null) + { + $this->type = $type; + $this->value = $value; + } + /** * @return string */ diff --git a/src/Model/Event.php b/src/Model/Event.php index 6ffa809..bdc7754 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -72,6 +72,35 @@ class Event */ private $reasonName; + /** + * Event constructor. + * @param DateTime $date + * @param string $locationCode + * @param string $locationName + * @param string $countryName + * @param string $code + * @param string $description + * @param string $reasonName + */ + public function __construct( + DateTime $date = null, + $locationCode = null, + $locationName = null, + $countryName = null, + $code = null, + $description = null, + $reasonName = null + ) { + $this->date = $date; + $this->locationCode = $locationCode; + $this->locationName = $locationName; + $this->countryName = $countryName; + $this->code = $code; + $this->description = $description; + $this->reasonName = $reasonName; + } + + /** * @return string */ diff --git a/src/Model/ExitCode.php b/src/Model/ExitCode.php index 096985d..eb10bc9 100644 --- a/src/Model/ExitCode.php +++ b/src/Model/ExitCode.php @@ -36,6 +36,17 @@ class ExitCode */ private $description; + /** + * ExitCode constructor. + * @param int $code + * @param string $description + */ + public function __construct($code, $description) + { + $this->code = $code; + $this->description = $description; + } + /** * @return int */ diff --git a/src/Model/Message/AbstractResponse.php b/src/Model/Message/AbstractResponse.php index 17b9aad..bc68b30 100644 --- a/src/Model/Message/AbstractResponse.php +++ b/src/Model/Message/AbstractResponse.php @@ -9,6 +9,7 @@ namespace Webit\GlsTracking\Model\Message; use JMS\Serializer\Annotation as JMS; +use Webit\GlsTracking\Model\ExitCode; /** * Class AbstractResponse @@ -24,6 +25,11 @@ abstract class AbstractResponse */ private $exitCode; + public function __construct(ExitCode $exitCode = null) + { + $this->exitCode = $exitCode; + } + public function getExitCode() { return $this->exitCode; diff --git a/src/Model/Message/TuDetailsResponse.php b/src/Model/Message/TuDetailsResponse.php index 6b53955..f606afb 100644 --- a/src/Model/Message/TuDetailsResponse.php +++ b/src/Model/Message/TuDetailsResponse.php @@ -8,9 +8,13 @@ use JMS\Serializer\Annotation as JMS; use Doctrine\Common\Collections\ArrayCollection; +use JMS\Serializer\DeserializationContext; +use JMS\Serializer\JsonDeserializationVisitor; use Webit\GlsTracking\Model\Address; use Webit\GlsTracking\Model\CustomerReference; use Webit\GlsTracking\Model\DateTime; +use Webit\GlsTracking\Model\Event; +use Webit\GlsTracking\Model\ExitCode; /** * Class TuDetailsResponse @@ -86,7 +90,7 @@ class TuDetailsResponse extends AbstractResponse * @JMS\Type("string") * @JMS\SerializedName("Services") * - * @var ArrayCollection + * @var string */ private $services; @@ -122,6 +126,57 @@ class TuDetailsResponse extends AbstractResponse */ private $signature; + /** + * TuDetailsResponse constructor. + * @param ExitCode $exitCode + * @param string $tuNo + * @param string $nationalRef + * @param Address $consigneeAddress + * @param Address $shipperAddress + * @param Address $requesterAddress + * @param DateTime $deliveryDateTime + * @param DateTime $pickupDateTime + * @param string $product + * @param string $services + * @param ArrayCollection $customerReference + * @param float $tuWeight + * @param ArrayCollection $history + * @param string $signature + */ + public function __construct( + ExitCode $exitCode = null, + $tuNo = null, + $nationalRef = null, + Address $consigneeAddress = null, + Address $shipperAddress = null, + Address $requesterAddress = null, + DateTime $deliveryDateTime = null, + DateTime $pickupDateTime = null, + $product = null, + $services = null, + ArrayCollection $customerReference = null, + $tuWeight = null, + ArrayCollection $history = null, + $signature = null + ) { + parent::__construct($exitCode); + + $this->tuNo = $tuNo; + $this->nationalRef = $nationalRef; + $this->consigneeAddress = $consigneeAddress; + $this->shipperAddress = $shipperAddress; + $this->requesterAddress = $requesterAddress; + $this->deliveryDateTime = $deliveryDateTime; + $this->pickupDateTime = $pickupDateTime; + $this->product = $product; + $this->services = $services ?: new ArrayCollection(); + $this->customerReference = $customerReference ?: new ArrayCollection(); + $this->tuWeight = $tuWeight; + $this->history = $history ?: new ArrayCollection(); + $this->signature = $signature; + } + + /** * @return Address */ @@ -131,7 +186,7 @@ public function getConsigneeAddress() } /** - * @return ArrayCollection + * @return ArrayCollection|CustomerReference[] */ public function getCustomerReference() { @@ -147,7 +202,7 @@ public function getDeliveryDateTime() } /** - * @return ArrayCollection + * @return ArrayCollection|Event[] */ public function getHistory() { @@ -187,7 +242,7 @@ public function getRequesterAddress() } /** - * @return ArrayCollection + * @return string */ public function getServices() { diff --git a/src/Model/Serialiser/TuDetailsResponseDeserialisationListener.php b/src/Model/Serialiser/TuDetailsResponseDeserialisationListener.php new file mode 100644 index 0000000..506f3dc --- /dev/null +++ b/src/Model/Serialiser/TuDetailsResponseDeserialisationListener.php @@ -0,0 +1,78 @@ + + * Created on 05/12/2016 15:20 + * Copyright (C) 8x8, Inc. + */ + +namespace Webit\GlsTracking\Model\Serialiser; + +use JMS\Serializer\EventDispatcher\EventSubscriberInterface; +use JMS\Serializer\EventDispatcher\PreDeserializeEvent; + +class TuDetailsResponseDeserialisationListener implements EventSubscriberInterface +{ + + /** + * Returns the events to which this class has subscribed. + * + * Return format: + * array( + * array('event' => 'the-event-name', 'method' => 'onEventName', 'class' => 'some-class', 'format' => 'json'), + * array(...), + * ) + * + * The class may be omitted if the class wants to subscribe to events of all classes. + * Same goes for the format key. + * + * @return array + */ + public static function getSubscribedEvents() + { + return array( + array( + 'event' => 'serializer.pre_deserialize', + 'method' => 'onPreDeserialise', + 'class' => 'Webit\GlsTracking\Model\Message\TuDetailsResponse', + 'format' => 'json' + ) + ); + } + + /** + * @param PreDeserializeEvent $event + */ + public function onPreDeserialise(PreDeserializeEvent $event) + { + $data = $event->getData(); + + if (isset($data['CustomerReference']) && is_array($data['CustomerReference'])) { + $data['CustomerReference'] = $this->ensureCollection($data['CustomerReference']); + } + + if (isset($data['History']) && is_array($data['History'])) { + $data['History'] = $this->ensureCollection($data['History']); + } + + $event->setData($data); + } + + /** + * @param array $data + * @return array + */ + private function ensureCollection(array $data) + { + if (count($data) == 0) { + return $data; + } + + if (isset($data[0])) { + return $data; + } + + return array($data); + } +} diff --git a/tests/Model/Message/TuDetailsResponseDeserialisationTest.php b/tests/Model/Message/TuDetailsResponseDeserialisationTest.php new file mode 100644 index 0000000..cabbb60 --- /dev/null +++ b/tests/Model/Message/TuDetailsResponseDeserialisationTest.php @@ -0,0 +1,275 @@ + + * Created on 05/12/2016 14:16 + * Copyright (C) 8x8, Inc. + */ + +namespace Webit\GlsTracking\Tests\Model\Message; + +use Doctrine\Common\Collections\ArrayCollection; +use JMS\Serializer\EventDispatcher\EventDispatcherInterface; +use JMS\Serializer\SerializerBuilder; +use JMS\Serializer\SerializerInterface; +use Webit\GlsTracking\Model\CustomerReference; +use Webit\GlsTracking\Model\DateTime; +use Webit\GlsTracking\Model\Event; +use Webit\GlsTracking\Model\ExitCode; +use Webit\GlsTracking\Model\Message\TuDetailsResponse; +use Webit\GlsTracking\Model\Serialiser\TuDetailsResponseDeserialisationListener; + +class TuDetailsResponseDeserialisationTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var SerializerInterface + */ + private $serialiser; + + protected function setUp() + { + $builder = SerializerBuilder::create(); + $builder->addDefaultListeners(); + $builder->configureListeners(function (EventDispatcherInterface $dispatcher) { + $dispatcher->addSubscriber(new TuDetailsResponseDeserialisationListener()); + }); + + $this->serialiser = $builder->build(); + } + + /** + * @test + * @dataProvider tuDetailsResponse + * @param string $json + * @param TuDetailsResponse $expectedResponse + */ + public function shouldDeserialiseTheTuDetailsResponse($json, TuDetailsResponse $expectedResponse) + { + $response = $this->serialiser->deserialize($json, 'Webit\GlsTracking\Model\Message\TuDetailsResponse', 'json'); + + $this->assertEquals($expectedResponse, $response); + } + + /** + * @return array + */ + public function tuDetailsResponse() + { + + return array( + array( + $this->multiplyCustomerReferenceAndHistory(), + new TuDetailsResponse( + new ExitCode(0, "OK"), + "44570818306", + "NationalRef #111", + null, + null, + null, + new DateTime(2016, 11, 17, 8, 41), + new DateTime(2016, 11, 16, 19, 51), + "ExpressParcel", + "10:00Service", + new ArrayCollection( + array( + new CustomerReference("Customer Reference Type", "23254333"), + new CustomerReference("Customer Reference Type 2", "33323254333") + ) + ), + 20.0, + new ArrayCollection( + array( + new Event( + new DateTime(2016, 11, 16, 19, 51), + "PL3000", + "Skawina", + "Poland", + "0.0", + "The parcel was handed over to GLS.", + "" + ), + new Event( + new DateTime(2016, 11, 15, 5, 51), + "PL3000", + "Skawina", + "Poland", + "0.0", + "The parcel was handed over to GLS.", + "" + ) + ) + ), + "Surname" + ) + ), + array( + $this->singleCustomerReferenceAndHistory(), + new TuDetailsResponse( + new ExitCode(0, "OK"), + "44570818306", + "NationalRef #111", + null, + null, + null, + new DateTime(2016, 11, 17, 8, 41), + new DateTime(2016, 11, 16, 19, 51), + "ExpressParcel", + "10:00Service", + new ArrayCollection( + array( + new CustomerReference("Customer Reference Type", "23254333") + ) + ), + 20.0, + new ArrayCollection( + array( + new Event( + new DateTime(2016, 11, 16, 19, 51), + "PL3000", + "Skawina", + "Poland", + "0.0", + "The parcel was handed over to GLS.", + "" + ) + ) + ), + "Surname" + ) + ), + ); + } + + private function multiplyCustomerReferenceAndHistory() + { + $json = <<