12 Commits
1.1.0 ... 1.1.4

Author SHA1 Message Date
f60aa3e1bc Merge branch 'development'
PHPstan config updates, test file update
2021-11-25 17:45:13 +09:00
b041720a18 phpstan config updates, test code update 2021-11-25 17:44:04 +09:00
be6b2be55d Merge pull request #1 from arif-rh/minor-fix
Minor fix for README type on composer command and trailing , in config class
2021-11-25 17:42:33 +09:00
Arif RH
6163d26f50 minor fix Config 2021-11-25 14:55:55 +07:00
Arif RH
a4c06b9a36 minor fix README 2021-11-25 14:55:09 +07:00
24dc8426de Remove space from client interface 2021-10-27 17:55:29 +09:00
7ef4133537 Update composer json file to exclude test and static test files 2021-10-21 15:51:05 +09:00
4f90f2d916 Update test with simpl .env variables and include example file 2021-10-21 15:00:45 +09:00
192e4e54e1 Add psalm to level 3 and clean up more code 2021-10-21 14:57:29 +09:00
d0b676f8ce Add phan checks at max level 2021-10-21 13:37:59 +09:00
c2721cb8d4 Add PHPstan and fix all checks for max level 2021-10-21 13:31:18 +09:00
18cf3330df Change license to MIT 2021-10-21 10:31:08 +09:00
18 changed files with 364 additions and 225 deletions

97
.phan/config.php Normal file
View File

@@ -0,0 +1,97 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command line arguments will be applied
* after this file is read.
*
* @see src/Phan/Config.php
* See Config for all configurable options.
*
* A Note About Paths
* ==================
*
* Files referenced from this file should be defined as
*
* ```
* Config::projectPath('relative_path/to/file')
* ```
*
* where the relative path is relative to the root of the
* project which is defined as either the working directory
* of the phan executable or a path passed in via the CLI
* '-d' flag.
*/
// use Phan\Config;
return [
// If true, missing properties will be created when
// they are first seen. If false, we'll report an
// error message.
"allow_missing_properties" => false,
// Allow null to be cast as any type and for any
// type to be cast to null.
"null_casts_as_any_type" => false,
// Backwards Compatibility Checking
'backward_compatibility_checks' => true,
// Run a quick version of checks that takes less
// time
"quick_mode" => false,
// Only emit critical issues to start with
// (0 is low severity, 5 is normal severity, 10 is critical)
"minimum_severity" => 10,
// default false for include path check
"enable_include_path_checks" => true,
"include_paths" => [
],
'ignore_undeclared_variables_in_global_scope' => true,
"file_list" => [
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
// Change this to include the folders you wish to analyze
// (and the folders of their dependencies)
'.'
// 'www',
// To speed up analysis, we recommend going back later and
// limiting this to only the vendor/ subdirectories your
// project depends on.
// `phan --init` will generate a list of folders for you
//'www/vendor',
],
// A list of directories holding code that we want
// to parse, but not analyze
"exclude_analysis_directory_list" => [
'vendor',
],
'exclude_file_list' => [
],
// what not to show as problem
'suppress_issue_types' => [
// 'PhanUndeclaredMethod',
'PhanEmptyFile',
],
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
// Class names should be prefixed with `\`.
//
// (E.g. `['_FOO' => '\FooClass', 'page' => '\PageClass', 'userId' => 'int']`)
'globals_type_map' => [],
];

View File

@@ -6,7 +6,7 @@ Amazon Gift Codes On Demand (AGCOD). Integration for Amazon Incentive API.
## How to install ## How to install
`composer request gullevek/amazon-incentives` `composer require gullevek/amazon-incentives`
## _ENV variables needed ## _ENV variables needed
@@ -99,16 +99,31 @@ to extract the below array from the thrown exception
`status`, `code` and `type` must be checked on a failure. `status`, `code` and `type` must be checked on a failure.
**NOTE**: if code is T001 then this is a request flood error: ## Other Errors from exceptions
### T001
if code is T001 then this is a request flood error:
In this case the request has to be resend after a certain waiting period. In this case the request has to be resend after a certain waiting period.
**NOTE**: if code is E999 some other critical error has happened ### E9999
**NOTE**: if code is E001 if the return create/cancel/check calls is not an array if code is E999 some other critical error has happened
**NOTE**: if code is C001 a curl error has happened ### E001
**NOTE**: any other NON amazon error will have only 'message' set if run through decode if code is E001 if the return create/cancel/check calls is not an array
### C001
fif code is C001 curl failed to init
### C002
if code is C002 a curl error has happened
### empty error code
any other NON amazon error will have only 'message' set if run through decode
## Debugging ## Debugging

View File

@@ -3,7 +3,7 @@
"description": "Amazon Gift Codes, Gift on Demand, Incentives", "description": "Amazon Gift Codes, Gift on Demand, Incentives",
"keywords": ["AmazonGiftCode", "Amazon", "GiftCard", "AGCOD", "Incentives API", "Amazon Incentives API"], "keywords": ["AmazonGiftCode", "Amazon", "GiftCard", "AGCOD", "Incentives API", "Amazon Incentives API"],
"type": "library", "type": "library",
"license": "help", "license": "MIT",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"gullevek\\AmazonIncentives\\": "src/" "gullevek\\AmazonIncentives\\": "src/"
@@ -20,5 +20,8 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"require": { "require": {
"php": ">=7.4.0" "php": ">=7.4.0"
},
"archive": {
"exclude": ["/test/", "/phpstan.neon", "/psalm.xml", "/.phan/", "/.vscode/"]
} }
} }

