From 79f805c02e9c30d8437628847df3aac2b374eb8b Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Wed, 12 Jul 2017 00:30:10 +0100 Subject: [PATCH 01/27] Initial work on adding composer + tests --- composer.json | 29 + composer.lock | 1134 ++++++++++++++++++++++++++++ phpunit.xml | 8 + AmazonAPI.php => src/AmazonAPI.php | 2 + tests/AmazonApiTest.php | 13 + 5 files changed, 1186 insertions(+) create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 phpunit.xml rename AmazonAPI.php => src/AmazonAPI.php (95%) create mode 100644 tests/AmazonApiTest.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..26c0a5b --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "marcl/amazonproductapi", + "description": "PHP library to perform product lookup and searches using the Amazon Product API.", + "version": "2.0.0", + "type": "library", + "keywords": ["amazon", "product", "api"], + "homepage": "https://github.com/MarcL/AmazonProductAPI/", + "license": "MIT", + "authors": [ + { + "name": "Marc Littlemore", + "email": "marc@marclittlemore.com", + "homepage": "http://www.marclittlemore.com", + "role": "Developer" + } + ], + "support": { + "source": "https://github.com/MarcL/AmazonProductAPI/", + "issues": "https://github.com/MarcL/AmazonProductAPI/issues" + }, + "require-dev": { + "phpunit/phpunit": "4.8.*" + }, + "autoload": { + "psr-4": { + "MarcL\\": "src/" + } + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..1fac96d --- /dev/null +++ b/composer.lock @@ -0,0 +1,1134 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "20459c2ae8a462c9a9bf336214e7cd22", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27T11:43:31+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2016-09-30T07:12:33+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-11-25T06:54:22+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2017-03-02T20:05:34+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-10-06T15:47:00+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2016-10-03T07:40:28+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-02-27T10:12:30+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.36", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-06-21T08:07:12+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2015-10-02T06:51:40+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-08-18T05:49:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-06-17T09:04:28+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-10-03T07:41:43+00:00" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21T13:59:46+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "1f93a8d19b8241617f5074a123e282575b821df8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/1f93a8d19b8241617f5074a123e282575b821df8", + "reference": "1f93a8d19b8241617f5074a123e282575b821df8", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2017-06-15T12:58:50+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23T20:04:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..89b39f2 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + ./tests/ + + + \ No newline at end of file diff --git a/AmazonAPI.php b/src/AmazonAPI.php similarity index 95% rename from AmazonAPI.php rename to src/AmazonAPI.php index 63626fc..3092677 100644 --- a/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -7,6 +7,8 @@ * */ +namespace MarcL; + class AmazonAPI { private $m_amazonUrl = ''; diff --git a/tests/AmazonApiTest.php b/tests/AmazonApiTest.php new file mode 100644 index 0000000..38acf41 --- /dev/null +++ b/tests/AmazonApiTest.php @@ -0,0 +1,13 @@ +assertEquals(0, 1); + } +} +?> \ No newline at end of file From faef39341dc5d4c91969cf0655a3d915377b1357 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Wed, 12 Jul 2017 09:46:04 +0100 Subject: [PATCH 02/27] Update to PHP 7 + new PHPUnit + tests --- composer.json | 2 +- composer.lock | 597 +++++++++++++++++++++++++++++++--------- src/AmazonAPI.php | 33 ++- tests/AmazonApiTest.php | 17 +- 4 files changed, 505 insertions(+), 144 deletions(-) diff --git a/composer.json b/composer.json index 26c0a5b..7c3e702 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "issues": "https://github.com/MarcL/AmazonProductAPI/issues" }, "require-dev": { - "phpunit/phpunit": "4.8.*" + "phpunit/phpunit": "6.1.*" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 1fac96d..950cd5b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "20459c2ae8a462c9a9bf336214e7cd22", + "content-hash": "677407d26dd1e9c0fcf31bd69cd2698c", "packages": [], "packages-dev": [ { @@ -61,6 +61,150 @@ ], "time": "2015-06-14T21:17:01+00:00" }, + { + "name": "myclabs/deep-copy", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-04-12T18:52:22+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "1.0", @@ -272,39 +416,41 @@ }, { "name": "phpunit/php-code-coverage", - "version": "2.2.4", + "version": "5.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dc421f9ca5082a0c0cb04afb171c765f79add85b", + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.11 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0", + "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" + "ext-xdebug": "^2.5", + "phpunit/phpunit": "^6.0" }, "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" + "ext-xdebug": "^2.5.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-master": "5.2.x-dev" } }, "autoload": { @@ -330,7 +476,7 @@ "testing", "xunit" ], - "time": "2015-10-06T15:47:00+00:00" + "time": "2017-04-21T08:03:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -520,41 +666,53 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.36", + "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + "reference": "42b7f394a8e009516582331b1e03a1aba40175d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/42b7f394a8e009516582331b1e03a1aba40175d1", + "reference": "42b7f394a8e009516582331b1e03a1aba40175d1", "shasum": "" }, "require": { "ext-dom": "*", "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.3", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.2", + "phpunit/php-file-iterator": "^1.4", + "phpunit/php-text-template": "^1.2", "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" + "phpunit/phpunit-mock-objects": "^4.0", + "sebastian/comparator": "^2.0", + "sebastian/diff": "^1.4.3 || ^2.0", + "sebastian/environment": "^3.0.2", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^1.1 || ^2.0", + "sebastian/object-enumerator": "^3.0.2", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" }, "suggest": { - "phpunit/php-invoker": "~1.1" + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" }, "bin": [ "phpunit" @@ -562,7 +720,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.8.x-dev" + "dev-master": "6.1.x-dev" } }, "autoload": { @@ -588,30 +746,33 @@ "testing", "xunit" ], - "time": "2017-06-21T08:07:12+00:00" + "time": "2017-05-22T07:45:30+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" + "php": "^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^3.0" + }, + "conflict": { + "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-soap": "*" @@ -619,7 +780,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -644,34 +805,79 @@ "mock", "xunit" ], - "time": "2015-10-02T06:51:40+00:00" + "time": "2017-06-30T08:15:21+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", - "version": "1.2.4", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "reference": "20f84f468cb67efee293246e6a09619b891f55f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "php": "^7.0", + "sebastian/diff": "^1.2", + "sebastian/exporter": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -708,7 +914,7 @@ "compare", "equality" ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2017-03-03T06:26:08+00:00" }, { "name": "sebastian/diff", @@ -764,28 +970,28 @@ }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -810,34 +1016,34 @@ "environment", "hhvm" ], - "time": "2016-08-18T05:49:44+00:00" + "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -877,27 +1083,27 @@ "export", "exporter" ], - "time": "2016-06-17T09:04:28+00:00" + "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -905,7 +1111,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -928,32 +1134,124 @@ "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8", + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-03-12T15:17:29+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.5", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -981,23 +1279,73 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-10-03T07:41:43+00:00" + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", - "version": "1.0.6", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, + "require": { + "php": ">=5.6" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1016,62 +1364,47 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21T13:59:46+00:00" + "time": "2016-10-03T07:35:21+00:00" }, { - "name": "symfony/yaml", - "version": "v3.3.4", + "name": "theseer/tokenizer", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "1f93a8d19b8241617f5074a123e282575b821df8" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/1f93a8d19b8241617f5074a123e282575b821df8", - "reference": "1f93a8d19b8241617f5074a123e282575b821df8", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", "shasum": "" }, "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "symfony/console": "~2.8|~3.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev" - } - }, "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2017-06-15T12:58:50+00:00" + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" }, { "name": "webmozart/assert", diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 3092677..305ddcf 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -18,15 +18,18 @@ class AmazonAPI // AWS endpoint for each locale private $m_localeTable = array( - 'ca' => 'webservices.amazon.ca/onca/xml', - 'cn' => 'webservices.amazon.cn/onca/xml', - 'de' => 'webservices.amazon.de/onca/xml', - 'es' => 'webservices.amazon.es/onca/xml', - 'fr' => 'webservices.amazon.fr/onca/xml', - 'it' => 'webservices.amazon.it/onca/xml', - 'jp' => 'webservices.amazon.jp/onca/xml', - 'uk' => 'webservices.amazon.co.uk/onca/xml', - 'us' => 'webservices.amazon.com/onca/xml', + 'br' => 'webservices.amazon.br/onca/xml', + 'ca' => 'webservices.amazon.ca/onca/xml', + 'cn' => 'webservices.amazon.cn/onca/xml', + 'fr' => 'webservices.amazon.fr/onca/xml', + 'de' => 'webservices.amazon.de/onca/xml', + 'in' => 'webservices.amazon.in/onca/xml', + 'it' => 'webservices.amazon.it/onca/xml', + 'jp' => 'webservices.amazon.jp/onca/xml', + 'mx' => 'webservices.amazon.mx/onca/xml', + 'es' => 'webservices.amazon.es/onca/xml', + 'uk' => 'webservices.amazon.co.uk/onca/xml', + 'us' => 'webservices.amazon.com/onca/xml' ); // API key ID @@ -83,8 +86,18 @@ class AmazonAPI private $mErrors = array(); - public function __construct( $keyId, $secretKey, $associateTag ) + private function throwIfNull($parameterValue, $parameterName) { + if ($parameterValue == NULL) { + throw new \Exception($parameterName . ' should be defined'); + } + } + + public function __construct($keyId, $secretKey, $associateTag) { + $this->throwIfNull($keyId, 'Amazon key ID'); + $this->throwIfNull($secretKey, 'Amazon secret key'); + $this->throwIfNull($associateTag, 'Amazon associate tag'); + // Setup the AWS credentials $this->m_keyId = $keyId; $this->m_secretKey = $secretKey; diff --git a/tests/AmazonApiTest.php b/tests/AmazonApiTest.php index 38acf41..f492195 100644 --- a/tests/AmazonApiTest.php +++ b/tests/AmazonApiTest.php @@ -4,10 +4,25 @@ use MarcL\AmazonAPI; class AmazonAPITest extends TestCase { + private $defaultKeyId = 'defaultKeyId'; + private $defaultSecretKey = 'defaultSecretKey'; + public function testShouldThrowExceptionIfMissingKeyId() { + $this->expectExceptionMessage('Amazon key ID should be defined'); + $amazonAPI = new AmazonApi(NULL, NULL, NULL); + } + + public function testShouldThrowExceptionIfMissingSecretKey() { + $this->expectExceptionMessage('Amazon secret key should be defined'); + + $amazonAPI = new AmazonApi($this->defaultKeyId, NULL, NULL); + } + + public function testShouldThrowExceptionIfMissingAssociateTag() { + $this->expectExceptionMessage('Amazon associate tag should be defined'); - $this->assertEquals(0, 1); + $amazonAPI = new AmazonApi($this->defaultKeyId, $this->defaultSecretKey, NULL); } } ?> \ No newline at end of file From 969a0919482900a616cb6de3be0f8100eb003de1 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Wed, 12 Jul 2017 19:47:41 +0100 Subject: [PATCH 03/27] Refactor request --- examples.php | 3 +- src/AmazonAPI.php | 234 +++++++++++++++++++--------------------- tests/AmazonApiTest.php | 2 +- 3 files changed, 115 insertions(+), 124 deletions(-) diff --git a/examples.php b/examples.php index 4be40e3..d67fd8b 100644 --- a/examples.php +++ b/examples.php @@ -1,7 +1,8 @@ error = curl_error($session); + } + + curl_close($session); + + if (!empty($error)) { + throw new \Exception($error); + } + + return($response); + } +} + class AmazonAPI { private $m_amazonUrl = ''; @@ -92,8 +128,7 @@ private function throwIfNull($parameterValue, $parameterName) { } } - public function __construct($keyId, $secretKey, $associateTag) - { + public function __construct($keyId, $secretKey, $associateTag) { $this->throwIfNull($keyId, 'Amazon key ID'); $this->throwIfNull($secretKey, 'Amazon secret key'); $this->throwIfNull($associateTag, 'Amazon associate tag'); @@ -104,7 +139,7 @@ public function __construct($keyId, $secretKey, $associateTag) $this->m_associateTag = $associateTag; // Set UK as locale by default - $this->SetLocale( 'uk' ); + $this->SetLocale('uk'); } /** @@ -114,8 +149,7 @@ public function __construct($keyId, $secretKey, $associateTag) * * @return None */ - public function SetSSL( $useSSL = true ) - { + public function SetSSL($useSSL = true) { $this->m_useSSL = $useSSL; } @@ -126,8 +160,7 @@ public function SetSSL( $useSSL = true ) * * @return None */ - public function SetRetrieveAsArray( $retrieveArray = true ) - { + public function SetRetrieveAsArray($retrieveArray = true) { $this->m_retrieveArray = $retrieveArray; } @@ -139,10 +172,9 @@ public function SetRetrieveAsArray( $retrieveArray = true ) * * @return None */ - public function SetLocale( $locale ) - { + public function SetLocale($locale) { // Check we have a locale in our table - if ( !array_key_exists( $locale, $this->m_localeTable ) ) + if (!array_key_exists($locale, $this->m_localeTable)) { // If not then just assume it's US $locale = 'us'; @@ -152,7 +184,7 @@ public function SetLocale( $locale ) $this->m_locale = $locale; // Check for SSL - if ( $this->m_useSSL ) + if ($this->m_useSSL) $this->m_amazonUrl = 'https://' . $this->m_localeTable[$locale]; else $this->m_amazonUrl = 'http://' . $this->m_localeTable[$locale]; @@ -165,9 +197,8 @@ public function SetLocale( $locale ) * * @return Array Array of valid string names */ - public function GetValidSearchNames() - { - return( $this->mValidSearchNames ); + public function GetValidSearchNames() { + return($this->mValidSearchNames); } /** @@ -177,38 +208,19 @@ public function GetValidSearchNames() * * @return mixed SimpleXML object or false if failure. */ - private function MakeRequest( $url ) - { - // Check if curl is installed - if ( !function_exists( 'curl_init' ) ) - { - $this->AddError( "Curl not available" ); - return( false ); - } - - // Use curl to retrieve data from Amazon - $session = curl_init( $url ); - curl_setopt( $session, CURLOPT_HEADER, false ); - curl_setopt( $session, CURLOPT_RETURNTRANSFER, true ); - $response = curl_exec( $session ); - - $error = NULL; - if ( $response === false ) - $error = curl_error( $session ); + private function MakeRequest($url) { + try { + $request = new CurlHttpRequest(); + $response = $request->execute($url); - curl_close( $session ); + $parsedXml = simplexml_load_string($response); - // Have we had an error? - if ( !empty( $error ) ) - { - $this->AddError( "Error downloading data : $url : " . $error ); - return( false ); + return($parsedXml); + } catch(\Exception $error) { + $this->AddError("Error downloading data : $url : " . $error->getMessage()); } - // Interpret data as XML - $parsedXml = simplexml_load_string( $response ); - - return( $parsedXml ); + return(false); } /** @@ -221,8 +233,7 @@ private function MakeRequest( $url ) * * @return mixed SimpleXML object, array of data or false if failure. */ - public function ItemSearch( $keywords, $searchIndex = NULL, $sortBy = NULL, $condition = 'New' ) - { + public function ItemSearch($keywords, $searchIndex = NULL, $sortBy = NULL, $condition = 'New') { // Set the values for some of the parameters. $operation = "ItemSearch"; $responseGroup = "ItemAttributes,Offers,Images"; @@ -235,39 +246,36 @@ public function ItemSearch( $keywords, $searchIndex = NULL, $sortBy = NULL, $con . "&Condition=" . $condition; // Assume we're searching in all if an index isn't passed - if ( empty( $searchIndex ) ) - { + if (empty($searchIndex)) { // Search for all $request .= "&SearchIndex=All"; } - else - { + else { // Searching for specific index $request .= "&SearchIndex=" . $searchIndex; // Set sort category - if ( $sortBy && ( $searchIndex != 'All' ) ) + if ($sortBy && ($searchIndex != 'All')) $request .= "&Sort=" . $sortBy; } // Need to sign the request now - $signedUrl = $this->GetSignedRequest( $this->m_secretKey, $request ); + $signedUrl = $this->GetSignedRequest($request); // Get the response from the signed URL - $parsedXml = $this->MakeRequest( $signedUrl ); - if ( $parsedXml === false ) - return( false ); + $parsedXml = $this->MakeRequest($signedUrl); + if ($parsedXml === false) { + return(false); + } - if ( $this->m_retrieveArray ) - { - $items = $this->RetrieveItems( $parsedXml ); + if ($this->m_retrieveArray) { + $items = $this->RetrieveItems($parsedXml); } - else - { + else { $items = $parsedXml; } - return( $items ); + return($items); } /** @@ -278,12 +286,9 @@ public function ItemSearch( $keywords, $searchIndex = NULL, $sortBy = NULL, $con * * @return mixed SimpleXML object, array of data or false if failure. */ - public function ItemLookup( $asinList, $onlyFromAmazon = false ) - { - // Check if it's an array - if ( is_array( $asinList ) ) - { - $asinList = implode( ',', $asinList ); + public function ItemLookup($asinList, $onlyFromAmazon = false) { + if (is_array($asinList)) { + $asinList = implode(',', $asinList); } // Set the values for some of the parameters. @@ -291,7 +296,7 @@ public function ItemLookup( $asinList, $onlyFromAmazon = false ) $responseGroup = "ItemAttributes,Offers,Reviews,Images,EditorialReview"; // Determine whether we just want Amazon results only or not - $merchantId = ( $onlyFromAmazon == true ) ? 'Amazon' : 'All'; + $merchantId = ($onlyFromAmazon == true) ? 'Amazon' : 'All'; $reviewSort = '-OverallRating'; //Define the request @@ -303,22 +308,21 @@ public function ItemLookup( $asinList, $onlyFromAmazon = false ) . "&MerchantId=" . $merchantId; // Need to sign the request now - $signedUrl = $this->GetSignedRequest( $this->m_secretKey, $request ); + $signedUrl = $this->GetSignedRequest($request); // Get the response from the signed URL - $parsedXml = $this->MakeRequest( $signedUrl ); - if ( $parsedXml === false ) - return( false ); + $parsedXml = $this->MakeRequest($signedUrl); + if ($parsedXml === false) { + return(false); + } - if ( $this->m_retrieveArray ) - { - $items = $this->RetrieveItems( $parsedXml ); + if ($this->m_retrieveArray) { + $items = $this->RetrieveItems($parsedXml); } - else - { + else { $items = $parsedXml; } - return( $items ); + return($items); } /** @@ -328,45 +332,38 @@ public function ItemLookup( $asinList, $onlyFromAmazon = false ) * * @return Array Array of item data. Empty array if not found */ - private function RetrieveItems( $responseXml ) - { + private function RetrieveItems($responseXml) { $items = array(); - if ( empty( $responseXml ) ) - { - $this->AddError( "No XML response found from AWS." ); - return( $items ); + if (empty($responseXml)) { + $this->AddError("No XML response found from AWS."); + return($items); } - if ( empty( $responseXml->Items ) ) - { - $this->AddError( "No items found." ); - return( $items ); + if (empty($responseXml->Items)) { + $this->AddError("No items found."); + return($items); } - if ( $responseXml->Items->Request->IsValid != 'True' ) - { + if ($responseXml->Items->Request->IsValid != 'True') { $errorCode = $responseXml->Items->Request->Errors->Error->Code; $errorMessage = $responseXml->Items->Request->Errors->Error->Message; $error = "API ERROR ($errorCode) : $errorMessage"; - $this->AddError( $error ); - return( $items ); + $this->AddError($error); + return($items); } // Get each item - foreach( $responseXml->Items->Item as $responseItem ) - { + foreach($responseXml->Items->Item as $responseItem) { $item = array(); $item['asin'] = (string) $responseItem->ASIN; $item['url'] = (string) $responseItem->DetailPageURL; - $item['rrp'] = ( (float) $responseItem->ItemAttributes->ListPrice->Amount ) / 100.0; + $item['rrp'] = ((float) $responseItem->ItemAttributes->ListPrice->Amount) / 100.0; $item['title'] = (string) $responseItem->ItemAttributes->Title; - if ( $responseItem->OfferSummary ) - { - $item['lowestPrice'] = ( (float) $responseItem->OfferSummary->LowestNewPrice->Amount ) / 100.0; + if ($responseItem->OfferSummary) { + $item['lowestPrice'] = ((float) $responseItem->OfferSummary->LowestNewPrice->Amount) / 100.0; } - else - { + else { $item['lowestPrice'] = 0.0; } @@ -375,10 +372,10 @@ private function RetrieveItems( $responseXml ) $item['mediumImage'] = (string) $responseItem->MediumImage->URL; $item['smallImage'] = (string) $responseItem->SmallImage->URL; - array_push( $items, $item ); + array_push($items, $item); } - return( $items ); + return($items); } /** @@ -388,8 +385,7 @@ private function RetrieveItems( $responseXml ) * * @return string Base URL of AWS request */ - private function GetBaseUrl() - { + private function GetBaseUrl() { //Define the request $request= $this->m_amazonUrl @@ -397,22 +393,20 @@ private function GetBaseUrl() . "&AssociateTag=" . $this->m_associateTag . "&AWSAccessKeyId=" . $this->m_keyId; - return( $request ); + return($request); } /** * This function will take an existing Amazon request and change it so that it will be usable * with the new authentication. * - * @param string $secret_key - your Amazon AWS secret key * @param string $request - your existing request URI * @param string $access_key - your Amazon AWS access key * @param string $version - (optional) the version of the service you are using * * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ */ - private function GetSignedRequest( $secret_key, $request, $access_key = false, $version = '2011-08-01') - { + private function GetSignedRequest($request, $access_key = false, $version = '2011-08-01') { // Get a nice array of elements to work with $uri_elements = parse_url($request); @@ -423,33 +417,31 @@ private function GetSignedRequest( $secret_key, $request, $access_key = false, $ parse_str($request, $parameters); // Add the new required paramters - $parameters['Timestamp'] = gmdate( "Y-m-d\TH:i:s\Z" ); + $parameters['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); $parameters['Version'] = $version; - if ( strlen($access_key) > 0 ) - { + if (strlen($access_key) > 0) { $parameters['AWSAccessKeyId'] = $access_key; } // The new authentication requirements need the keys to be sorted - ksort( $parameters ); + ksort($parameters); // Create our new request - foreach ( $parameters as $parameter => $value ) - { + foreach ($parameters as $parameter => $value) { // We need to be sure we properly encode the value of our parameter - $parameter = str_replace( "%7E", "~", rawurlencode( $parameter ) ); - $value = str_replace( "%7E", "~", rawurlencode( $value ) ); + $parameter = str_replace("%7E", "~", rawurlencode($parameter)); + $value = str_replace("%7E", "~", rawurlencode($value)); $request_array[] = $parameter . '=' . $value; } // Put our & symbol at the beginning of each of our request variables and put it in a string - $new_request = implode( '&', $request_array ); + $new_request = implode('&', $request_array); // Create our signature string $signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}"; // Create our signature using hash_hmac - $signature = urlencode( base64_encode( hash_hmac( 'sha256', $signature_string, $secret_key, true ) ) ); + $signature = urlencode(base64_encode(hash_hmac('sha256', $signature_string, $this->m_secretKey, true))); // Return our new request return "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}"; @@ -462,9 +454,8 @@ private function GetSignedRequest( $secret_key, $request, $access_key = false, $ * * @return None */ - private function AddError( $error ) - { - array_push( $this->mErrors, $error ); + private function AddError($error) { + array_push($this->mErrors, $error); } /** @@ -474,9 +465,8 @@ private function AddError( $error ) * * @return Array Array of errors. Empty array if none found */ - public function GetErrors() - { - return( $this->mErrors ); + public function GetErrors() { + return($this->mErrors); } } ?> diff --git a/tests/AmazonApiTest.php b/tests/AmazonApiTest.php index f492195..261a6aa 100644 --- a/tests/AmazonApiTest.php +++ b/tests/AmazonApiTest.php @@ -1,6 +1,6 @@ Date: Thu, 13 Jul 2017 23:56:26 +0100 Subject: [PATCH 04/27] Break out Http request code + fixup phpunit + composer autload --- composer.json | 9 +++++++-- examples.php | 4 ++-- phpunit.xml | 6 +++--- src/AmazonAPI.php | 36 +----------------------------------- src/CurlHttpRequest.php | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 src/CurlHttpRequest.php diff --git a/composer.json b/composer.json index 7c3e702..a272e73 100644 --- a/composer.json +++ b/composer.json @@ -25,5 +25,10 @@ "psr-4": { "MarcL\\": "src/" } - } -} \ No newline at end of file + }, + "autoload-dev": { + "psr-4": { + "MarcL\\": "src/", + "tests\\": "tests/" + } + }} \ No newline at end of file diff --git a/examples.php b/examples.php index d67fd8b..924232a 100644 --- a/examples.php +++ b/examples.php @@ -1,7 +1,7 @@ - + - - ./tests/ + + ./tests/ \ No newline at end of file diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 3018734..883d86e 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -9,41 +9,7 @@ namespace MarcL; -interface IHttpRequest { - public function execute($url); -} - -class CurlHttpRequest implements IHttpRequest { - private $url = NULL; - private $error = NULL; - - public function __construct() { - if (!function_exists('curl_init')) - { - throw new \Exception('Curl not found'); - } - } - - public function execute($url) { - // Use curl to retrieve data from Amazon - $session = curl_init($url); - curl_setopt($session, CURLOPT_HEADER, false); - curl_setopt($session, CURLOPT_RETURNTRANSFER, true); - $response = curl_exec($session); - - if ($response === false) { - $this->error = curl_error($session); - } - - curl_close($session); - - if (!empty($error)) { - throw new \Exception($error); - } - - return($response); - } -} +use MarcL\CurlHttpRequest; class AmazonAPI { diff --git a/src/CurlHttpRequest.php b/src/CurlHttpRequest.php new file mode 100644 index 0000000..6f4a876 --- /dev/null +++ b/src/CurlHttpRequest.php @@ -0,0 +1,41 @@ +error = curl_error($session); + } + + curl_close($session); + + if (!empty($error)) { + throw new \Exception($error); + } + + return($response); + } +} + +?> \ No newline at end of file From c74563caebd80abc71006bb091ad1d162883494b Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:19:00 +0100 Subject: [PATCH 05/27] Refactor out signed URL builder --- src/AmazonAPI.php | 44 ++++---------------------------------------- 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 883d86e..28f94f2 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -10,6 +10,7 @@ namespace MarcL; use MarcL\CurlHttpRequest; +use MarcL\AmazonUrlBuilder; class AmazonAPI { @@ -367,50 +368,13 @@ private function GetBaseUrl() { * with the new authentication. * * @param string $request - your existing request URI - * @param string $access_key - your Amazon AWS access key - * @param string $version - (optional) the version of the service you are using * * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ */ - private function GetSignedRequest($request, $access_key = false, $version = '2011-08-01') { - // Get a nice array of elements to work with - $uri_elements = parse_url($request); + private function GetSignedRequest($request) { + $urlBuilder = new AmazonUrlBuilder($request, $this->m_secretKey); - // Grab our request elements - $request = $uri_elements['query']; - - // Throw them into an array - parse_str($request, $parameters); - - // Add the new required paramters - $parameters['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); - $parameters['Version'] = $version; - if (strlen($access_key) > 0) { - $parameters['AWSAccessKeyId'] = $access_key; - } - - // The new authentication requirements need the keys to be sorted - ksort($parameters); - - // Create our new request - foreach ($parameters as $parameter => $value) { - // We need to be sure we properly encode the value of our parameter - $parameter = str_replace("%7E", "~", rawurlencode($parameter)); - $value = str_replace("%7E", "~", rawurlencode($value)); - $request_array[] = $parameter . '=' . $value; - } - - // Put our & symbol at the beginning of each of our request variables and put it in a string - $new_request = implode('&', $request_array); - - // Create our signature string - $signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}"; - - // Create our signature using hash_hmac - $signature = urlencode(base64_encode(hash_hmac('sha256', $signature_string, $this->m_secretKey, true))); - - // Return our new request - return "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}"; + return($urlBuilder->get()); } /** From 2434ae3e593bc1628216cac66025fe78951376ea Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:19:07 +0100 Subject: [PATCH 06/27] Refactor out signed URL builder --- src/AmazonUrlBuilder.php | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/AmazonUrlBuilder.php diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php new file mode 100644 index 0000000..a761d85 --- /dev/null +++ b/src/AmazonUrlBuilder.php @@ -0,0 +1,71 @@ +secretKey = $secretKey; + $this->url = $this->GetSignedRequest($url); + } + + /** + * This function will take an existing Amazon request and change it so that it will be usable + * with the new authentication. + * + * @param string $request - your existing request URI + * @param string $access_key - your Amazon AWS access key + * @param string $version - (optional) the version of the service you are using + * + * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ + */ + private function GetSignedRequest($request, $access_key = false, $version = '2011-08-01') { + // Get a nice array of elements to work with + $uri_elements = parse_url($request); + + // Grab our request elements + $request = $uri_elements['query']; + + // Throw them into an array + parse_str($request, $parameters); + + // Add the new required paramters + $parameters['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); + $parameters['Version'] = $version; + if (strlen($access_key) > 0) { + $parameters['AWSAccessKeyId'] = $access_key; + } + + // The new authentication requirements need the keys to be sorted + ksort($parameters); + + // Create our new request + foreach ($parameters as $parameter => $value) { + // We need to be sure we properly encode the value of our parameter + $parameter = str_replace("%7E", "~", rawurlencode($parameter)); + $value = str_replace("%7E", "~", rawurlencode($value)); + $request_array[] = $parameter . '=' . $value; + } + + // Put our & symbol at the beginning of each of our request variables and put it in a string + $new_request = implode('&', $request_array); + + // Create our signature string + $signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}"; + + // Create our signature using hash_hmac + $signature = urlencode(base64_encode(hash_hmac('sha256', $signature_string, $this->secretKey, true))); + + // Return our new request + $newUrl = "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}"; + return $newUrl; + } + + public function get() { + return($this->url); + } +} + +?> \ No newline at end of file From 18090c9031a8b610baf0759d6541687e4b28851c Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:23:56 +0100 Subject: [PATCH 07/27] Generate the url with function (for refactoring) --- src/AmazonAPI.php | 2 +- src/AmazonUrlBuilder.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 28f94f2..172d6b7 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -374,7 +374,7 @@ private function GetBaseUrl() { private function GetSignedRequest($request) { $urlBuilder = new AmazonUrlBuilder($request, $this->m_secretKey); - return($urlBuilder->get()); + return($urlBuilder->generate()); } /** diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index a761d85..baabbc3 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -8,7 +8,7 @@ class AmazonUrlBuilder { public function __construct($url, $secretKey) { $this->secretKey = $secretKey; - $this->url = $this->GetSignedRequest($url); + $this->url = $url; } /** @@ -63,8 +63,8 @@ private function GetSignedRequest($request, $access_key = false, $version = '201 return $newUrl; } - public function get() { - return($this->url); + public function generate() { + return($this->GetSignedRequest($this->url)); } } From 587f5f30499128142a8d3c6eaef69eabaa4a8b0f Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:29:08 +0100 Subject: [PATCH 08/27] Refactor duplicated code --- src/AmazonAPI.php | 57 ++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 172d6b7..d8c4e70 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -176,20 +176,38 @@ public function GetValidSearchNames() { * @return mixed SimpleXML object or false if failure. */ private function MakeRequest($url) { + $signedUrl = $this->GetSignedRequest($url); + try { $request = new CurlHttpRequest(); - $response = $request->execute($url); + $response = $request->execute($signedUrl); $parsedXml = simplexml_load_string($response); return($parsedXml); } catch(\Exception $error) { - $this->AddError("Error downloading data : $url : " . $error->getMessage()); + $this->AddError("Error downloading data : $signedUrl : " . $error->getMessage()); } return(false); } + private function MakeAndParseRequest($url) { + $parsedXml = $this->MakeRequest($url); + if ($parsedXml === false) { + return(false); + } + + if ($this->m_retrieveArray) { + $items = $this->RetrieveItems($parsedXml); + } + else { + $items = $parsedXml; + } + + return($items); + } + /** * Search for items * @@ -226,23 +244,7 @@ public function ItemSearch($keywords, $searchIndex = NULL, $sortBy = NULL, $cond $request .= "&Sort=" . $sortBy; } - // Need to sign the request now - $signedUrl = $this->GetSignedRequest($request); - - // Get the response from the signed URL - $parsedXml = $this->MakeRequest($signedUrl); - if ($parsedXml === false) { - return(false); - } - - if ($this->m_retrieveArray) { - $items = $this->RetrieveItems($parsedXml); - } - else { - $items = $parsedXml; - } - - return($items); + return($this->MakeAndParseRequest($request)); } /** @@ -274,22 +276,7 @@ public function ItemLookup($asinList, $onlyFromAmazon = false) { . "&ReviewSort=" . $reviewSort . "&MerchantId=" . $merchantId; - // Need to sign the request now - $signedUrl = $this->GetSignedRequest($request); - - // Get the response from the signed URL - $parsedXml = $this->MakeRequest($signedUrl); - if ($parsedXml === false) { - return(false); - } - - if ($this->m_retrieveArray) { - $items = $this->RetrieveItems($parsedXml); - } - else { - $items = $parsedXml; - } - return($items); + return($this->MakeAndParseRequest($request)); } /** From f7c22b94fe9929c165dcf18d6e21676d5407cfc8 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:49:15 +0100 Subject: [PATCH 09/27] Remove unused access key from URL builder --- src/AmazonUrlBuilder.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index baabbc3..07282b9 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -16,12 +16,11 @@ public function __construct($url, $secretKey) { * with the new authentication. * * @param string $request - your existing request URI - * @param string $access_key - your Amazon AWS access key * @param string $version - (optional) the version of the service you are using * * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ */ - private function GetSignedRequest($request, $access_key = false, $version = '2011-08-01') { + private function GetSignedRequest($request, $version = '2011-08-01') { // Get a nice array of elements to work with $uri_elements = parse_url($request); @@ -34,9 +33,6 @@ private function GetSignedRequest($request, $access_key = false, $version = '201 // Add the new required paramters $parameters['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z"); $parameters['Version'] = $version; - if (strlen($access_key) > 0) { - $parameters['AWSAccessKeyId'] = $access_key; - } // The new authentication requirements need the keys to be sorted ksort($parameters); From 3199ae17fb75414ecb84f10ea95f927b43820bab Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:49:30 +0100 Subject: [PATCH 10/27] Refactor URL creation --- src/AmazonAPI.php | 94 ++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index d8c4e70..6d3ffb7 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -208,6 +208,28 @@ private function MakeAndParseRequest($url) { return($items); } + /** + * Creates an unsigned Amazon URL + * + * @param params Array of request parameters + * + * @return string Unsigned URL of AWS request + */ + private function CreateUnsignedAmazonUrl($params) { + $baseParams = array( + 'Service' => 'AWSECommerceService', + 'AssociateTag' => $this->m_associateTag, + 'AWSAccessKeyId' => $this->m_keyId + ); + + $buildParams = array_merge($baseParams, $params); + + $request = $this->m_amazonUrl . '?' .http_build_query($buildParams); + + return($request); + + } + /** * Search for items * @@ -219,30 +241,16 @@ private function MakeAndParseRequest($url) { * @return mixed SimpleXML object, array of data or false if failure. */ public function ItemSearch($keywords, $searchIndex = NULL, $sortBy = NULL, $condition = 'New') { - // Set the values for some of the parameters. - $operation = "ItemSearch"; - $responseGroup = "ItemAttributes,Offers,Images"; - - //Define the request - $request= $this->GetBaseUrl() - . "&Operation=" . $operation - . "&Keywords=" . $keywords - . "&ResponseGroup=" . $responseGroup - . "&Condition=" . $condition; - - // Assume we're searching in all if an index isn't passed - if (empty($searchIndex)) { - // Search for all - $request .= "&SearchIndex=All"; - } - else { - // Searching for specific index - $request .= "&SearchIndex=" . $searchIndex; + $params = array( + 'Operation' => 'ItemSearch', + 'ResponseGroup' => 'ItemAttributes,Offers,Images', + 'Keywords' => $keywords, + 'Condition' => $condition, + 'SearchIndex' => empty($searchIndex) ? 'All' : $searchIndex, + 'Sort' => $sortBy && ($searchIndex != 'All') ? $sortBy : NULL + ); - // Set sort category - if ($sortBy && ($searchIndex != 'All')) - $request .= "&Sort=" . $sortBy; - } + $request = $this->CreateUnsignedAmazonUrl($params); return($this->MakeAndParseRequest($request)); } @@ -260,21 +268,15 @@ public function ItemLookup($asinList, $onlyFromAmazon = false) { $asinList = implode(',', $asinList); } - // Set the values for some of the parameters. - $operation = "ItemLookup"; - $responseGroup = "ItemAttributes,Offers,Reviews,Images,EditorialReview"; - - // Determine whether we just want Amazon results only or not - $merchantId = ($onlyFromAmazon == true) ? 'Amazon' : 'All'; + $params = array( + 'Operation' => 'ItemLookup', + 'ResponseGroup' => 'ItemAttributes,Offers,Reviews,Images,EditorialReview', + 'ReviewSort' => '-OverallRating', + 'ItemId' => $asinList, + 'MerchantId' => ($onlyFromAmazon == true) ? 'Amazon' : 'All' + ); - $reviewSort = '-OverallRating'; - //Define the request - $request = $this->GetBaseUrl() - . "&ItemId=" . $asinList - . "&Operation=" . $operation - . "&ResponseGroup=" . $responseGroup - . "&ReviewSort=" . $reviewSort - . "&MerchantId=" . $merchantId; + $request = $this->CreateUnsignedAmazonUrl($params); return($this->MakeAndParseRequest($request)); } @@ -332,24 +334,6 @@ private function RetrieveItems($responseXml) { return($items); } - /** - * Determines the base address of the request - * - * @param None - * - * @return string Base URL of AWS request - */ - private function GetBaseUrl() { - //Define the request - $request= - $this->m_amazonUrl - . "?Service=AWSECommerceService" - . "&AssociateTag=" . $this->m_associateTag - . "&AWSAccessKeyId=" . $this->m_keyId; - - return($request); - } - /** * This function will take an existing Amazon request and change it so that it will be usable * with the new authentication. From 8a28802fb4586da0e0600236bc450b65c7f3a984 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:50:52 +0100 Subject: [PATCH 11/27] Clarify name --- src/AmazonAPI.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 6d3ffb7..5bbe62e 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -168,14 +168,7 @@ public function GetValidSearchNames() { return($this->mValidSearchNames); } - /** - * Return data from AWS - * - * @param url URL request - * - * @return mixed SimpleXML object or false if failure. - */ - private function MakeRequest($url) { + private function MakeSignedRequest($url) { $signedUrl = $this->GetSignedRequest($url); try { @@ -193,7 +186,7 @@ private function MakeRequest($url) { } private function MakeAndParseRequest($url) { - $parsedXml = $this->MakeRequest($url); + $parsedXml = $this->MakeSignedRequest($url); if ($parsedXml === false) { return(false); } From 507dd2a3b29d9412aaa5923af1b5f790040e36e6 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 00:54:49 +0100 Subject: [PATCH 12/27] Remove shoddy comments + little refactor --- src/AmazonAPI.php | 67 ++--------------------------------------------- 1 file changed, 2 insertions(+), 65 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 5bbe62e..61adc6e 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -109,36 +109,14 @@ public function __construct($keyId, $secretKey, $associateTag) { $this->SetLocale('uk'); } - /** - * Enable or disable SSL endpoints - * - * @param useSSL True if using SSL, false otherwise - * - * @return None - */ public function SetSSL($useSSL = true) { $this->m_useSSL = $useSSL; } - /** - * Enable or disable retrieving items array rather than XML - * - * @param retrieveArray True if retrieving as array, false otherwise. - * - * @return None - */ public function SetRetrieveAsArray($retrieveArray = true) { $this->m_retrieveArray = $retrieveArray; } - /** - * Sets the locale for the endpoints - * - * @param locale Set to a valid AWS locale - see link below. - * @link http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Locales.html - * - * @return None - */ public function SetLocale($locale) { // Check we have a locale in our table if (!array_key_exists($locale, $this->m_localeTable)) @@ -157,19 +135,13 @@ public function SetLocale($locale) { $this->m_amazonUrl = 'http://' . $this->m_localeTable[$locale]; } - /** - * Return valid search names - * - * @param None - * - * @return Array Array of valid string names - */ public function GetValidSearchNames() { return($this->mValidSearchNames); } private function MakeSignedRequest($url) { - $signedUrl = $this->GetSignedRequest($url); + $urlBuilder = new AmazonUrlBuilder($url, $this->m_secretKey); + $signedUrl = $urlBuilder->generate(); try { $request = new CurlHttpRequest(); @@ -201,13 +173,6 @@ private function MakeAndParseRequest($url) { return($items); } - /** - * Creates an unsigned Amazon URL - * - * @param params Array of request parameters - * - * @return string Unsigned URL of AWS request - */ private function CreateUnsignedAmazonUrl($params) { $baseParams = array( 'Service' => 'AWSECommerceService', @@ -327,38 +292,10 @@ private function RetrieveItems($responseXml) { return($items); } - /** - * This function will take an existing Amazon request and change it so that it will be usable - * with the new authentication. - * - * @param string $request - your existing request URI - * - * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ - */ - private function GetSignedRequest($request) { - $urlBuilder = new AmazonUrlBuilder($request, $this->m_secretKey); - - return($urlBuilder->generate()); - } - - /** - * Adds error to an error array - * - * @param error Error string - * - * @return None - */ private function AddError($error) { array_push($this->mErrors, $error); } - /** - * Returns array of errors - * - * @param None - * - * @return Array Array of errors. Empty array if none found - */ public function GetErrors() { return($this->mErrors); } From 1a9d18131fadb2ce83ee1a94206286aea315ed49 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 01:01:09 +0100 Subject: [PATCH 13/27] Update version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a272e73..a28e5db 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "marcl/amazonproductapi", "description": "PHP library to perform product lookup and searches using the Amazon Product API.", - "version": "2.0.0", + "version": "3.0.0", "type": "library", "keywords": ["amazon", "product", "api"], "homepage": "https://github.com/MarcL/AmazonProductAPI/", From a4c346f80874afa39c25415e73be1d8b6396bbab Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 08:31:58 +0100 Subject: [PATCH 14/27] More refactoring --- examples.php | 2 +- src/AmazonAPI.php | 79 ++++++---------------------------------- src/AmazonUrlBuilder.php | 53 ++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 73 deletions(-) diff --git a/examples.php b/examples.php index 924232a..44a2f91 100644 --- a/examples.php +++ b/examples.php @@ -24,7 +24,7 @@ print('>> Harry Potter in Books, sort by price low to high'); var_dump($items); -// Harry Potter in Books, sort by price high to low +// // Harry Potter in Books, sort by price high to low $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); print('>> Harry Potter in Books, sort by price high to low'); var_dump($items); diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 61adc6e..6b8611e 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -14,34 +14,11 @@ class AmazonAPI { - private $m_amazonUrl = ''; private $m_locale = 'uk'; private $m_retrieveArray = false; - private $m_useSSL = true; - - // AWS endpoint for each locale - private $m_localeTable = array( - 'br' => 'webservices.amazon.br/onca/xml', - 'ca' => 'webservices.amazon.ca/onca/xml', - 'cn' => 'webservices.amazon.cn/onca/xml', - 'fr' => 'webservices.amazon.fr/onca/xml', - 'de' => 'webservices.amazon.de/onca/xml', - 'in' => 'webservices.amazon.in/onca/xml', - 'it' => 'webservices.amazon.it/onca/xml', - 'jp' => 'webservices.amazon.jp/onca/xml', - 'mx' => 'webservices.amazon.mx/onca/xml', - 'es' => 'webservices.amazon.es/onca/xml', - 'uk' => 'webservices.amazon.co.uk/onca/xml', - 'us' => 'webservices.amazon.com/onca/xml' - ); - // API key ID private $m_keyId = NULL; - - // API Secret Key private $m_secretKey = NULL; - - // AWS associate tag private $m_associateTag = NULL; // Valid names that can be used for search @@ -109,39 +86,26 @@ public function __construct($keyId, $secretKey, $associateTag) { $this->SetLocale('uk'); } - public function SetSSL($useSSL = true) { - $this->m_useSSL = $useSSL; - } - public function SetRetrieveAsArray($retrieveArray = true) { $this->m_retrieveArray = $retrieveArray; } public function SetLocale($locale) { - // Check we have a locale in our table - if (!array_key_exists($locale, $this->m_localeTable)) - { - // If not then just assume it's US - $locale = 'us'; - } - - // Set the URL for this locale $this->m_locale = $locale; - - // Check for SSL - if ($this->m_useSSL) - $this->m_amazonUrl = 'https://' . $this->m_localeTable[$locale]; - else - $this->m_amazonUrl = 'http://' . $this->m_localeTable[$locale]; } public function GetValidSearchNames() { return($this->mValidSearchNames); } - private function MakeSignedRequest($url) { - $urlBuilder = new AmazonUrlBuilder($url, $this->m_secretKey); - $signedUrl = $urlBuilder->generate(); + private function MakeSignedRequest($params) { + $urlBuilder = new AmazonUrlBuilder( + $this->m_keyId, + $this->m_secretKey, + $this->m_associateTag, + $this->m_locale + ); + $signedUrl = $urlBuilder->generate($params); try { $request = new CurlHttpRequest(); @@ -157,8 +121,8 @@ private function MakeSignedRequest($url) { return(false); } - private function MakeAndParseRequest($url) { - $parsedXml = $this->MakeSignedRequest($url); + private function MakeAndParseRequest($params) { + $parsedXml = $this->MakeSignedRequest($params); if ($parsedXml === false) { return(false); } @@ -173,21 +137,6 @@ private function MakeAndParseRequest($url) { return($items); } - private function CreateUnsignedAmazonUrl($params) { - $baseParams = array( - 'Service' => 'AWSECommerceService', - 'AssociateTag' => $this->m_associateTag, - 'AWSAccessKeyId' => $this->m_keyId - ); - - $buildParams = array_merge($baseParams, $params); - - $request = $this->m_amazonUrl . '?' .http_build_query($buildParams); - - return($request); - - } - /** * Search for items * @@ -208,9 +157,7 @@ public function ItemSearch($keywords, $searchIndex = NULL, $sortBy = NULL, $cond 'Sort' => $sortBy && ($searchIndex != 'All') ? $sortBy : NULL ); - $request = $this->CreateUnsignedAmazonUrl($params); - - return($this->MakeAndParseRequest($request)); + return($this->MakeAndParseRequest($params)); } /** @@ -234,9 +181,7 @@ public function ItemLookup($asinList, $onlyFromAmazon = false) { 'MerchantId' => ($onlyFromAmazon == true) ? 'Amazon' : 'All' ); - $request = $this->CreateUnsignedAmazonUrl($params); - - return($this->MakeAndParseRequest($request)); + return($this->MakeAndParseRequest($params)); } /** diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index 07282b9..9fbe5c8 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -3,14 +3,55 @@ namespace MarcL; class AmazonUrlBuilder { - private $url = NULL; private $secretKey = NULL; + private $keyId = NULL; + private $associateTag = NULL; + private $amazonTld = NULL; - public function __construct($url, $secretKey) { + private $localeTable = array( + 'br' => 'webservices.amazon.br/onca/xml', + 'ca' => 'webservices.amazon.ca/onca/xml', + 'cn' => 'webservices.amazon.cn/onca/xml', + 'fr' => 'webservices.amazon.fr/onca/xml', + 'de' => 'webservices.amazon.de/onca/xml', + 'in' => 'webservices.amazon.in/onca/xml', + 'it' => 'webservices.amazon.it/onca/xml', + 'jp' => 'webservices.amazon.jp/onca/xml', + 'mx' => 'webservices.amazon.mx/onca/xml', + 'es' => 'webservices.amazon.es/onca/xml', + 'uk' => 'webservices.amazon.co.uk/onca/xml', + 'us' => 'webservices.amazon.com/onca/xml' + ); + + public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { $this->secretKey = $secretKey; - $this->url = $url; + $this->amazonTld = $this->GetAmazonApiEndpoint($locale); + $this->associateTag = $associateTag; + $this->keyId = $keyId; } + private function GetAmazonApiEndpoint($locale) { + if (!array_key_exists($locale, $this->localeTable)) { + $locale = 'us'; + } + + return('https://' . $this->localeTable[$locale]); + } + + private function CreateUnsignedAmazonUrl($params) { + $baseParams = array( + 'Service' => 'AWSECommerceService', + 'AssociateTag' => $this->associateTag, + 'AWSAccessKeyId' => $this->keyId + ); + + $buildParams = array_merge($baseParams, $params); + + $request = $this->amazonTld . '?' .http_build_query($buildParams); + + return($request); + } + /** * This function will take an existing Amazon request and change it so that it will be usable * with the new authentication. @@ -59,8 +100,10 @@ private function GetSignedRequest($request, $version = '2011-08-01') { return $newUrl; } - public function generate() { - return($this->GetSignedRequest($this->url)); + public function generate($params) { + $unsignedRequest = $this->CreateUnsignedAmazonUrl($params); + + return($this->GetSignedRequest($unsignedRequest)); } } From b4937451fbac08429c9aa366af440119b35c603a Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Fri, 14 Jul 2017 17:06:19 +0100 Subject: [PATCH 15/27] Refactor --- README.md | 22 ++++------------------ examples.php | 4 +--- src/AmazonAPI.php | 36 ++++++++++++++---------------------- 3 files changed, 19 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 52d7447..12c917d 100644 --- a/README.md +++ b/README.md @@ -45,20 +45,16 @@ $keyId = 'YOUR-AWS-KEY'; $secretKey = 'YOUR-AWS-SECRET-KEY'; $associateId = 'YOUR-AMAZON-ASSOCIATE-ID'; -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId); +$locale = 'us'; // Default is 'uk' + +$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId, $locale); ``` **Note:** Keep your Amazon keys safe. Either use environment variables or include from a file that you don't check into GitHub. ### Locale -This library supports all [Product Advertising API locales](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Locales.html) and you can set them using `SetLocale`: - -It defaults to US but to set the locale call `SetLocale()` __before__ calling the product methods. E.g. - -```php -$amazonAPI->SetLocale('uk'); -``` +This library supports all [Product Advertising API locales](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Locales.html) and you can set it as you construct the class. At this time, these are the current supported locales: @@ -75,16 +71,6 @@ At this time, these are the current supported locales: * United Kingdom ('uk') * United States ('us') -### SSL - -By default it will use HTTPS, but if you don't want to use SSL then call the following before using the product methods and it will connect to the HTTP endpoints: - -```php -$amazonAPI->SetSSL(false); -``` - -**Note:** I have no idea why I originally had this method. Perhaps the Amazon Product API didn't use SSL at one point. I've enabled HTTPS as default now but you can turn it off if you need to. I assume you won't need to but I've left it in the API. - ### Item Search To search for an item use the `ItemSearch()` method: diff --git a/examples.php b/examples.php index 44a2f91..41ec59c 100644 --- a/examples.php +++ b/examples.php @@ -8,9 +8,7 @@ include_once('./secretKeys.php'); // Setup a new instance of the AmazonAPI with your keys -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId); -$amazonAPI->SetLocale('uk'); -$amazonAPI->SetSSL(true); +$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId, 'uk'); $amazonAPI->SetRetrieveAsArray(); // Item Search: diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 6b8611e..7f45e53 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -20,6 +20,7 @@ class AmazonAPI private $m_keyId = NULL; private $m_secretKey = NULL; private $m_associateTag = NULL; + private $urlBuilder = NULL; // Valid names that can be used for search private $mValidSearchNames = array( @@ -72,7 +73,7 @@ private function throwIfNull($parameterValue, $parameterName) { } } - public function __construct($keyId, $secretKey, $associateTag) { + public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { $this->throwIfNull($keyId, 'Amazon key ID'); $this->throwIfNull($secretKey, 'Amazon secret key'); $this->throwIfNull($associateTag, 'Amazon associate tag'); @@ -81,31 +82,26 @@ public function __construct($keyId, $secretKey, $associateTag) { $this->m_keyId = $keyId; $this->m_secretKey = $secretKey; $this->m_associateTag = $associateTag; + $this->m_locale = $locale; - // Set UK as locale by default - $this->SetLocale('uk'); + $this->urlBuilder = new AmazonUrlBuilder( + $this->m_keyId, + $this->m_secretKey, + $this->m_associateTag, + $this->m_locale + ); } public function SetRetrieveAsArray($retrieveArray = true) { $this->m_retrieveArray = $retrieveArray; } - public function SetLocale($locale) { - $this->m_locale = $locale; - } - public function GetValidSearchNames() { return($this->mValidSearchNames); } private function MakeSignedRequest($params) { - $urlBuilder = new AmazonUrlBuilder( - $this->m_keyId, - $this->m_secretKey, - $this->m_associateTag, - $this->m_locale - ); - $signedUrl = $urlBuilder->generate($params); + $signedUrl = $this->urlBuilder->generate($params); try { $request = new CurlHttpRequest(); @@ -127,14 +123,10 @@ private function MakeAndParseRequest($params) { return(false); } - if ($this->m_retrieveArray) { - $items = $this->RetrieveItems($parsedXml); - } - else { - $items = $parsedXml; - } - - return($items); + return($this->m_retrieveArray + ? $this->RetrieveItems($parsedXml) + : $parsedXml + ); } /** From 94b5606eb53f84fbfc6671eb5c77ac65eab481ee Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 16:03:50 +0100 Subject: [PATCH 16/27] Refactor data transformation --- examples.php | 2 +- src/AmazonAPI.php | 76 ++++----------------- src/Transformers/ArrayTransformer.php | 20 ++++++ src/Transformers/IDataTransformer.php | 9 +++ src/Transformers/JsonTransformer.php | 19 ++++++ src/Transformers/SimpleArrayTransformer.php | 60 ++++++++++++++++ src/Transformers/XmlDecorator.php | 19 ++++++ 7 files changed, 141 insertions(+), 64 deletions(-) create mode 100644 src/Transformers/ArrayTransformer.php create mode 100644 src/Transformers/IDataTransformer.php create mode 100644 src/Transformers/JsonTransformer.php create mode 100644 src/Transformers/SimpleArrayTransformer.php create mode 100644 src/Transformers/XmlDecorator.php diff --git a/examples.php b/examples.php index 41ec59c..93efd90 100644 --- a/examples.php +++ b/examples.php @@ -22,7 +22,7 @@ print('>> Harry Potter in Books, sort by price low to high'); var_dump($items); -// // Harry Potter in Books, sort by price high to low +// Harry Potter in Books, sort by price high to low $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); print('>> Harry Potter in Books, sort by price high to low'); var_dump($items); diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 7f45e53..d5a518b 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -11,6 +11,8 @@ use MarcL\CurlHttpRequest; use MarcL\AmazonUrlBuilder; +use MarcL\Transformers\SimpleArrayTransformer; +use MarcL\Transformers\XmlTransformer; class AmazonAPI { @@ -93,11 +95,11 @@ public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { } public function SetRetrieveAsArray($retrieveArray = true) { - $this->m_retrieveArray = $retrieveArray; + $this->m_retrieveArray = $retrieveArray; } public function GetValidSearchNames() { - return($this->mValidSearchNames); + return $this->mValidSearchNames; } private function MakeSignedRequest($params) { @@ -114,7 +116,7 @@ private function MakeSignedRequest($params) { $this->AddError("Error downloading data : $signedUrl : " . $error->getMessage()); } - return(false); + return false; } private function MakeAndParseRequest($params) { @@ -123,10 +125,11 @@ private function MakeAndParseRequest($params) { return(false); } - return($this->m_retrieveArray - ? $this->RetrieveItems($parsedXml) - : $parsedXml - ); + $dataTransformer = $this->m_retrieveArray + ? new SimpleArrayTransformer($parsedXml) + : new XmlTransformer($parsedXml); + + return $dataTransformer->execute(); } /** @@ -149,7 +152,7 @@ public function ItemSearch($keywords, $searchIndex = NULL, $sortBy = NULL, $cond 'Sort' => $sortBy && ($searchIndex != 'All') ? $sortBy : NULL ); - return($this->MakeAndParseRequest($params)); + return $this->MakeAndParseRequest($params); } /** @@ -173,60 +176,7 @@ public function ItemLookup($asinList, $onlyFromAmazon = false) { 'MerchantId' => ($onlyFromAmazon == true) ? 'Amazon' : 'All' ); - return($this->MakeAndParseRequest($params)); - } - - /** - * Basic method to retrieve only requested item data as an array - * - * @param responseXML XML data to be passed - * - * @return Array Array of item data. Empty array if not found - */ - private function RetrieveItems($responseXml) { - $items = array(); - if (empty($responseXml)) { - $this->AddError("No XML response found from AWS."); - return($items); - } - - if (empty($responseXml->Items)) { - $this->AddError("No items found."); - return($items); - } - - if ($responseXml->Items->Request->IsValid != 'True') { - $errorCode = $responseXml->Items->Request->Errors->Error->Code; - $errorMessage = $responseXml->Items->Request->Errors->Error->Message; - $error = "API ERROR ($errorCode) : $errorMessage"; - $this->AddError($error); - return($items); - } - - // Get each item - foreach($responseXml->Items->Item as $responseItem) { - $item = array(); - $item['asin'] = (string) $responseItem->ASIN; - $item['url'] = (string) $responseItem->DetailPageURL; - $item['rrp'] = ((float) $responseItem->ItemAttributes->ListPrice->Amount) / 100.0; - $item['title'] = (string) $responseItem->ItemAttributes->Title; - - if ($responseItem->OfferSummary) { - $item['lowestPrice'] = ((float) $responseItem->OfferSummary->LowestNewPrice->Amount) / 100.0; - } - else { - $item['lowestPrice'] = 0.0; - } - - // Images - $item['largeImage'] = (string) $responseItem->LargeImage->URL; - $item['mediumImage'] = (string) $responseItem->MediumImage->URL; - $item['smallImage'] = (string) $responseItem->SmallImage->URL; - - array_push($items, $item); - } - - return($items); + return $this->MakeAndParseRequest($params); } private function AddError($error) { @@ -234,7 +184,7 @@ private function AddError($error) { } public function GetErrors() { - return($this->mErrors); + return $this->mErrors; } } ?> diff --git a/src/Transformers/ArrayTransformer.php b/src/Transformers/ArrayTransformer.php new file mode 100644 index 0000000..ab214e7 --- /dev/null +++ b/src/Transformers/ArrayTransformer.php @@ -0,0 +1,20 @@ +xmlData = $xmlData; + } + + public function execute() { + $json = json_encode($this->xmlData); + return(json_decode($json)); + } +} + +?> \ No newline at end of file diff --git a/src/Transformers/IDataTransformer.php b/src/Transformers/IDataTransformer.php new file mode 100644 index 0000000..686c36a --- /dev/null +++ b/src/Transformers/IDataTransformer.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/src/Transformers/JsonTransformer.php b/src/Transformers/JsonTransformer.php new file mode 100644 index 0000000..fa1cd79 --- /dev/null +++ b/src/Transformers/JsonTransformer.php @@ -0,0 +1,19 @@ +xmlData = $xmlData; + } + + public function execute() { + return json_encode($this->xmlData); + } +} + +?> \ No newline at end of file diff --git a/src/Transformers/SimpleArrayTransformer.php b/src/Transformers/SimpleArrayTransformer.php new file mode 100644 index 0000000..569e2c3 --- /dev/null +++ b/src/Transformers/SimpleArrayTransformer.php @@ -0,0 +1,60 @@ +xmlData = $xmlData; + } + + public function execute() { + $items = array(); + if (empty($this->xmlData)) { + $this->AddError("No XML response found from AWS."); + return($items); + } + + if (empty($this->xmlData->Items)) { + $this->AddError("No items found."); + return($items); + } + + if ($this->xmlData->Items->Request->IsValid != 'True') { + $errorCode = $this->xmlData->Items->Request->Errors->Error->Code; + $errorMessage = $this->xmlData->Items->Request->Errors->Error->Message; + $error = "API ERROR ($errorCode) : $errorMessage"; + $this->AddError($error); + return($items); + } + + // Get each item + foreach($this->xmlData->Items->Item as $responseItem) { + $item = array(); + $item['asin'] = (string) $responseItem->ASIN; + $item['url'] = (string) $responseItem->DetailPageURL; + $item['rrp'] = ((float) $responseItem->ItemAttributes->ListPrice->Amount) / 100.0; + $item['title'] = (string) $responseItem->ItemAttributes->Title; + + if ($responseItem->OfferSummary) { + $item['lowestPrice'] = ((float) $responseItem->OfferSummary->LowestNewPrice->Amount) / 100.0; + } + else { + $item['lowestPrice'] = 0.0; + } + + // Images + $item['largeImage'] = (string) $responseItem->LargeImage->URL; + $item['mediumImage'] = (string) $responseItem->MediumImage->URL; + $item['smallImage'] = (string) $responseItem->SmallImage->URL; + + array_push($items, $item); + } + + return($items); } +} + +?> \ No newline at end of file diff --git a/src/Transformers/XmlDecorator.php b/src/Transformers/XmlDecorator.php new file mode 100644 index 0000000..b292ed7 --- /dev/null +++ b/src/Transformers/XmlDecorator.php @@ -0,0 +1,19 @@ +xmlData = $xmlData; + } + + public function execute() { + return $this->xmlData; + } +} + +?> \ No newline at end of file From 79a885655f8ff30a96995b8ef4800825b1801e7a Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 16:18:13 +0100 Subject: [PATCH 17/27] Refactor to take url builder --- examples.php | 15 ++++++++++++++- src/AmazonAPI.php | 24 ++---------------------- src/AmazonUrlBuilder.php | 10 ++++++++++ 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/examples.php b/examples.php index 93efd90..50ecef5 100644 --- a/examples.php +++ b/examples.php @@ -3,12 +3,21 @@ require('vendor/autoload.php'); use MarcL\AmazonAPI; +use MarcL\AmazonUrlBuilder; // Should load these from environment variables include_once('./secretKeys.php'); +// Setup a new instance of the AmazonUrlBuilder with your keys +$urlBuilder = new AmazonUrlBuilder( + $keyId, + $secretKey, + $associateId, + 'uk' +); + // Setup a new instance of the AmazonAPI with your keys -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId, 'uk'); +$amazonAPI = new AmazonAPI($urlBuilder); $amazonAPI->SetRetrieveAsArray(); // Item Search: @@ -26,4 +35,8 @@ $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); print('>> Harry Potter in Books, sort by price high to low'); var_dump($items); + +$items = $amazonAPI->ItemLookUp('B01GAGVIE4', true); +print('>> Look up specific ASIN\n'); +var_dump($items); ?> \ No newline at end of file diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index d5a518b..7700ffe 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -16,12 +16,7 @@ class AmazonAPI { - private $m_locale = 'uk'; private $m_retrieveArray = false; - - private $m_keyId = NULL; - private $m_secretKey = NULL; - private $m_associateTag = NULL; private $urlBuilder = NULL; // Valid names that can be used for search @@ -75,23 +70,8 @@ private function throwIfNull($parameterValue, $parameterName) { } } - public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { - $this->throwIfNull($keyId, 'Amazon key ID'); - $this->throwIfNull($secretKey, 'Amazon secret key'); - $this->throwIfNull($associateTag, 'Amazon associate tag'); - - // Setup the AWS credentials - $this->m_keyId = $keyId; - $this->m_secretKey = $secretKey; - $this->m_associateTag = $associateTag; - $this->m_locale = $locale; - - $this->urlBuilder = new AmazonUrlBuilder( - $this->m_keyId, - $this->m_secretKey, - $this->m_associateTag, - $this->m_locale - ); + public function __construct($urlBuilder) { + $this->urlBuilder = $urlBuilder; } public function SetRetrieveAsArray($retrieveArray = true) { diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index 9fbe5c8..b256e21 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -23,7 +23,17 @@ class AmazonUrlBuilder { 'us' => 'webservices.amazon.com/onca/xml' ); + private function throwIfNull($parameterValue, $parameterName) { + if ($parameterValue == NULL) { + throw new \Exception($parameterName . ' should be defined'); + } + } + public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { + $this->throwIfNull($keyId, 'Amazon key ID'); + $this->throwIfNull($secretKey, 'Amazon secret key'); + $this->throwIfNull($associateTag, 'Amazon associate tag'); + $this->secretKey = $secretKey; $this->amazonTld = $this->GetAmazonApiEndpoint($locale); $this->associateTag = $associateTag; From b5c802118170141fc0044376e4a15f0263f24e2c Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 17:07:37 +0100 Subject: [PATCH 18/27] Initial url builder tests --- src/AmazonUrlBuilder.php | 23 ++-- tests/AmazonUrlBuilderTest.php | 186 +++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 tests/AmazonUrlBuilderTest.php diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index b256e21..4439151 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -6,7 +6,7 @@ class AmazonUrlBuilder { private $secretKey = NULL; private $keyId = NULL; private $associateTag = NULL; - private $amazonTld = NULL; + private $amazonEndpoint = NULL; private $localeTable = array( 'br' => 'webservices.amazon.br/onca/xml', @@ -16,8 +16,8 @@ class AmazonUrlBuilder { 'de' => 'webservices.amazon.de/onca/xml', 'in' => 'webservices.amazon.in/onca/xml', 'it' => 'webservices.amazon.it/onca/xml', - 'jp' => 'webservices.amazon.jp/onca/xml', - 'mx' => 'webservices.amazon.mx/onca/xml', + 'jp' => 'webservices.amazon.co.jp/onca/xml', + 'mx' => 'webservices.amazon.com.mx/onca/xml', 'es' => 'webservices.amazon.es/onca/xml', 'uk' => 'webservices.amazon.co.uk/onca/xml', 'us' => 'webservices.amazon.com/onca/xml' @@ -35,7 +35,7 @@ public function __construct($keyId, $secretKey, $associateTag, $locale = 'us') { $this->throwIfNull($associateTag, 'Amazon associate tag'); $this->secretKey = $secretKey; - $this->amazonTld = $this->GetAmazonApiEndpoint($locale); + $this->amazonEndpoint = $this->GetAmazonApiEndpoint($locale); $this->associateTag = $associateTag; $this->keyId = $keyId; } @@ -57,7 +57,7 @@ private function CreateUnsignedAmazonUrl($params) { $buildParams = array_merge($baseParams, $params); - $request = $this->amazonTld . '?' .http_build_query($buildParams); + $request = $this->amazonEndpoint . '?' .http_build_query($buildParams); return($request); } @@ -103,7 +103,16 @@ private function GetSignedRequest($request, $version = '2011-08-01') { $signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}"; // Create our signature using hash_hmac - $signature = urlencode(base64_encode(hash_hmac('sha256', $signature_string, $this->secretKey, true))); + $signature = urlencode( + base64_encode( + hash_hmac( + 'sha256', + $signature_string, + $this->secretKey, + true + ) + ) + ); // Return our new request $newUrl = "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}"; @@ -113,7 +122,7 @@ private function GetSignedRequest($request, $version = '2011-08-01') { public function generate($params) { $unsignedRequest = $this->CreateUnsignedAmazonUrl($params); - return($this->GetSignedRequest($unsignedRequest)); + return $this->GetSignedRequest($unsignedRequest); } } diff --git a/tests/AmazonUrlBuilderTest.php b/tests/AmazonUrlBuilderTest.php new file mode 100644 index 0000000..a753d33 --- /dev/null +++ b/tests/AmazonUrlBuilderTest.php @@ -0,0 +1,186 @@ +expectExceptionMessage('Amazon key ID should be defined'); + + $amazonUrlBuilder = new AmazonUrlBuilder(NULL, NULL, NULL); + } + + public function testShouldThrowExceptionIfMissingSecretKey() { + $this->expectExceptionMessage('Amazon secret key should be defined'); + + $amazonUrlBuilder = new AmazonUrlBuilder($this->defaultKeyId, NULL, NULL); + } + + public function testShouldThrowExceptionIfMissingAssociateTag() { + $this->expectExceptionMessage('Amazon associate tag should be defined'); + + $amazonUrlBuilder = new AmazonUrlBuilder($this->defaultKeyId, $this->defaultSecretKey, NULL); + } + + private function createDefaultUrlBuilder($locale = 'us') { + return new AmazonUrlBuilder( + $this->defaultKeyId, + $this->defaultSecretKey, + $this->defaultAssociateTag, + $locale + ); + } + + private function getUrlQueryParameterArray($url) { + $uriElements = parse_url($url); + $query = $uriElements['query']; + + parse_str($query, $parameters); + + return($parameters); + } + + public function testShouldBuildUrlWithExpectedDefaultTld() { + $amazonUrlBuilder = new AmazonUrlBuilder( + $this->defaultKeyId, + $this->defaultSecretKey, + $this->defaultAssociateTag + ); + $expectedTld = 'amazon.com'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldBuildUrlWithExpectedGivenUKLocale() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder('uk'); + $expectedTld = 'amazon.co.uk'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldBuildUrlWithExpectedGivenJapaneseLocale() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder('jp'); + $expectedTld = 'amazon.co.jp'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldBuildUrlWithExpectedGivenMexicanLocale() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder('mx'); + $expectedTld = 'amazon.com.mx'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldBuildUrlWithExpectedGivenValidLocale() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder('de'); + $expectedTld = 'amazon.de'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldBuildUrlWithDefaultUSLocaleIfGivenLocaleIsUnknown() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder('unknown'); + $expectedTld = 'amazon.com'; + + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains($expectedTld, $url); + } + + public function testShouldContainExpectedService() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder(); + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains('Service=AWSECommerceService', $url); + } + + public function testShouldContainExpectedAssociateTag() { + $givenAssociateTag = 'given-associate-tag'; + $amazonUrlBuilder = new AmazonUrlBuilder( + $this->defaultKeyId, + $this->defaultSecretKey, + $givenAssociateTag + ); + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains('AssociateTag=' . $givenAssociateTag, $url); + } + + public function testShouldContainExpectedAwsAccessKeyId() { + $givenAwsAccessKeyId = 'givenAwsAccessKeyId'; + $amazonUrlBuilder = new AmazonUrlBuilder( + $givenAwsAccessKeyId, + $this->defaultSecretKey, + $this->defaultAssociateTag + ); + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains('AWSAccessKeyId=' . $givenAwsAccessKeyId, $url); + } + + public function testShouldContainExpectedVersion() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder(); + $url = $amazonUrlBuilder->generate(array()); + + $this->assertContains('Version=2011-08-01', $url); + } + + public function testShouldContainValidTimestamp() { + $amazonUrlBuilder = $this->createDefaultUrlBuilder(); + $url = $amazonUrlBuilder->generate(array()); + + $parameters = $this->getUrlQueryParameterArray($url); + + $this->assertStringMatchesFormat('%d-%d-%dT%d:%d:%dZ', $parameters['Timestamp']); + } + + // array( + // 'Operation' => 'ItemLookup', + // 'ResponseGroup' => 'ItemAttributes,Offers,Reviews,Images,EditorialReview', + // 'ReviewSort' => '-OverallRating', + // 'ItemId' => $asinList, + // 'MerchantId' => ($onlyFromAmazon == true) ? 'Amazon' : 'All' + // ) + + public function testShouldContainPassedParameter() { + $givenParameters = array( + 'Operation' => 'ItemLookup' + ); + $amazonUrlBuilder = $this->createDefaultUrlBuilder(); + $url = $amazonUrlBuilder->generate($givenParameters); + + $parameters = $this->getUrlQueryParameterArray($url); + + $this->assertContains('Operation=' . $givenParameters['Operation'], $url); + } + + public function testShouldContainPassedParameterWithCorrectEncoding() { + $givenParameters = array( + 'ResponseGroup' => 'ItemAttributes,Offers,Reviews,Images,EditorialReview', + ); + $amazonUrlBuilder = $this->createDefaultUrlBuilder(); + $url = $amazonUrlBuilder->generate($givenParameters); + + $expectedParameter = 'ResponseGroup=' . rawurlencode($givenParameters['ResponseGroup']); + + $parameters = $this->getUrlQueryParameterArray($url); + + $this->assertContains($expectedParameter, $url); + } +} +?> \ No newline at end of file From e10c96775417a9d9a94b04d339f78a179348193c Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 22:40:00 +0100 Subject: [PATCH 19/27] Slow down examples to avoid throttling --- examples.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples.php b/examples.php index 50ecef5..9916c2f 100644 --- a/examples.php +++ b/examples.php @@ -20,22 +20,32 @@ $amazonAPI = new AmazonAPI($urlBuilder); $amazonAPI->SetRetrieveAsArray(); +// Need to avoid triggering Amazon API throttling +$sleepTime = 1.5; + // Item Search: // Harry Potter in Books, sort by featured $items = $amazonAPI->ItemSearch('harry potter', 'Books'); print('>> Harry Potter in Books, sort by featured'); var_dump($items); +sleep($sleepTime); + // Harry Potter in Books, sort by price low to high $items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); print('>> Harry Potter in Books, sort by price low to high'); var_dump($items); +sleep($sleepTime); + // Harry Potter in Books, sort by price high to low $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); print('>> Harry Potter in Books, sort by price high to low'); var_dump($items); +sleep($sleepTime); + +// Amazon echo, only in Amazon $items = $amazonAPI->ItemLookUp('B01GAGVIE4', true); print('>> Look up specific ASIN\n'); var_dump($items); From 5aef502e0f7241da00b2e72ed7fd1a1508fa4f7c Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 22:42:23 +0100 Subject: [PATCH 20/27] Refactor --- src/AmazonUrlBuilder.php | 52 +++++++++++++++++++++++----------- tests/AmazonApiTest.php | 19 +------------ tests/AmazonUrlBuilderTest.php | 8 ------ 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index 4439151..ddcb56f 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -8,6 +8,8 @@ class AmazonUrlBuilder { private $associateTag = NULL; private $amazonEndpoint = NULL; + private $endpoint = 'onca/xml'; + private $localeTable = array( 'br' => 'webservices.amazon.br/onca/xml', 'ca' => 'webservices.amazon.ca/onca/xml', @@ -62,6 +64,30 @@ private function CreateUnsignedAmazonUrl($params) { return($request); } + private function encodeParameters($parameters) { + $encodedParameters = array(); + foreach ($parameters as $parameter => $value) { + $parameter = str_replace("%7E", "~", rawurlencode($parameter)); + $value = str_replace("%7E", "~", rawurlencode($value)); + $encodedParameters[$parameter]= $value; + } + + return $encodedParameters; + } + + private function createSignature($signatureString) { + return urlencode( + base64_encode( + hash_hmac( + 'sha256', + $signatureString, + $this->secretKey, + true + ) + ) + ); + } + /** * This function will take an existing Amazon request and change it so that it will be usable * with the new authentication. @@ -71,7 +97,7 @@ private function CreateUnsignedAmazonUrl($params) { * * @link http://www.ilovebonnie.net/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/ */ - private function GetSignedRequest($request, $version = '2011-08-01') { + private function CreateSignedAwsRequest($request, $version = '2011-08-01') { // Get a nice array of elements to work with $uri_elements = parse_url($request); @@ -93,36 +119,28 @@ private function GetSignedRequest($request, $version = '2011-08-01') { // We need to be sure we properly encode the value of our parameter $parameter = str_replace("%7E", "~", rawurlencode($parameter)); $value = str_replace("%7E", "~", rawurlencode($value)); - $request_array[] = $parameter . '=' . $value; + $requestArray[] = $parameter . '=' . $value; } // Put our & symbol at the beginning of each of our request variables and put it in a string - $new_request = implode('&', $request_array); + $requestParameters = implode('&', $requestArray); // Create our signature string - $signature_string = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$new_request}"; + $signatureString = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$requestParameters}"; + // $signatureString = $this->createSignatureString($this->encodeParameters($parameters)); + // var_dump($signatureString); - // Create our signature using hash_hmac - $signature = urlencode( - base64_encode( - hash_hmac( - 'sha256', - $signature_string, - $this->secretKey, - true - ) - ) - ); + $signature = $this->createSignature($signatureString); // Return our new request - $newUrl = "http://{$uri_elements['host']}{$uri_elements['path']}?{$new_request}&Signature={$signature}"; + $newUrl = "http://{$uri_elements['host']}{$uri_elements['path']}?{$requestParameters}&Signature={$signature}"; return $newUrl; } public function generate($params) { $unsignedRequest = $this->CreateUnsignedAmazonUrl($params); - return $this->GetSignedRequest($unsignedRequest); + return $this->CreateSignedAwsRequest($unsignedRequest); } } diff --git a/tests/AmazonApiTest.php b/tests/AmazonApiTest.php index 261a6aa..da9ba0f 100644 --- a/tests/AmazonApiTest.php +++ b/tests/AmazonApiTest.php @@ -4,25 +4,8 @@ use MarcL\AmazonAPI; class AmazonAPITest extends TestCase { - private $defaultKeyId = 'defaultKeyId'; - private $defaultSecretKey = 'defaultSecretKey'; - public function testShouldThrowExceptionIfMissingKeyId() { - $this->expectExceptionMessage('Amazon key ID should be defined'); - - $amazonAPI = new AmazonApi(NULL, NULL, NULL); - } - - public function testShouldThrowExceptionIfMissingSecretKey() { - $this->expectExceptionMessage('Amazon secret key should be defined'); - - $amazonAPI = new AmazonApi($this->defaultKeyId, NULL, NULL); - } - - public function testShouldThrowExceptionIfMissingAssociateTag() { - $this->expectExceptionMessage('Amazon associate tag should be defined'); - - $amazonAPI = new AmazonApi($this->defaultKeyId, $this->defaultSecretKey, NULL); + $this->assertEquals(true, true); } } ?> \ No newline at end of file diff --git a/tests/AmazonUrlBuilderTest.php b/tests/AmazonUrlBuilderTest.php index a753d33..9e850c4 100644 --- a/tests/AmazonUrlBuilderTest.php +++ b/tests/AmazonUrlBuilderTest.php @@ -149,14 +149,6 @@ public function testShouldContainValidTimestamp() { $this->assertStringMatchesFormat('%d-%d-%dT%d:%d:%dZ', $parameters['Timestamp']); } - // array( - // 'Operation' => 'ItemLookup', - // 'ResponseGroup' => 'ItemAttributes,Offers,Reviews,Images,EditorialReview', - // 'ReviewSort' => '-OverallRating', - // 'ItemId' => $asinList, - // 'MerchantId' => ($onlyFromAmazon == true) ? 'Amazon' : 'All' - // ) - public function testShouldContainPassedParameter() { $givenParameters = array( 'Operation' => 'ItemLookup' From ed9f1708206cf7bb2d6073863ed3342340341364 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sat, 15 Jul 2017 23:29:43 +0100 Subject: [PATCH 21/27] Refactor data transformers --- examples.php | 31 ++++++++++----------- src/AmazonAPI.php | 28 +++++++++++++++---- src/Transformers/ArrayTransformer.php | 10 ++----- src/Transformers/IDataTransformer.php | 2 +- src/Transformers/JsonTransformer.php | 10 ++----- src/Transformers/SimpleArrayTransformer.php | 20 +++++-------- src/Transformers/XmlDecorator.php | 19 ------------- src/Transformers/XmlTransformer.php | 13 +++++++++ 8 files changed, 63 insertions(+), 70 deletions(-) delete mode 100644 src/Transformers/XmlDecorator.php create mode 100644 src/Transformers/XmlTransformer.php diff --git a/examples.php b/examples.php index 9916c2f..0854aa8 100644 --- a/examples.php +++ b/examples.php @@ -17,33 +17,32 @@ ); // Setup a new instance of the AmazonAPI with your keys -$amazonAPI = new AmazonAPI($urlBuilder); -$amazonAPI->SetRetrieveAsArray(); +$amazonAPI = new AmazonAPI($urlBuilder, 'simple'); // Need to avoid triggering Amazon API throttling $sleepTime = 1.5; // Item Search: // Harry Potter in Books, sort by featured -$items = $amazonAPI->ItemSearch('harry potter', 'Books'); -print('>> Harry Potter in Books, sort by featured'); -var_dump($items); +// $items = $amazonAPI->ItemSearch('harry potter', 'Books'); +// print('>> Harry Potter in Books, sort by featured'); +// var_dump($items); -sleep($sleepTime); +// sleep($sleepTime); -// Harry Potter in Books, sort by price low to high -$items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); -print('>> Harry Potter in Books, sort by price low to high'); -var_dump($items); +// // Harry Potter in Books, sort by price low to high +// $items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); +// print('>> Harry Potter in Books, sort by price low to high'); +// var_dump($items); -sleep($sleepTime); +// sleep($sleepTime); -// Harry Potter in Books, sort by price high to low -$items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); -print('>> Harry Potter in Books, sort by price high to low'); -var_dump($items); +// // Harry Potter in Books, sort by price high to low +// $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); +// print('>> Harry Potter in Books, sort by price high to low'); +// var_dump($items); -sleep($sleepTime); +// sleep($sleepTime); // Amazon echo, only in Amazon $items = $amazonAPI->ItemLookUp('B01GAGVIE4', true); diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 7700ffe..fab3b44 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -11,6 +11,8 @@ use MarcL\CurlHttpRequest; use MarcL\AmazonUrlBuilder; +use MarcL\Transformers\ArrayTransformer; +use MarcL\Transformers\JsonTransformer; use MarcL\Transformers\SimpleArrayTransformer; use MarcL\Transformers\XmlTransformer; @@ -18,6 +20,7 @@ class AmazonAPI { private $m_retrieveArray = false; private $urlBuilder = NULL; + private $dataTransformer = NULL; // Valid names that can be used for search private $mValidSearchNames = array( @@ -70,8 +73,9 @@ private function throwIfNull($parameterValue, $parameterName) { } } - public function __construct($urlBuilder) { + public function __construct($urlBuilder, $outputType) { $this->urlBuilder = $urlBuilder; + $this->dataTransformer = $this->createDataTransformer($outputType); } public function SetRetrieveAsArray($retrieveArray = true) { @@ -105,11 +109,25 @@ private function MakeAndParseRequest($params) { return(false); } - $dataTransformer = $this->m_retrieveArray - ? new SimpleArrayTransformer($parsedXml) - : new XmlTransformer($parsedXml); + return $this->dataTransformer->execute($parsedXml); + } - return $dataTransformer->execute(); + private function createDataTransformer($outputType) { + switch($outputType) { + case 'array': + return new ArrayTransformer(); + break; + case 'json': + return new JsonTransformer(); + break; + case 'simple': + return new SimpleArrayTransformer(); + break; + case 'xml': + default: + return new XmlTransformer(); + break; + } } /** diff --git a/src/Transformers/ArrayTransformer.php b/src/Transformers/ArrayTransformer.php index ab214e7..797f038 100644 --- a/src/Transformers/ArrayTransformer.php +++ b/src/Transformers/ArrayTransformer.php @@ -5,14 +5,8 @@ use MarcL\Transformers\IDataTransformer; class ArrayTransformer implements IDataTransformer { - private $xmlData = NULL; - - public function __construct($xmlData) { - $this->xmlData = $xmlData; - } - - public function execute() { - $json = json_encode($this->xmlData); + public function execute($xmlData) { + $json = json_encode($xmlData); return(json_decode($json)); } } diff --git a/src/Transformers/IDataTransformer.php b/src/Transformers/IDataTransformer.php index 686c36a..45db901 100644 --- a/src/Transformers/IDataTransformer.php +++ b/src/Transformers/IDataTransformer.php @@ -3,7 +3,7 @@ namespace MarcL\Transformers; interface IDataTransformer { - public function execute(); + public function execute($data); } ?> \ No newline at end of file diff --git a/src/Transformers/JsonTransformer.php b/src/Transformers/JsonTransformer.php index fa1cd79..1c3e981 100644 --- a/src/Transformers/JsonTransformer.php +++ b/src/Transformers/JsonTransformer.php @@ -5,14 +5,8 @@ use MarcL\Transformers\IDataTransformer; class JsonTransformer implements IDataTransformer { - private $xmlData = NULL; - - public function __construct($xmlData) { - $this->xmlData = $xmlData; - } - - public function execute() { - return json_encode($this->xmlData); + public function execute($xmlData) { + return json_encode($xmlData); } } diff --git a/src/Transformers/SimpleArrayTransformer.php b/src/Transformers/SimpleArrayTransformer.php index 569e2c3..1494dee 100644 --- a/src/Transformers/SimpleArrayTransformer.php +++ b/src/Transformers/SimpleArrayTransformer.php @@ -5,34 +5,28 @@ use MarcL\Transformers\IDataTransformer; class SimpleArrayTransformer implements IDataTransformer { - private $xmlData = NULL; - - public function __construct($xmlData) { - $this->xmlData = $xmlData; - } - - public function execute() { + public function execute($xmlData) { $items = array(); - if (empty($this->xmlData)) { + if (empty($xmlData)) { $this->AddError("No XML response found from AWS."); return($items); } - if (empty($this->xmlData->Items)) { + if (empty($xmlData->Items)) { $this->AddError("No items found."); return($items); } - if ($this->xmlData->Items->Request->IsValid != 'True') { - $errorCode = $this->xmlData->Items->Request->Errors->Error->Code; - $errorMessage = $this->xmlData->Items->Request->Errors->Error->Message; + if ($xmlData->Items->Request->IsValid != 'True') { + $errorCode = $xmlData->Items->Request->Errors->Error->Code; + $errorMessage = $xmlData->Items->Request->Errors->Error->Message; $error = "API ERROR ($errorCode) : $errorMessage"; $this->AddError($error); return($items); } // Get each item - foreach($this->xmlData->Items->Item as $responseItem) { + foreach($xmlData->Items->Item as $responseItem) { $item = array(); $item['asin'] = (string) $responseItem->ASIN; $item['url'] = (string) $responseItem->DetailPageURL; diff --git a/src/Transformers/XmlDecorator.php b/src/Transformers/XmlDecorator.php deleted file mode 100644 index b292ed7..0000000 --- a/src/Transformers/XmlDecorator.php +++ /dev/null @@ -1,19 +0,0 @@ -xmlData = $xmlData; - } - - public function execute() { - return $this->xmlData; - } -} - -?> \ No newline at end of file diff --git a/src/Transformers/XmlTransformer.php b/src/Transformers/XmlTransformer.php new file mode 100644 index 0000000..5a42f9d --- /dev/null +++ b/src/Transformers/XmlTransformer.php @@ -0,0 +1,13 @@ + \ No newline at end of file From 5ff0a1827425323f5a0cc28b97096b709691b797 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sun, 16 Jul 2017 19:43:12 +0100 Subject: [PATCH 22/27] Add examples back --- examples.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/examples.php b/examples.php index 0854aa8..d140e52 100644 --- a/examples.php +++ b/examples.php @@ -24,27 +24,27 @@ // Item Search: // Harry Potter in Books, sort by featured -// $items = $amazonAPI->ItemSearch('harry potter', 'Books'); -// print('>> Harry Potter in Books, sort by featured'); -// var_dump($items); +$items = $amazonAPI->ItemSearch('harry potter', 'Books'); +print('>> Harry Potter in Books, sort by featured'); +var_dump($items); -// sleep($sleepTime); +sleep($sleepTime); -// // Harry Potter in Books, sort by price low to high -// $items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); -// print('>> Harry Potter in Books, sort by price low to high'); -// var_dump($items); +// Harry Potter in Books, sort by price low to high +$items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); +print('>> Harry Potter in Books, sort by price low to high'); +var_dump($items); -// sleep($sleepTime); +sleep($sleepTime); -// // Harry Potter in Books, sort by price high to low -// $items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); -// print('>> Harry Potter in Books, sort by price high to low'); -// var_dump($items); +// Harry Potter in Books, sort by price high to low +$items = $amazonAPI->ItemSearch('harry potter', 'Books', '-price'); +print('>> Harry Potter in Books, sort by price high to low'); +var_dump($items); -// sleep($sleepTime); +sleep($sleepTime); -// Amazon echo, only in Amazon +// Amazon echo, lookup only with Amazon as a seller $items = $amazonAPI->ItemLookUp('B01GAGVIE4', true); print('>> Look up specific ASIN\n'); var_dump($items); From 76a8b2422d5cb84cba9958c2b7b0566fe86fa57d Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sun, 16 Jul 2017 19:43:21 +0100 Subject: [PATCH 23/27] Update README --- README.md | 66 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 12c917d..732044f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ # AmazonProductAPI PHP library to perform product lookup and searches using the Amazon Product API. -## Dependencies -Requires the [SimpleXML](http://php.net/manual/en/book.simplexml.php) PHP and [Curl](http://php.net/manual/en/book.curl.php) extensions to be installed. -It also assumes that you have some knowledge of Amazon's Product API and have set up an Amazon Associate and [Amazon Web Services](http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/GettingSetUp.html) account in order to retrieve your access keys. - ## Installation -Clone the git repository: + +This library requires the [SimpleXML](http://php.net/manual/en/book.simplexml.php) and [Curl](http://php.net/manual/en/book.curl.php) extensions to be installed and uses PHP 7+ . Installation is simple using [Composer](https://composer.io): ```shell -git clone https://github.com/MarcL/AmazonProductAPI.git +composer require marcl\amazonproductapi ``` +### Amazon Product API +It also assumes that you have some basic knowledge of Amazon's Product API and have set up an Amazon Associate account see: [Amazon Product API Set Up](http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/GettingSetUp.html). + +You'll need an AWS key, secret key, and associate tag. Ensure that you keep these safe! + ## Examples I've added some simple examples in `examples.php`. To run them create a file called `secretKeys.php` containing your secret keys: @@ -30,31 +32,41 @@ and then run the examples with: php examples.php ``` -## Usage -Include the library in your code: +## Quick Start + +Include the library in your code using the Composer autoloader and create an AmazonUrlBuilder with your credentials ```php -include_once('./AmazonAPI.php'); -``` +require('vendor/autoload.php'); -Instantiate the class using your secret keys: +use MarcL\AmazonAPI; +use MarcL\AmazonUrlBuilder; -```php // Keep these safe $keyId = 'YOUR-AWS-KEY'; $secretKey = 'YOUR-AWS-SECRET-KEY'; $associateId = 'YOUR-AMAZON-ASSOCIATE-ID'; -$locale = 'us'; // Default is 'uk' +// Setup a new instance of the AmazonUrlBuilder with your keys +$urlBuilder = new AmazonUrlBuilder( + $keyId, + $secretKey, + $associateId, + 'uk' +); + +// Setup a new instance of the AmazonAPI and define the type of response +$amazonAPI = new AmazonAPI($urlBuilder, 'simple'); + +$items = $amazonAPI->ItemSearch('harry potter', 'Books', 'price'); -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId, $locale); ``` **Note:** Keep your Amazon keys safe. Either use environment variables or include from a file that you don't check into GitHub. ### Locale -This library supports all [Product Advertising API locales](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Locales.html) and you can set it as you construct the class. +This library supports all [Product Advertising API locales](http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Locales.html) and you can set it as you construct the AmazonUrlBuilder class with your keys. At this time, these are the current supported locales: @@ -113,12 +125,12 @@ $asinIds = array('B003U6I396', 'B003U6I397', 'B003U6I398'); $items = $amazonAPI->ItemLookUp($asinIds); ``` -### Returned data -By default the data will be returned as SimpleXML nodes. However if you call `SetRetrieveAsArray()` then a simplified array of items will be returned. For example: +### Data Transformation +By default the data will be returned as SimpleXML nodes. However, you can ask for the data to be transformed differently, depending on your use case for the API. Pass a type when instantiating the AmazonAPI class as follows: ```php -// Return XML data -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId); +// Default return type is XML +$amazonAPI = new AmazonAPI($amazonUrlBuilder); $items = $amazonAPI->ItemSearch('harry potter'); var_dump($items); ``` @@ -140,13 +152,12 @@ class SimpleXMLElement#2 (2) { ```php // Return simplified data -$amazonAPI = new AmazonAPI($keyId, $secretKey, $associateId); -$amazonAPI->SetRetrieveAsArray(); +$amazonAPI = new AmazonAPI($amazonUrlBuilder, 'simple'); $items = $amazonAPI->ItemSearch('harry potter'); var_dump($items); ``` -Returning simplified data gives a PHP array +This will return a simplified version of each item with minimal data but enough for simple use cases. ``` array(10) { @@ -182,15 +193,20 @@ array(10) { … ``` +The different data transformation types are defined as follows. Feel free to raise an issue if you'd like the data transforming to a new type. + +* **xml** - (Default) returns data as SimpleXML nodes. +* **array** - Returns data as PHP arrays and objects. +* **simple** - Returns data as simplified arrays and doesn't contain all API data. Use this if you just need prices, title and images. +* **json** - Returns data as a JSON string. Use this for returning from a server API endpoint. + ## TODO * Need to make the simplified data less hardcoded! -* Make this a Composer package -* Add unit tests ## Thanks -This library uses code based on [AWS API authentication For PHP](http://randomdrake.com/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/) by [David Drake](https://github.com/randomdrake). +This library uses code based on [AWS API authentication For PHP](http://randomdrake.com/2009/07/27/amazon-aws-api-rest-authentication-for-php-5/) by [David Drake](https://github.com/randomdrake) but has been mostly rewritten. ## LICENSE From 235bfc11673c6c952cfca6800cc0eb4e256dd67e Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Sun, 16 Jul 2017 21:39:39 +0100 Subject: [PATCH 24/27] Cleanup --- src/AmazonUrlBuilder.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/AmazonUrlBuilder.php b/src/AmazonUrlBuilder.php index ddcb56f..04627a1 100644 --- a/src/AmazonUrlBuilder.php +++ b/src/AmazonUrlBuilder.php @@ -64,17 +64,6 @@ private function CreateUnsignedAmazonUrl($params) { return($request); } - private function encodeParameters($parameters) { - $encodedParameters = array(); - foreach ($parameters as $parameter => $value) { - $parameter = str_replace("%7E", "~", rawurlencode($parameter)); - $value = str_replace("%7E", "~", rawurlencode($value)); - $encodedParameters[$parameter]= $value; - } - - return $encodedParameters; - } - private function createSignature($signatureString) { return urlencode( base64_encode( @@ -127,9 +116,6 @@ private function CreateSignedAwsRequest($request, $version = '2011-08-01') { // Create our signature string $signatureString = "GET\n{$uri_elements['host']}\n{$uri_elements['path']}\n{$requestParameters}"; - // $signatureString = $this->createSignatureString($this->encodeParameters($parameters)); - // var_dump($signatureString); - $signature = $this->createSignature($signatureString); // Return our new request From cd432d243e9fb88972df01005e4ff5378087b892 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Thu, 20 Jul 2017 11:12:24 +0100 Subject: [PATCH 25/27] Add DataTransformerFactory + tidy up --- src/AmazonAPI.php | 86 +++++++-------------- src/Transformers/DataTransformerFactory.php | 25 ++++++ 2 files changed, 55 insertions(+), 56 deletions(-) create mode 100644 src/Transformers/DataTransformerFactory.php diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index fab3b44..7ed5bc5 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -11,14 +11,10 @@ use MarcL\CurlHttpRequest; use MarcL\AmazonUrlBuilder; -use MarcL\Transformers\ArrayTransformer; -use MarcL\Transformers\JsonTransformer; -use MarcL\Transformers\SimpleArrayTransformer; -use MarcL\Transformers\XmlTransformer; +use MarcL\Transformers\DataTransformerFactory; class AmazonAPI { - private $m_retrieveArray = false; private $urlBuilder = NULL; private $dataTransformer = NULL; @@ -75,61 +71,13 @@ private function throwIfNull($parameterValue, $parameterName) { public function __construct($urlBuilder, $outputType) { $this->urlBuilder = $urlBuilder; - $this->dataTransformer = $this->createDataTransformer($outputType); - } - - public function SetRetrieveAsArray($retrieveArray = true) { - $this->m_retrieveArray = $retrieveArray; + $this->dataTransformer = DataTransformerFactory::create($outputType); } public function GetValidSearchNames() { return $this->mValidSearchNames; } - private function MakeSignedRequest($params) { - $signedUrl = $this->urlBuilder->generate($params); - - try { - $request = new CurlHttpRequest(); - $response = $request->execute($signedUrl); - - $parsedXml = simplexml_load_string($response); - - return($parsedXml); - } catch(\Exception $error) { - $this->AddError("Error downloading data : $signedUrl : " . $error->getMessage()); - } - - return false; - } - - private function MakeAndParseRequest($params) { - $parsedXml = $this->MakeSignedRequest($params); - if ($parsedXml === false) { - return(false); - } - - return $this->dataTransformer->execute($parsedXml); - } - - private function createDataTransformer($outputType) { - switch($outputType) { - case 'array': - return new ArrayTransformer(); - break; - case 'json': - return new JsonTransformer(); - break; - case 'simple': - return new SimpleArrayTransformer(); - break; - case 'xml': - default: - return new XmlTransformer(); - break; - } - } - /** * Search for items * @@ -177,12 +125,38 @@ public function ItemLookup($asinList, $onlyFromAmazon = false) { return $this->MakeAndParseRequest($params); } + public function GetErrors() { + return $this->mErrors; + } + private function AddError($error) { array_push($this->mErrors, $error); } - public function GetErrors() { - return $this->mErrors; + private function MakeSignedRequest($params) { + $signedUrl = $this->urlBuilder->generate($params); + + try { + $request = new CurlHttpRequest(); + $response = $request->execute($signedUrl); + + $parsedXml = simplexml_load_string($response); + + return($parsedXml); + } catch(\Exception $error) { + $this->AddError("Error downloading data : $signedUrl : " . $error->getMessage()); + } + + return false; + } + + private function MakeAndParseRequest($params) { + $parsedXml = $this->MakeSignedRequest($params); + if ($parsedXml === false) { + return(false); + } + + return $this->dataTransformer->execute($parsedXml); } } ?> diff --git a/src/Transformers/DataTransformerFactory.php b/src/Transformers/DataTransformerFactory.php new file mode 100644 index 0000000..751adc1 --- /dev/null +++ b/src/Transformers/DataTransformerFactory.php @@ -0,0 +1,25 @@ + \ No newline at end of file From 7f10f84b2efea71456bb928aad8819dc4676c5f3 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Thu, 20 Jul 2017 11:14:49 +0100 Subject: [PATCH 26/27] Remove unused code --- src/AmazonAPI.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index 7ed5bc5..c0e808b 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -63,12 +63,6 @@ class AmazonAPI private $mErrors = array(); - private function throwIfNull($parameterValue, $parameterName) { - if ($parameterValue == NULL) { - throw new \Exception($parameterName . ' should be defined'); - } - } - public function __construct($urlBuilder, $outputType) { $this->urlBuilder = $urlBuilder; $this->dataTransformer = DataTransformerFactory::create($outputType); From 835f0beb3b73bd4219b52535dfa3679265012665 Mon Sep 17 00:00:00 2001 From: Marc Littlemore Date: Thu, 20 Jul 2017 11:17:41 +0100 Subject: [PATCH 27/27] Refactoring --- src/AmazonAPI.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/AmazonAPI.php b/src/AmazonAPI.php index c0e808b..96b4901 100644 --- a/src/AmazonAPI.php +++ b/src/AmazonAPI.php @@ -127,7 +127,7 @@ private function AddError($error) { array_push($this->mErrors, $error); } - private function MakeSignedRequest($params) { + private function MakeAndParseRequest($params) { $signedUrl = $this->urlBuilder->generate($params); try { @@ -141,13 +141,8 @@ private function MakeSignedRequest($params) { $this->AddError("Error downloading data : $signedUrl : " . $error->getMessage()); } - return false; - } - - private function MakeAndParseRequest($params) { - $parsedXml = $this->MakeSignedRequest($params); if ($parsedXml === false) { - return(false); + return false; } return $this->dataTransformer->execute($parsedXml);