15
phpstan.neon Normal file
View File

@@ -0,0 +1,15 @@
# PHP Stan Config
parameters:
tmpDir: /tmp/phpstan-codeblocks-amazon-incentives
level: 8
paths:
- %currentWorkingDirectory%
excludePaths:
# ignore composer
- vendor
# ignore errores with
ignoreErrors:
-
message: '#Strict comparison using === between false and true will always evaluate to false.#'
path: %currentWorkingDirectory%/test/aws_gift_card_tests.php

15
psalm.xml Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<psalm
errorLevel="3"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@@ -26,6 +26,9 @@ class AWS
public const CANCEL_GIFT_CARD_SERVICE = 'CancelGiftCard'; public const CANCEL_GIFT_CARD_SERVICE = 'CancelGiftCard';
public const GET_AVAILABLE_FUNDS_SERVICE = 'GetAvailableFunds'; public const GET_AVAILABLE_FUNDS_SERVICE = 'GetAvailableFunds';
/**
* @var Config
*/
private $config; private $config;
/** /**
@@ -152,7 +155,7 @@ class AWS
'Service' => $k_service_hexis, 'Service' => $k_service_hexis,
]]); ]]);
$url = 'https://' . (string)$endpoint . '/' . $service_operation; $url = 'https://' . $endpoint . '/' . $service_operation;
$headers = $this->buildHeaders($payload, $authorization_value, $date_time_string, $service_target); $headers = $this->buildHeaders($payload, $authorization_value, $date_time_string, $service_target);
return (new Client())->request($url, $headers, $payload); return (new Client())->request($url, $headers, $payload);
} }
@@ -162,7 +165,7 @@ class AWS
* @param string $authorization_value * @param string $authorization_value
* @param string $date_time_string * @param string $date_time_string
* @param string $service_target * @param string $service_target
* @return array * @return array<mixed>
*/ */
public function buildHeaders( public function buildHeaders(
string $payload, string $payload,
@@ -318,22 +321,21 @@ class AWS
/** /**
* @param float $amount * @param float $amount
* @param string $creation_id * @param string|null $creation_id
* @return string * @return string
*/ */
public function getGiftCardPayload(float $amount, ?string $creation_id = null): string public function getGiftCardPayload(float $amount, ?string $creation_id = null): string
{ {
$amount = trim($amount);
$payload = [ $payload = [
'creationRequestId' => $creation_id ?: uniqid($this->config->getPartner() . '_'), 'creationRequestId' => $creation_id ?: uniqid($this->config->getPartner() . '_'),
'partnerId' => $this->config->getPartner(), 'partnerId' => $this->config->getPartner(),
'value' => 'value' =>
[ [
'currencyCode' => $this->config->getCurrency(), 'currencyCode' => $this->config->getCurrency(),
'amount' => (float)$amount 'amount' => $amount
] ]
]; ];
return json_encode($payload); return (json_encode($payload)) ?: '';
} }
/** /**
@@ -343,13 +345,12 @@ class AWS
*/ */
public function getCancelGiftCardPayload(string $creation_request_id, string $gift_card_id): string public function getCancelGiftCardPayload(string $creation_request_id, string $gift_card_id): string
{ {
$gift_card_response_id = trim($gift_card_id);
$payload = [ $payload = [
'creationRequestId' => $creation_request_id, 'creationRequestId' => $creation_request_id,
'partnerId' => $this->config->getPartner(), 'partnerId' => $this->config->getPartner(),
'gcId' => $gift_card_response_id 'gcId' => $gift_card_id
]; ];
return json_encode($payload); return (json_encode($payload)) ?: '';
} }
/** /**
@@ -360,7 +361,7 @@ class AWS
$payload = [ $payload = [
'partnerId' => $this->config->getPartner(), 'partnerId' => $this->config->getPartner(),
]; ];
return json_encode($payload); return (json_encode($payload)) ?: '';
} }
/** /**
@@ -394,7 +395,7 @@ class AWS
} }
/** /**
* @return false|string * @return string
*/ */
public function getTimestamp() public function getTimestamp()
{ {
@@ -413,7 +414,7 @@ class AWS
} }
/** /**
* @return bool|string * @return string
*/ */
public function getDateString() public function getDateString()
{ {

View File

@@ -2,36 +2,7 @@
/* /*
* Amazon Incentive Code * Amazon Incentive Code
* * Amazon Gift Code on Demand
* # settings:
* aws endpoint (also sets region)
* aws key
* aws secret
* aws partner id
* money type (set as default, override in call)
* money value (set as default, override in call)
*
* # checks
* endpoint + region must match
*
* # calls:
* create gift card: CreateGiftCard
* cancel gift card: CancelGiftCard
*
* activate gift card: ActivateGiftCard
* deactivate gift card: DeactivateGiftCard
*
* gift card status: ActivationStatusCheck
*
* check available funds: GetAvailablefunds
*
* api server health check
*
* # sub classes
* config reader/checker
* API v4 encrypter
* submitter/data getter
* error handler/retry
*/ */
namespace gullevek\AmazonIncentives; namespace gullevek\AmazonIncentives;
@@ -41,8 +12,11 @@ use gullevek\AmazonIncentives\Config\Config;
use gullevek\AmazonIncentives\Exceptions\AmazonErrors; use gullevek\AmazonIncentives\Exceptions\AmazonErrors;
use gullevek\AmazonIncentives\Debug\AmazonDebug; use gullevek\AmazonIncentives\Debug\AmazonDebug;
class AmazonIncentives final class AmazonIncentives
{ {
/**
* @var Config
*/
private $config; private $config;
/** /**
@@ -80,7 +54,7 @@ class AmazonIncentives
/** /**
* @param float $value * @param float $value
* @param string $creation_request_id AWS creationRequestId * @param string|null $creation_request_id AWS creationRequestId
* @return Response\CreateResponse * @return Response\CreateResponse
* *
* @throws AmazonErrors * @throws AmazonErrors
@@ -112,7 +86,7 @@ class AmazonIncentives
} }
/** /**
* AmazonGiftCode make own client. * AmazonIncentives make own client.
* *
* @param string|null $key * @param string|null $key
* @param string|null $secret * @param string|null $secret
@@ -120,7 +94,7 @@ class AmazonIncentives
* @param string|null $endpoint * @param string|null $endpoint
* @param string|null $currency * @param string|null $currency
* @param bool|null $debug * @param bool|null $debug
* @return AmazonGiftCode * @return AmazonIncentives
*/ */
public static function make( public static function make(
string $key = null, string $key = null,
@@ -139,7 +113,7 @@ class AmazonIncentives
* message (Amazon returned error message string) * message (Amazon returned error message string)
* *
* @param string $message Exception message json string * @param string $message Exception message json string
* @return array Decoded with code, type, message fields * @return array<mixed> Decoded with code, type, message fields
*/ */
public static function decodeExceptionMessage(string $message): array public static function decodeExceptionMessage(string $message): array
{ {
@@ -162,6 +136,9 @@ class AmazonIncentives
// PUBLIC TEST METHODS // PUBLIC TEST METHODS
// ********************************************************************* // *********************************************************************
/**
* @return array<mixed>
*/
public function checkMe(): array public function checkMe(): array
{ {
$data = []; $data = [];

View File

@@ -13,15 +13,25 @@ class Client implements ClientInterface
/** /**
* *
* @param string $url The URL being requested, including domain and protocol * @param string $url The URL being requested, including domain and protocol
* @param array $headers Headers to be used in the request * @param array<mixed> $headers Headers to be used in the request
* @param array|string $params Can be nested for arrays and hashes * @param array<mixed>|string $params Can be nested for arrays and hashes
* *
* *
* @return String * @return string
*/ */
public function request(string $url, array $headers, $params): string public function request(string $url, array $headers, $params): string
{ {
$handle = curl_init($url); $handle = curl_init($url);
if ($handle === false) {
// throw Error here with all codes
throw AmazonErrors::getError(
'FAILURE',
'C001',
'CurlInitError',
'Failed to init curl with url: ' . $url,
0
);
}
curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($handle, CURLOPT_FAILONERROR, true); // curl_setopt($handle, CURLOPT_FAILONERROR, true);
@@ -39,13 +49,13 @@ class Client implements ClientInterface
$err = curl_errno($handle); $err = curl_errno($handle);
AmazonDebug::writeLog(['CURL_REQUEST_RESULT' => $result]); AmazonDebug::writeLog(['CURL_REQUEST_RESULT' => $result]);
// extract all the error codes from Amazon // extract all the error codes from Amazon
$result_ar = json_decode($result, true); $result_ar = json_decode((string)$result, true);
// if message is 'Rate exceeded', set different error // if message is 'Rate exceeded', set different error
if (($result_ar['message'] ?? '') == 'Rate exceeded') { if (($result_ar['message'] ?? '') == 'Rate exceeded') {
$error_status = 'RESEND'; $error_status = 'RESEND';
$error_code = 'T001'; $error_code = 'T001';
$error_type = 'RateExceeded'; $error_type = 'RateExceeded';
$message = $result_ar['message']; $message = $result_ar['message'] ?? 'Rate exceeded';
} else { } else {
// for all other error messages // for all other error messages
$error_status = $result_ar['agcodResponse']['status'] ?? 'FAILURE'; $error_status = $result_ar['agcodResponse']['status'] ?? 'FAILURE';
@@ -62,14 +72,14 @@ class Client implements ClientInterface
$err $err
); );
} }
return $result; return (string)$result;
} }
/** /**
* Undocumented function * Undocumented function
* *
* @param string $url * @param string $url
* @param string $errno * @param int $errno
* @param string $message * @param string $message
* @return void * @return void
*/ */
@@ -82,7 +92,6 @@ class Client implements ClientInterface
$message = 'Could not connect to AWS (' . $url . '). Please check your ' $message = 'Could not connect to AWS (' . $url . '). Please check your '
. 'internet connection and try again. [' . $message . ']'; . 'internet connection and try again. [' . $message . ']';
break; break;
case CURLE_SSL_CACERT:
case CURLE_SSL_PEER_CERTIFICATE: case CURLE_SSL_PEER_CERTIFICATE:
$message = 'Could not verify AWS SSL certificate. Please make sure ' $message = 'Could not verify AWS SSL certificate. Please make sure '
. 'that your network is not intercepting certificates. ' . 'that your network is not intercepting certificates. '
@@ -97,7 +106,7 @@ class Client implements ClientInterface
// throw an error like in the normal reqeust, but set to CURL error // throw an error like in the normal reqeust, but set to CURL error
throw AmazonErrors::getError( throw AmazonErrors::getError(
'FAILURE', 'FAILURE',
'C001', 'C002',
'CurlError', 'CurlError',
$message, $message,
$errno $errno

View File

@@ -5,13 +5,13 @@ namespace gullevek\AmazonIncentives\Client;
interface ClientInterface interface ClientInterface
{ {
/** /**
* @param string $url The URL being requested, including domain and protocol * @param string $url The URL being requested,
* @param array $headers Headers to be used in the request * including domain and protocol
* @param array|string $params Can be nested for arrays and hashes * @param array<mixed> $headers Headers to be used in the request
* @param array<mixed>|string $params Can be nested for arrays and hashes
* *
* @return String * @return String
*/ */
public function request(string $url, array $headers, $params): string; public function request(string $url, array $headers, $params): string;
} }

View File

@@ -7,27 +7,27 @@ class Config implements ConfigInterface
/** /**
* @var string * @var string
*/ */
private $endpoint; private $endpoint = '';
/** /**
* @var string * @var string
*/ */
private $access_key; private $access_key = '';
/** /**
* @var string * @var string
*/ */
private $secret_key; private $secret_key = '';
/** /**
* @var string * @var string
*/ */
private $partner_id; private $partner_id = '';
/** /**
* @var string * @var string
*/ */
private $currency; private $currency = '';
/** /**
* @var bool * @var bool
*/ */
private $debug; private $debug = false;
/** /**
* @param string|null $key * @param string|null $key
@@ -42,14 +42,38 @@ class Config implements ConfigInterface
?string $partner, ?string $partner,
?string $endpoint, ?string $endpoint,
?string $currency, ?string $currency,
?bool $debug, ?bool $debug
) { ) {
$this->setAccessKey($key ?: $this->parseEnv('AWS_GIFT_CARD_KEY')); /**
$this->setSecret($secret ?: $this->parseEnv('AWS_GIFT_CARD_SECRET')); * @psalm-suppress InvalidScalarArgument
$this->setPartner($partner ?: $this->parseEnv('AWS_GIFT_CARD_PARTNER_ID')); * @phpstan-ignore-next-line
$this->setEndpoint($endpoint ?: $this->parseEnv('AWS_GIFT_CARD_ENDPOINT')); */
$this->setCurrency($currency ?: $this->parseEnv('AWS_GIFT_CARD_CURRENCY')); $this->setAccessKey(($key) ?: $this->parseEnv('AWS_GIFT_CARD_KEY'));
$this->setDebug($debug ?: $this->parseEnv('AWS_DEBUG')); /**
* @psalm-suppress InvalidScalarArgument
* @phpstan-ignore-next-line
*/
$this->setSecret(($secret) ?: $this->parseEnv('AWS_GIFT_CARD_SECRET'));
/**
* @psalm-suppress InvalidScalarArgument
* @phpstan-ignore-next-line
*/
$this->setPartner(($partner) ?: $this->parseEnv('AWS_GIFT_CARD_PARTNER_ID'));
/**
* @psalm-suppress InvalidScalarArgument
* @phpstan-ignore-next-line
*/
$this->setEndpoint(($endpoint) ?: $this->parseEnv('AWS_GIFT_CARD_ENDPOINT'));
/**
* @psalm-suppress InvalidScalarArgument
* @phpstan-ignore-next-line
*/
$this->setCurrency(($currency) ?: $this->parseEnv('AWS_GIFT_CARD_CURRENCY'));
/**
* @psalm-suppress InvalidScalarArgument
* @phpstan-ignore-next-line
*/
$this->setDebug(($debug) ?: $this->parseEnv('AWS_DEBUG'));
} }
/** /**
@@ -80,9 +104,9 @@ class Config implements ConfigInterface
} }
/** /**
* @return string|null * @return string
*/ */
public function getEndpoint(): ?string public function getEndpoint(): string
{ {
return $this->endpoint; return $this->endpoint;
} }
@@ -94,15 +118,15 @@ class Config implements ConfigInterface
public function setEndpoint(string $endpoint): ConfigInterface public function setEndpoint(string $endpoint): ConfigInterface
{ {
// TODO: check valid endpoint + set region // TODO: check valid endpoint + set region
$this->endpoint = parse_url($endpoint, PHP_URL_HOST); $this->endpoint = (parse_url($endpoint, PHP_URL_HOST)) ?: '';
return $this; return $this;
} }
/** /**
* @return string|null * @return string
*/ */
public function getAccessKey(): ?string public function getAccessKey(): string
{ {
return $this->access_key; return $this->access_key;
} }
@@ -119,9 +143,9 @@ class Config implements ConfigInterface
} }
/** /**
* @return string|null * @return string
*/ */
public function getSecret(): ?string public function getSecret(): string
{ {
return $this->secret_key; return $this->secret_key;
} }
@@ -138,9 +162,9 @@ class Config implements ConfigInterface
} }
/** /**
* @return string|null * @return string
*/ */
public function getCurrency(): ?string public function getCurrency(): string
{ {
return $this->currency; return $this->currency;
} }
@@ -158,9 +182,9 @@ class Config implements ConfigInterface
} }
/** /**
* @return string|null * @return string
*/ */
public function getPartner(): ?string public function getPartner(): string
{ {
return $this->partner_id; return $this->partner_id;
} }
@@ -177,9 +201,9 @@ class Config implements ConfigInterface
} }
/** /**
* @return bool|null * @return bool
*/ */
public function getDebug(): ?bool public function getDebug(): bool
{ {
return $this->debug; return $this->debug;
} }

View File

@@ -5,68 +5,68 @@ namespace gullevek\AmazonIncentives\Config;
interface ConfigInterface interface ConfigInterface
{ {
/** /**
* @return string|null * @return string
*/ */
public function getEndpoint(): ?string; public function getEndpoint(): string;
/** /**
* @param string $endpoint * @param string $endpoint
* @return $this * @return ConfigInterface
*/ */
public function setEndpoint(string $endpoint): ConfigInterface; public function setEndpoint(string $endpoint): ConfigInterface;
/** /**
* @return string|null * @return string
*/ */
public function getAccessKey(): ?string; public function getAccessKey(): string;
/** /**
* @param string $key * @param string $key
* @return $this * @return ConfigInterface
*/ */
public function setAccessKey(string $key): ConfigInterface; public function setAccessKey(string $key): ConfigInterface;
/** /**
* @return string|null * @return string
*/ */
public function getSecret(): ?string; public function getSecret(): string;
/** /**
* @param string $secret * @param string $secret
* @return $this * @return ConfigInterface
*/ */
public function setSecret(string $secret): ConfigInterface; public function setSecret(string $secret): ConfigInterface;
/** /**
* @return string|null * @return string
*/ */
public function getCurrency(): ?string; public function getCurrency(): string;
/** /**
* @param string $currency * @param string $currency
* @return $this * @return ConfigInterface
*/ */
public function setCurrency(string $currency): ConfigInterface; public function setCurrency(string $currency): ConfigInterface;
/** /**
* @return string|null * @return string
*/ */
public function getPartner(): ?string; public function getPartner(): string;
/** /**
* @param string $partner * @param string $partner
* @return $this * @return ConfigInterface
*/ */
public function setPartner(string $partner): ConfigInterface; public function setPartner(string $partner): ConfigInterface;
/** /**
* @return bool|null * @return bool
*/ */
public function getDebug(): ?bool; public function getDebug(): bool;
/** /**
* @param bool $debug * @param bool $debug
* @return $this * @return ConfigInterface
*/ */
public function setDebug(bool $debug): ConfigInterface; public function setDebug(bool $debug): ConfigInterface;
} }

View File

@@ -7,8 +7,17 @@ namespace gullevek\AmazonIncentives\Debug;
class AmazonDebug class AmazonDebug
{ {
/**
* @var array<mixed>
*/
private static $log = []; private static $log = [];
/**
* @var bool
*/
private static $debug = false; private static $debug = false;
/**
* @var string|null
*/
private static $id = null; private static $id = null;
/** /**
@@ -74,7 +83,7 @@ class AmazonDebug
* Will be pushed as new array entry int log * Will be pushed as new array entry int log
* Main key is the set Id for this run * Main key is the set Id for this run
* *
* @param array $data Any array data to store in the log * @param array<mixed> $data Any array data to store in the log
* @return void * @return void
*/ */
public static function writeLog(array $data): void public static function writeLog(array $data): void
@@ -82,7 +91,7 @@ class AmazonDebug
if (self::$debug === false) { if (self::$debug === false) {
return; return;
} }
self::$log[self::getId()][] = $data; self::$log[self::getId() ?? ''][] = $data;
} }
/** /**
@@ -91,7 +100,7 @@ class AmazonDebug
* *
* @param string|null $id If set returns only this id logs * @param string|null $id If set returns only this id logs
* or empty array if not found * or empty array if not found
* @return array Always array, empty if not data or not found * @return array<mixed> Always array, empty if not data or not found
*/ */
public static function getLog(?string $id = null): array public static function getLog(?string $id = null): array
{ {

View File

@@ -5,14 +5,14 @@ namespace gullevek\AmazonIncentives\Exceptions;
use RuntimeException; use RuntimeException;
use gullevek\AmazonIncentives\Debug\AmazonDebug; use gullevek\AmazonIncentives\Debug\AmazonDebug;
class AmazonErrors extends RuntimeException final class AmazonErrors extends RuntimeException
{ {
/** /**
* @param string $error_status agcodResponse->status from Amazon * @param string $error_status agcodResponse->status from Amazon
* @param string $error_code errorCode from Amazon * @param string $error_code errorCode from Amazon
* @param string $error_type errorType from Amazon * @param string $error_type errorType from Amazon
* @param string $message * @param string $message
* @param string $_error_code * @param int $_error_code
* @return AmazonErrors * @return AmazonErrors
*/ */
public static function getError( public static function getError(
@@ -20,11 +20,11 @@ class AmazonErrors extends RuntimeException
string $error_code, string $error_code,
string $error_type, string $error_type,
string $message, string $message,
string $_error_code int $_error_code
): self { ): self {
// NOTE: if xdebug.show_exception_trace is set to 1 this will print ERRORS // NOTE: if xdebug.show_exception_trace is set to 1 this will print ERRORS
return new static( return new static(
json_encode([ (json_encode([
'status' => $error_status, 'status' => $error_status,
'code' => $error_code, 'code' => $error_code,
'type' => $error_type, 'type' => $error_type,
@@ -32,7 +32,7 @@ class AmazonErrors extends RuntimeException
// atach log data if exists // atach log data if exists
'log_id' => AmazonDebug::getId(), 'log_id' => AmazonDebug::getId(),
'log' => AmazonDebug::getLog(), 'log' => AmazonDebug::getLog(),
]), ])) ?: 'AmazonErrors: json encode problem: ' . $message,
$_error_code $_error_code
); );
} }

View File

@@ -2,7 +2,6 @@
namespace gullevek\AmazonIncentives\Response; namespace gullevek\AmazonIncentives\Response;
use gullevek\AmazonIncentives\Exceptions\AmazonErrors;
use gullevek\AmazonIncentives\Debug\AmazonDebug; use gullevek\AmazonIncentives\Debug\AmazonDebug;
class CancelResponse class CancelResponse
@@ -12,47 +11,42 @@ class CancelResponse
* *
* @var string * @var string
*/ */
protected $id; protected $id = '';
/** /**
* Amazon Gift Card creationRequestId * Amazon Gift Card creationRequestId
* *
* @var string * @var string
*/ */
protected $creation_request_id; protected $creation_request_id = '';
/** /**
* Amazon Gift Card status * Amazon Gift Card status
* *
* @var string * @var string
*/ */
protected $status; protected $status = '';
/** /**
* Amazon Gift Card Raw JSON * Amazon Gift Card Raw JSON
* *
* @var string * @var array<mixed>
*/ */
protected $raw_json; protected $raw_json = [];
/**
* @var array
*/
protected $log;
/** /**
* Response constructor. * Response constructor.
* @param array $json_response * @param array<mixed> $json_response
*/ */
public function __construct(array $json_response) public function __construct(array $json_response)
{ {
$this->raw_json = $json_response; $this->raw_json = $json_response;
$this->log = AmazonDebug::getLog(AmazonDebug::getId());
$this->parseJsonResponse($json_response); $this->parseJsonResponse($json_response);
} }
/** /**
* @return array * @return array<mixed>
*/ */
public function getLog(): array public function getLog(): array
{ {
return $this->log; return AmazonDebug::getLog(AmazonDebug::getId());
} }
/** /**
@@ -84,24 +78,15 @@ class CancelResponse
*/ */
public function getRawJson(): string public function getRawJson(): string
{ {
return json_encode($this->raw_json); return (json_encode($this->raw_json)) ?: '';
} }
/** /**
* @param array $json_response * @param array<mixed> $json_response
* @return CancelResponse * @return CancelResponse
*/ */
public function parseJsonResponse(array $json_response): self public function parseJsonResponse(array $json_response): self
{ {
if (!is_array($json_response)) {
throw AmazonErrors::getError(
'FAILURE',
'E001',
'NonScalarValue',
'Response must be a scalar value',
0
);
}
if (array_key_exists('gcId', $json_response)) { if (array_key_exists('gcId', $json_response)) {
$this->id = $json_response['gcId']; $this->id = $json_response['gcId'];
} }

View File

@@ -2,7 +2,6 @@
namespace gullevek\AmazonIncentives\Response; namespace gullevek\AmazonIncentives\Response;
use gullevek\AmazonIncentives\Exceptions\AmazonErrors;
use gullevek\AmazonIncentives\Debug\AmazonDebug; use gullevek\AmazonIncentives\Debug\AmazonDebug;
class CreateBalanceResponse class CreateBalanceResponse
@@ -12,54 +11,49 @@ class CreateBalanceResponse
* *
* @var string * @var string
*/ */
protected $amount; protected $amount = '';
/** /**
* Amazon Gift Card Balance Currency * Amazon Gift Card Balance Currency
* *
* @var string * @var string
*/ */
protected $currency; protected $currency = '';
/** /**
* Amazon Gift Card Balance Status * Amazon Gift Card Balance Status
* *
* @var string * @var string
*/ */
protected $status; protected $status = '';
/** /**
* Amazon Gift Card Balance Timestamp * Amazon Gift Card Balance Timestamp
* *
* @var string * @var string
*/ */
protected $timestamp; protected $timestamp = '';
/** /**
* Amazon Gift Card Raw JSON * Amazon Gift Card Raw JSON
* *
* @var string * @var array<mixed>
*/ */
protected $raw_json; protected $raw_json = [];
/**
* @var array
*/
protected $log;
/** /**
* Response constructor. * Response constructor.
* *
* @param array $json_response * @param array<mixed> $json_response
*/ */
public function __construct(array $json_response) public function __construct(array $json_response)
{ {
$this->raw_json = $json_response; $this->raw_json = $json_response;
$this->log = AmazonDebug::getLog(AmazonDebug::getId());
$this->parseJsonResponse($json_response); $this->parseJsonResponse($json_response);
} }
/** /**
* @return array * @return array<mixed>
*/ */
public function getLog(): array public function getLog(): array
{ {
return $this->log; return AmazonDebug::getLog(AmazonDebug::getId());
} }
/** /**
@@ -99,26 +93,17 @@ class CreateBalanceResponse
*/ */
public function getRawJson(): string public function getRawJson(): string
{ {
return json_encode($this->raw_json); return (json_encode($this->raw_json)) ?: '';
} }
/** /**
* Undocumented function * Undocumented function
* *
* @param array $json_response * @param array<mixed> $json_response
* @return CreateBalanceResponse * @return CreateBalanceResponse
*/ */
public function parseJsonResponse(array $json_response): self public function parseJsonResponse(array $json_response): self
{ {
if (!is_array($json_response)) {
throw AmazonErrors::getError(
'FAILURE',
'E001',
'NonScalarValue',
'Response must be a scalar value',
0
);
}
if (array_key_exists('amount', $json_response['availableFunds'])) { if (array_key_exists('amount', $json_response['availableFunds'])) {
$this->amount = $json_response['availableFunds']['amount']; $this->amount = $json_response['availableFunds']['amount'];
} }

View File

@@ -2,7 +2,6 @@
namespace gullevek\AmazonIncentives\Response; namespace gullevek\AmazonIncentives\Response;
use gullevek\AmazonIncentives\Exceptions\AmazonErrors;
use gullevek\AmazonIncentives\Debug\AmazonDebug; use gullevek\AmazonIncentives\Debug\AmazonDebug;
class CreateResponse class CreateResponse
@@ -12,81 +11,76 @@ class CreateResponse
* *
* @var string * @var string
*/ */
protected $id; protected $id = '';
/** /**
* Amazon Gift Card creationRequestId * Amazon Gift Card creationRequestId
* *
* @var string * @var string
*/ */
protected $creation_request_id; protected $creation_request_id = '';
/** /**
* Amazon Gift Card gcClaimCode * Amazon Gift Card gcClaimCode
* *
* @var string * @var string
*/ */
protected $claim_code; protected $claim_code = '';
/** /**
* Amazon Gift Card amount * Amazon Gift Card amount
* *
* @var float * @var float
*/ */
protected $value; protected $value = 0;
/** /**
* Amazon Gift Card currency * Amazon Gift Card currency
* *
* @var string * @var string
*/ */
protected $currency; protected $currency = '';
/** /**
* Amazon Gift Card status * Amazon Gift Card status
* *
* @var string * @var string
*/ */
protected $status; protected $status = '';
/** /**
* Amazon Gift Card Expiration Date * Amazon Gift Card Expiration Date
* *
* @var string * @var string
*/ */
protected $expiration_date; protected $expiration_date = '';
/** /**
* Amazon Gift Card Expiration Date * Amazon Gift Card Expiration Date
* *
* @var string * @var string
*/ */
protected $card_status; protected $card_status = '';
/** /**
* Amazon Gift Card Raw JSON * Amazon Gift Card Raw JSON
* *
* @var string * @var array<mixed>
*/ */
protected $raw_json; protected $raw_json = [];
/**
* @var array
*/
protected $log;
/** /**
* Response constructor. * Response constructor.
* @param array $json_response * @param array<mixed> $json_response
*/ */
public function __construct(array $json_response) public function __construct(array $json_response)
{ {
$this->raw_json = $json_response; $this->raw_json = $json_response;
$this->log = AmazonDebug::getLog(AmazonDebug::getId());
$this->parseJsonResponse($json_response); $this->parseJsonResponse($json_response);
} }
/** /**
* @return array * @return array<mixed>
*/ */
public function getLog(): array public function getLog(): array
{ {
return $this->log; return AmazonDebug::getLog(AmazonDebug::getId());
} }
/** /**
@@ -114,9 +108,9 @@ class CreateResponse
} }
/** /**
* @return string * @return float
*/ */
public function getValue(): string public function getValue(): float
{ {
return $this->value; return $this->value;
} }
@@ -159,24 +153,15 @@ class CreateResponse
*/ */
public function getRawJson(): string public function getRawJson(): string
{ {
return json_encode($this->raw_json); return (json_encode($this->raw_json)) ?: '';
} }
/** /**
* @param array $json_response * @param array<array-key,mixed|array> $json_response
* @return CreateResponse * @return CreateResponse
*/ */
public function parseJsonResponse(array $json_response): self public function parseJsonResponse(array $json_response): self
{ {
if (!is_array($json_response)) {
throw AmazonErrors::getError(
'FAILURE',
'E001',
'NonScalarValue',
'Response must be a scalar value',
0
);
}
if (array_key_exists('gcId', $json_response)) { if (array_key_exists('gcId', $json_response)) {
$this->id = $json_response['gcId']; $this->id = $json_response['gcId'];
} }

7
test/.env.example Normal file
View File

@@ -0,0 +1,7 @@
# for AWS gift card testing
AWS_GIFT_CARD_ENDPOINT=
AWS_GIFT_CARD_KEY=
AWS_GIFT_CARD_SECRET=
AWS_GIFT_CARD_PARTNER_ID=
AWS_GIFT_CARD_CURRENCY=
AWS_DEBUG=

View File

@@ -6,7 +6,7 @@
* write log as string from array data * write log as string from array data
* includes timestamp * includes timestamp
* *
* @param array $data Debug log array data to add to the json string * @param array<mixed> $data Debug log array data to add to the json string
* @return string * @return string
*/ */
function writeLog(array $data): string function writeLog(array $data): string
@@ -25,7 +25,7 @@ function writeLog(array $data): string
*/ */
function dateTr(string $date): string function dateTr(string $date): string
{ {
return date('Y-m-d H:i:s', strtotime($date)); return date('Y-m-d H:i:s', (strtotime($date)) ?: null);
} }
/** /**
@@ -33,7 +33,7 @@ function dateTr(string $date): string
* *
* @param string $call_request Call request, eg buyGiftCard * @param string $call_request Call request, eg buyGiftCard
* @param integer $error_code $e Exception error code * @param integer $error_code $e Exception error code
* @param array $error Array from the Exception message json string * @param array<mixed> $error Array from the Exception message json string
* @param boolean $debug_print If we should show the debug log * @param boolean $debug_print If we should show the debug log
* @return void * @return void
*/ */
@@ -76,23 +76,11 @@ print "<h1>Amazon Gift Card Incentives</h1><br>";
// optional // optional
// debug: AWS_DEBUG (if not set: off) // debug: AWS_DEBUG (if not set: off)
// as in .env
// AWS_GIFT_CARD_ENDPOINT.TEST
// AWS_GIFT_CARD_ENDPOINT.LIVE
define('LOCATION', 'test');
foreach (
[
'AWS_GIFT_CARD_KEY', 'AWS_GIFT_CARD_SECRET', 'AWS_GIFT_CARD_PARTNER_ID',
'AWS_GIFT_CARD_ENDPOINT', 'AWS_GIFT_CARD_CURRENCY', 'AWS_DEBUG'
] as $key
) {
//
$_ENV[$key] = $_ENV[$key . '.' . strtoupper((LOCATION))] ?? $_ENV[$key] ?? '';
}
// open debug file output // open debug file output
$fp = fopen('log/debug.' . date('YmdHis') . '.log', 'w'); $fp = fopen('log/debug.' . date('YmdHis') . '.log', 'w');
if (!is_resource($fp)) {
die("Cannot open log debug file");
}
// run info test (prints ENV vars) // run info test (prints ENV vars)
$run_info_test = false; $run_info_test = false;
@@ -193,6 +181,28 @@ if ($run_gift_tests === true) {
} }
print "<br>"; print "<br>";
sleep($debug_wait); sleep($debug_wait);
// request same card again and get error
try {
$aws_test = AmazonIncentives::make()->buyGiftCard((float)$value, $creation_request_id);
$request_status = $aws_test->getStatus();
// same?
$claim_code = $aws_test->getClaimCode();
$expiration_date = $aws_test->getExpirationDate();
print "AWS: buyGiftCard: CANCLED SAME CODE AGAIN: " . $request_status . ": "
. "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", "
. "EXPIRE DATE: <b>" . dateTr($expiration_date) . "</b>, "
. "CLAIM CODE: <b>" . $claim_code . "</b>";
if ($debug_print === true) {
print "<pre>" . print_r($aws_test, true) . "</pre>";
}
fwrite($fp, writeLog((array)$aws_test));
} catch (\Exception $e) {
$error = AmazonIncentives::decodeExceptionMessage($e->getMessage());
printException('buyGiftCard', $e->getCode(), $error, $debug_print);
fwrite($fp, writeLog($error));
}
print "<br>";
sleep($debug_wait);
// set same request ID twice to get same response test // set same request ID twice to get same response test
try { try {
@@ -221,6 +231,7 @@ if ($run_gift_tests === true) {
$aws_test = AmazonIncentives::make()->buyGiftCard((float)$value, $creation_request_id); $aws_test = AmazonIncentives::make()->buyGiftCard((float)$value, $creation_request_id);
$request_status = $aws_test->getStatus(); $request_status = $aws_test->getStatus();
// same? // same?
$claim_code = $aws_test->getClaimCode();
$expiration_date = $aws_test->getExpirationDate(); $expiration_date = $aws_test->getExpirationDate();
print "AWS: buyGiftCard: SAME CODE A AGAIN: " . $request_status . ": " print "AWS: buyGiftCard: SAME CODE A AGAIN: " . $request_status . ": "
. "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", "
@@ -241,10 +252,11 @@ if ($run_gift_tests === true) {
} }
// MOCK TEST // MOCK TEST
if ($mock_debug === true) { if ($run_mocks === true) {
$mock_ok = '<span style="color:green;">MOCK OK</span>'; $mock_ok = '<span style="color:green;">MOCK OK</span>';
$mock_failure = '<span style="color:red;">MOCK FAILURE</span>'; $mock_failure = '<span style="color:red;">MOCK FAILURE</span>';
$mock_value = 500; $mock_value = 500;
$mock = [];
$mock['F0000'] = [ 'ret' => '', 'st' => 'SUCCESS']; // success mock $mock['F0000'] = [ 'ret' => '', 'st' => 'SUCCESS']; // success mock
$mock['F1000'] = [ 'ret' => 'F100', 'st' => 'FAILURE']; // SimpleAmountIsNull, etc $mock['F1000'] = [ 'ret' => 'F100', 'st' => 'FAILURE']; // SimpleAmountIsNull, etc