diff --git a/app.php b/app.php new file mode 100644 index 0000000..df271e7 --- /dev/null +++ b/app.php @@ -0,0 +1,34 @@ + "Jane", + "lastName" => "Doe", + "email" => "jane.doe@example.com", + "phone" => "", + "status" => false +]; + +$data = json_encode($test); + +$enc = \Retargeting\Helpers\Encryption::encrypt($data); + +var_dump($enc); + + +//try { +// $dec = (new Retargeting\Helpers\Decryption())->decrypt($enc); +//} catch (\Retargeting\Exceptions\DecryptException $e) { +//} +// +//var_dump($dec); +// +// +//var_dump(\Retargeting\Helpers\Token::createRandomToken()); \ No newline at end of file diff --git a/composer.json b/composer.json index b8e91f4..adcf21e 100644 --- a/composer.json +++ b/composer.json @@ -9,16 +9,17 @@ } ], "require": { - "php": ">=7.0.0", - "ext-json": "*" + "php": ">=5.6.0", + "ext-json": "*", + "ext-openssl": "*" }, "autoload": { "psr-4": { - "Retargeting\\": "lib" + "RetargetingSDK\\": "lib" } }, "require-dev": { - "phpunit/phpunit": "^8.0", + "phpunit/phpunit": "8.0", "mockery/mockery": "^1.0", "fzaninotto/faker": "^1.4" }, @@ -26,5 +27,13 @@ "psr-4": { "Tests\\": "tests/" } + }, + "config": { + "preferred-install": "dist", + "sort-packages": true, + "optimize-autoloader": true, + "platform": { + "php": "5.6.0" + } } } diff --git a/composer.lock b/composer.lock index b8902f5..a852cbb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,32 +4,34 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a53aa27fc92345d16984371263c548ee", + "content-hash": "88e7e2fb42005ec60364302425bb6b5f", "packages": [], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { @@ -54,12 +56,12 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2019-03-17T17:37:11+00:00" }, { "name": "fzaninotto/faker", @@ -591,40 +593,40 @@ }, { "name": "phpunit/php-code-coverage", - "version": "7.0.2", + "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "cfca9c5f7f2694ca0c7749ffb142927d9f05250f" + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cfca9c5f7f2694ca0c7749ffb142927d9f05250f", - "reference": "cfca9c5f7f2694ca0c7749ffb142927d9f05250f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.2", - "phpunit/php-file-iterator": "^2.0.2", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0.1", + "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^4.1", + "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^7.0" }, "suggest": { - "ext-xdebug": "^2.6.1" + "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "6.1-dev" } }, "autoload": { @@ -650,7 +652,7 @@ "testing", "xunit" ], - "time": "2019-02-15T13:40:27+00:00" + "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", @@ -843,16 +845,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.0.4", + "version": "7.5.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a7af0201285445c9c73c4bdf869c486e36b41604" + "reference": "eb343b86753d26de07ecba7868fa983104361948" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7af0201285445c9c73c4bdf869c486e36b41604", - "reference": "a7af0201285445c9c73c4bdf869c486e36b41604", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/eb343b86753d26de07ecba7868fa983104361948", + "reference": "eb343b86753d26de07ecba7868fa983104361948", "shasum": "" }, "require": { @@ -862,25 +864,27 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.2", "phar-io/version": "^2.0", - "php": "^7.2", + "php": "^7.1", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^7.0", + "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", + "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", - "sebastian/environment": "^4.1", + "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", - "sebastian/global-state": "^3.0", + "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, "require-dev": { "ext-pdo": "*" }, @@ -895,7 +899,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.0-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -921,7 +925,7 @@ "testing", "xunit" ], - "time": "2019-02-18T09:23:05+00:00" + "time": "2019-03-16T07:31:17+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -1210,26 +1214,23 @@ }, { "name": "sebastian/global-state", - "version": "3.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", - "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { - "php": "^7.2", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": "^7.0" }, "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -1237,7 +1238,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1260,7 +1261,7 @@ "keywords": [ "global state" ], - "time": "2019-02-01T05:30:01+00:00" + "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", @@ -1494,16 +1495,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + "reference": "82ebae02209c21113908c229e9883c419720738a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", "shasum": "" }, "require": { @@ -1515,7 +1516,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.11-dev" } }, "autoload": { @@ -1537,7 +1538,7 @@ }, { "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "email": "backendtea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -1548,7 +1549,7 @@ "polyfill", "portable" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2019-02-06T07:57:58+00:00" }, { "name": "theseer/tokenizer", @@ -1648,7 +1649,12 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.0.0" + "php": ">=7.2.0", + "ext-json": "*", + "ext-openssl": "*" }, - "platform-dev": [] + "platform-dev": [], + "platform-overrides": { + "php": "7.2.0" + } } diff --git a/lib/AbstractRetargetingSDK.php b/lib/AbstractRetargetingSDK.php index fde50cb..5a6434a 100644 --- a/lib/AbstractRetargetingSDK.php +++ b/lib/AbstractRetargetingSDK.php @@ -5,20 +5,92 @@ * Date: 2019-02-19 * Time: 07:48 */ -namespace Retargeting; + +namespace RetargetingSDK; + +use RetargetingSDK\Helpers\UrlHelper; + /** * Class AbstractRetargetingSDK */ abstract class AbstractRetargetingSDK { - /** * @param array $data * @return string */ - public function toJSON(array $data): string + public function toJSON(array $data) { return json_encode($data, JSON_PRETTY_PRINT); } + /** + * Get proper formatted string + * @param $text + * @return string + */ + public function getProperFormattedString($text) + { + $text = (string)$text; + + if ((bool)$text) { + return trim(strip_tags(html_entity_decode( + html_entity_decode($text), + ENT_QUOTES | ENT_COMPAT, + 'UTF-8'))); + } else { + return ''; + } + } + + /** + * Parse correct format of given data + * @param $value + * @return float|int|string + */ + public function formatIntFloatString($value) + { + + if(!is_numeric($value)) + { + return 0; + } + + if($this->isFloat($value)) + { + return (float)$value; + } + else if(!$this->isFloat($value)) + { + return (int)$value; + } + else + { + return $this->getProperFormattedString($value); + } + } + + /** + * Is value float or not + * @param $num + * @return bool + */ + function isFloat($num) + { + return is_float($num) || is_numeric($num) && ((float) $num != (int) $num); + } + + /** + * Format url from an array + * @param $array + * @return array + */ + public function validateArrayData($array) + { + $mappedArray = array_map(function($item){ + return UrlHelper::validate($item); + }, $array); + + return $mappedArray; + } } \ No newline at end of file diff --git a/lib/Api/Client.php b/lib/Api/Client.php new file mode 100644 index 0000000..7cf80c2 --- /dev/null +++ b/lib/Api/Client.php @@ -0,0 +1,202 @@ +api_key = $api_key; + } else { + $this->_throwException("checkApiKey"); + } + } + + /** + * Method: set a new API uri + * @param string $api_uri + */ + public function setApiUri($api_uri) { + if (is_string($api_uri) && !empty($api_uri)) { + $this->api_uri = $api_uri; + } else { + $this->_throwException("apiUriType"); + } + } + + /** + * Method: set a new API version + * @param string $api_version + */ + public function setApiVersion($api_version) + { + if (is_string($api_version) && !empty($api_version)) { + $this->api_version = $api_version; + } else { + $this->_throwException("apiVersionType"); + } + } + + /** + * Method: set a new API response format: json or serial (php serialize) + * @param string $response_format + */ + public function setResponseFormat($response_format = "json") + { + if (in_array($response_format, ["json", "serial"])) { + $this->response_format = $response_format; + } else { + $this->_throwException("responseFormat"); + } + } + + /** + * Method: set encoding for API response + * @param bool $mode + */ + public function setDecoding($mode = true) + { + if (is_bool($mode)) { + $this->decoding = $mode; + } else { + $this->_throwException("decodingMode"); + } + } + + /** + * Overloading method: is utilized for reading data from inaccessible properties + * @param string $name + * @return Retargeting_REST_API_Client + */ + public function __get($name) + { + $this->api_path[] = $name; + return $this; + } + + /** + * Overloading method: is triggered when invoking inaccessible methods in an object context + * @param string $name + * @param array $arguments + * @see _processRequest() + * @return array + */ + public function __call($name, $arguments) + { + $this->api_path[] = $name; + $this->api_parameters = $arguments; + return $this->_processRequest(); + } + + /** + * Method: use PHP cURL library to connect with Retargeting REST API and send the request + * @see http://php.net/manual/ro/book.curl.php + * @return array + */ + private function _processRequest() + { + if (empty($this->api_path)) { + $this->_throwException("emptyApiPath"); + } + + $api_uri = $this->api_uri."/".$this->api_version."/".implode("/", $this->api_path).".".$this->response_format; + + $this->api_path = []; + + $api_parameters = [ + "api_key" => $this->api_key + ]; + + $api_parameters = http_build_query(array_merge($api_parameters, $this->api_parameters)); + $this->api_parameters = []; + + $curl_request = curl_init(); + curl_setopt($curl_request, CURLOPT_URL, $api_uri); + curl_setopt($curl_request, CURLOPT_TIMEOUT, 30); + curl_setopt($curl_request, CURLOPT_POST, true); + curl_setopt($curl_request, CURLOPT_POSTFIELDS, $api_parameters); + curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false); + + if ($this->decoding) { + if ($this->response_format == "json") { + return json_decode(curl_exec($curl_request), true); + } elseif ($this->response_format == "serial") { + return unserialize(curl_exec($curl_request)); + } + } + + return curl_exec($curl_request); + } + + /**_throwException + * Method: throw new exception with custom message + * @param string $message + * @throws \Exception + */ + private function _throwException($message) + { + $messages = [ + "checkApiKey" => "You need an API KEY to use Retargeting API. Please go to your Retargeting Administration Panel to set up or check your API KEY.", + "apiUriType" => "The API uri must be string", + "apiVersionType" => "The API version must be a string", + "responseFormat" => "The response format can only be json or serial (php serialize)", + "decodingMode" => "Decoding must be boolean", + "emptyApiPath" => "You API request is empty" + ]; + + throw new \Exception($messages[$message]); + } +} \ No newline at end of file diff --git a/lib/Api/Customers.php b/lib/Api/Customers.php new file mode 100644 index 0000000..5171106 --- /dev/null +++ b/lib/Api/Customers.php @@ -0,0 +1,149 @@ +token = $token; + } + + /** + * @return mixed + */ + public function getToken() + { + return $this->token; + } + + /** + * @param mixed $token + */ + public function setToken($token) + { + $this->token = $token; + } + + /** + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * @param mixed $data + */ + public function setData($data) + { + $this->data = $data; + } + + /** + * @return mixed + */ + public function getCurrentPage() + { + return $this->currentPage; + } + + /** + * @param mixed $currentPage + */ + public function setCurrentPage($currentPage) + { + $this->currentPage = $currentPage; + } + + /** + * @return mixed + */ + public function getLastPage() + { + return $this->lastPage; + } + + /** + * @param mixed $lastPage + */ + public function setLastPage($lastPage) + { + $this->lastPage = $lastPage; + } + + /** + * @return mixed + */ + public function getNextPage() + { + return $this->nextPage; + } + + /** + * @param mixed $nextPage + */ + public function setNextPage($nextPage) + { + $this->nextPage = $nextPage; + } + + /** + * @return mixed + */ + public function getPrevPage() + { + return $this->prevPage; + } + + /** + * @param mixed $prevPage + */ + public function setPrevPage($prevPage) + { + $this->prevPage = $prevPage; + } + + /** + * Prepare customers api information + * @throws \Exception + */ + public function prepareCustomersApiInfo() + { + return $this->toJSON([ + 'data' => $this->getData(), + "current_page" => $this->getCurrentPage(), + "last_page" => $this->getLastPage(), + "next_page" => $this->getNextPage(), + "prev_page" => $this->getPrevPage() + ]); + } +} diff --git a/lib/Api/StockManagement.php b/lib/Api/StockManagement.php new file mode 100644 index 0000000..082a192 --- /dev/null +++ b/lib/Api/StockManagement.php @@ -0,0 +1,170 @@ +productId; + } + + /** + * @param mixed $productId + */ + public function setProductId($productId) + { + $this->productId = $productId; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + + /** + * @param mixed $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return mixed + */ + public function getPrice() + { + return $this->price; + } + + /** + * @param mixed $price + */ + public function setPrice($price) + { + $this->price = $price; + } + + /** + * @return mixed + */ + public function getPromo() + { + return $this->promo; + } + + /** + * @param mixed $promo + */ + public function setPromo($promo) + { + $this->promo = $promo; + } + + /** + * @return bool + */ + public function isStock() + { + return $this->stock; + } + + /** + * @param bool $stock + */ + public function setStock($stock) + { + $this->stock = $stock; + } + + /** + * @return mixed + */ + public function getImage() + { + return $this->image; + } + + /** + * @param mixed $image + */ + public function setImage($image) + { + $this->image = $image; + } + + /** + * @return mixed + */ + public function getUrl() + { + return $this->url; + } + + /** + * @param mixed $url + */ + public function setUrl($url) + { + $this->url = $url; + } + + /** + * Prepare stock information + * @return array + */ + public function prepareStockInfo() + { + return [ + 'productId' => $this->getProductId(), + 'name' => $this->getName(), + 'price' => $this->getPrice(), + 'promo' => $this->getPromo(), + 'image' => $this->getImage(), + 'url' => $this->getUrl(), + 'stock' => $this->isStock(), + ]; + } + + /** + * Update product stock + * @param $api + * @param $product + * @throws RTGException + */ + public function updateStock($api, $product) + { + try { + $rtgClient = new Client($api); + $rtgClient->setResponseFormat("json"); + $rtgClient->setDecoding(false); + $rtgClient->products->update($product); + } catch(RTGException $exception) { + throw new RTGException($exception->getMessage()); + } + } +} \ No newline at end of file diff --git a/lib/Api/readme.md b/lib/Api/readme.md new file mode 100644 index 0000000..8f867a7 --- /dev/null +++ b/lib/Api/readme.md @@ -0,0 +1,77 @@ +# REST API Response examples + +## Customers + +Each customer object must be encrypted using Encryption Helpers. When you develop this API Endpoint, you can leave it plain. + +Response example (plain) + +```json + +{ + "data" : [ + { + "firstName": "John", + "lastName": "Doe", + "email": "john.doe@example.com", + "phone": "0770123456", + "status": true + }, + { + "firstName": "Jane", + "lastName": "Doe", + "email": "jane.doe@example.com", + "phone": "", + "status": false + } + ], + "current_page": 1, + "last_page": 145, + "next_page": "/retargetingtracker/customers?page=2", + "prev_page": "/retargetingtracker/customers?page=1" +} + +``` + +Response example (encrypted) + +```json + +{ + "data": [ + "CLgwGLmYEkecnT5ZIEjfxCTWmmCs-WWOJW7uft-fkINjFDYLB4F9RQ42gqw1yfsnWumg6I2XlXQ2oCO3b29pFY7f5-2XceCXsAto51RMA2alKFIPgMz59Tv0iYSppw7BETH-9PnEv3eS8ZCNseaPcKiL6RQNcpyJ2kSpTLBJFdk", + "Js35cJP-vCLMi9dXYLffUMgle9m9hV8VBeVfSNNM1qiumHSmhyt3cQGR3cIKraNijP3sm4GtkXDr0XBMC29G9k05oGhtfPmEoYAFEjhGwikEHMsWCWo1luew7rpEeEh2VTT9JKmsz_z-eowe97TRPw" + ], + "current_page": 1, + "last_page": 145, + "next_page": "/retargetingtracker/customers?page=2", + "prev_page": "/retargetingtracker/customers?page=1" +} + +``` + +## Stock Management + +Call api stock management each time you make some changes on your products. + +Request example + +```php +use Retargeting/Api; + +$stock = new StockManagement(); + +$stock->setProductId(123); +$stock->setName('Canon EOS 5D'); +$stock->setPrice(900); +$stock->setPromo(800); +$stock->setImage('https://www.example.com/products/image/canon-eos-5d.jpg'); +$stock->setUrl('https://www.example.com/products/camera/canon-eos-5d'); +$stock->setStock(true); + +$api_key = 'YOUR_RTG_GENERATED_API_KEY'; +$product_data = $stock->prepareStockInfo(); + +//Update stock each time you make some change +$stock->updateStock($api_key, $product_data); +``` diff --git a/lib/Brand.php b/lib/Brand.php index 1c2aa82..95428d4 100644 --- a/lib/Brand.php +++ b/lib/Brand.php @@ -6,10 +6,56 @@ * Time: 08:03 */ -namespace Retargeting; +namespace RetargetingSDK; +use RetargetingSDK\Helpers\BrandHelper; -class Brand +class Brand extends AbstractRetargetingSDK { + protected $id; + protected $name = ''; + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Prepare brand information + * @return string + */ + public function prepareBrandInformation() + { + return $this->toJSON(BrandHelper::validate([ + 'id' => $this->getId(), + 'name' => $this->getProperFormattedString($this->getName()) + ])); + } } \ No newline at end of file diff --git a/lib/Category.php b/lib/Category.php index b1f23d3..ae3ee55 100644 --- a/lib/Category.php +++ b/lib/Category.php @@ -6,7 +6,10 @@ * Time: 08:02 */ -namespace Retargeting; +namespace RetargetingSDK; + +use RetargetingSDK\Helpers\CategoryHelper; +use RetargetingSDK\Helpers\UrlHelper; /** * Class Category @@ -14,5 +17,113 @@ */ class Category extends AbstractRetargetingSDK { + protected $id = '-1'; + protected $name = ''; + protected $url = ''; + protected $parent = false; + protected $breadcrumb = []; + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + */ + public function setId($id) + { + $id = $this->getProperFormattedString($id); + + $this->id = $id; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + + /** + * @param mixed $name + */ + public function setName($name) + { + $name = $this->getProperFormattedString($name); + + $this->name = $name; + } + + /** + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * @param $url + * @throws \Exception + */ + public function setUrl($url) + { + $this->url = UrlHelper::validate($url); + } + + /** + * @return int + */ + public function getParent() + { + return $this->parent; + } + + /** + * @param int $parent + */ + public function setParent($parent) + { + $parent = (is_bool($parent) && !$parent) || $parent === '' ? false : $parent; + + $this->parent = $parent; + } + + /** + * @return array + */ + public function getBreadcrumb() + { + return $this->breadcrumb; + } + + /** + * @param array $breadcrumb + */ + public function setBreadcrumb(array $breadcrumb) + { + $breadcrumb = CategoryHelper::validateBreadcrumb($breadcrumb); + + $this->breadcrumb = $breadcrumb; + } + /** + * Prepare category data + * @return string + */ + public function prepareCategoryData() + { + return $this->toJSON([ + 'id' => $this->getId(), + 'name' => $this->getName(), + 'url' => $this->getUrl(), + 'parent' => $this->getParent(), + 'breadcrumb' => $this->getBreadcrumb() + ]); + } } \ No newline at end of file diff --git a/lib/Checkout.php b/lib/Checkout.php index f229767..b59e30c 100644 --- a/lib/Checkout.php +++ b/lib/Checkout.php @@ -6,10 +6,38 @@ * Time: 08:04 */ -namespace Retargeting; +namespace RetargetingSDK; - -class Checkout +class Checkout extends AbstractRetargetingSDK { + protected $productIds = []; + + /** + * @return array + */ + public function getProductIds() + { + return $this->productIds; + } + + /** + * @param array $productIds + */ + public function setProductIds(array $productIds) + { + $productIds = is_array($productIds) ? $productIds : (array)$productIds; + + $this->productIds = $productIds; + } + /** + * Prepare checkout ids + * @return string + */ + public function prepareCheckoutIds() + { + return $this->toJSON( + $this->getProductIds() + ); + } } \ No newline at end of file diff --git a/lib/Email.php b/lib/Email.php index 5f7f19c..a16bfa6 100644 --- a/lib/Email.php +++ b/lib/Email.php @@ -6,10 +6,140 @@ * Time: 08:03 */ -namespace Retargeting; +namespace RetargetingSDK; +use RetargetingSDK\Helpers\EmailHelper; -class Email +class Email extends AbstractRetargetingSDK { + protected $email; + protected $name = ''; + protected $phone = ''; + protected $city = ''; + protected $sex = ''; + protected $birthday = ''; + /** + * @return mixed + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param $email + * @throws \Exception + */ + public function setEmail($email) + { + $email = EmailHelper::validate($email); + + $this->email = $email; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $name = $this->getProperFormattedString($name); + + $this->name = $name; + } + + /** + * @return string + */ + public function getPhone() + { + return $this->phone; + } + + /** + * @param string $phone + */ + public function setPhone($phone) + { + $phone = $this->getProperFormattedString($phone); + + $this->phone = $phone; + } + + /** + * @return string + */ + public function getCity() + { + return $this->city; + } + + /** + * @param string $city + */ + public function setCity($city) + { + $city = $this->getProperFormattedString($city); + + $this->city = $city; + } + + /** + * @return string + */ + public function getSex() + { + return $this->sex; + } + + /** + * @param string $sex + */ + public function setSex($sex) + { + $sex = is_numeric($sex) ? $sex : (int)$sex; + + $this->sex = $sex; + } + + /** + * @return string + */ + public function getBirthday() + { + return $this->birthday; + } + + /** + * @param $birthday + * @throws \Exception + */ + public function setBirthday($birthday) + { + $this->birthday = EmailHelper::validateBirthday($birthday); + } + + /** + * Prepare email data + * @return string + */ + public function prepareEmailData() + { + return $this->toJSON([ + 'email' => $this->getEmail(), + 'name' => $this->getName(), + 'phone' => $this->getPhone(), + 'city' => $this->getCity(), + 'sex' => $this->getSex(), + 'birthday' => $this->getBirthday() + ]); + } } \ No newline at end of file diff --git a/lib/Exceptions/DecryptException.php b/lib/Exceptions/DecryptException.php new file mode 100644 index 0000000..f9801e1 --- /dev/null +++ b/lib/Exceptions/DecryptException.php @@ -0,0 +1,18 @@ + $value) { + + if(!isset($new_array[$value[$keyname]])) { + $new_array[$value[$keyname]] = $value; + } + } + + $new_array = array_values($new_array); + + return $new_array; + } + + /** + * Throw exceptions when validating data + * @param $message + * @throws \Exception + */ + public static function _throwException($message) + { + $messages = [ + "emptyURL" => "Url is required. Please don't leave it empty.", + "wrongUrl" => "The url has wrong format.", + "emptyCustomerData" => "Customer data is required. Please don't leave it empty.", + "emptyToken" => "Token is required. Please don't leave it empty.", + "wrongFormatToken" => "Token format is wrong.", + "wrongFormat" => "The array format you provided is wrong.", + "invalidEmail" => "Invalid email format.", + "wrongPrice" => "Wrong price format." + ]; + + throw new \Exception($messages[$message]); + } +} \ No newline at end of file diff --git a/lib/Helpers/BrandHelper.php b/lib/Helpers/BrandHelper.php new file mode 100644 index 0000000..31a2d67 --- /dev/null +++ b/lib/Helpers/BrandHelper.php @@ -0,0 +1,43 @@ += 2) + { + foreach($categoryData as $category) + { + $category['name'] = self::formatString($category['name']); + $category['breadcrumb'] = is_array($category['breadcrumb']) ? $category['breadcrumb'] : (array)$category['breadcrumb']; + + $categoryArr[] = $category; + } + } + } + + return $categoryArr; + } + + /** + * @param $breadcrumb + * @return array + */ + public static function validateBreadcrumb($breadcrumb) + { + $breadcrumbArr = []; + + if(is_array($breadcrumb) && !empty($breadcrumb)) + { + if(array_key_exists('0', $breadcrumb)) + { + foreach ($breadcrumb as $value) + { + $value['id'] = self::formatString($value['id']); + $value['name'] = self::formatString($value['name']); + $value['parent'] = is_bool($value['parent']) && !$value['parent'] ? false : $value['parent']; + + $breadcrumbArr[] = $value; + } + } + else { + $breadcrumbArr['id'] = $breadcrumb['id']; + $breadcrumbArr['name'] = self::formatString($breadcrumb['name']); + $breadcrumbArr['parent'] = is_bool($breadcrumb['parent']) && !$breadcrumb['parent'] ? false : $breadcrumb['parent']; + } + + } + + return $breadcrumbArr; + } +} \ No newline at end of file diff --git a/lib/Helpers/CodeHelper.php b/lib/Helpers/CodeHelper.php new file mode 100644 index 0000000..5fd4c6d --- /dev/null +++ b/lib/Helpers/CodeHelper.php @@ -0,0 +1,38 @@ += 1) + { + $code = explode('-', $code); + + if(is_numeric($code[0]) && is_string($code[1])) + { + $code = implode('-', $code); + } + else + { + $code = ''; + } + } + + return $code; + } +} \ No newline at end of file diff --git a/lib/Helpers/CustomersApiHelper.php b/lib/Helpers/CustomersApiHelper.php new file mode 100644 index 0000000..9b65598 --- /dev/null +++ b/lib/Helpers/CustomersApiHelper.php @@ -0,0 +1,68 @@ + 0) + { + self::_throwException('wrongFormat'); + } + + $customers = $data; + } + + return $customers; + } + + /** + * Get token + * @param $token + * @return mixed + * @throws \Exception + */ + public static function getToken($token) + { + if(empty($token)) + { + self::_throwException('emptyToken'); + } + + return $token; + } +} \ No newline at end of file diff --git a/lib/Helpers/DecryptionHelper.php b/lib/Helpers/DecryptionHelper.php new file mode 100644 index 0000000..a11b6c8 --- /dev/null +++ b/lib/Helpers/DecryptionHelper.php @@ -0,0 +1,115 @@ +hash = hash(self::HASH_ALGORITHM, $token); + } + + /** + * @param $token + * @param $nonce + * @return string + * @throws DecryptException + */ + public function decrypt($token, $nonce = null) + { + $data = $this->tokenDecrypt($token, $this->hash, self::METHOD); + + if ($nonce && !$this->verifyNonce($nonce)) { + throw new DecryptException('Invalid Nonce!'); + } + + return $data; + } + + /** + * @param $data + * @param $key + * @param $method + * @return bool|string + */ + private function tokenDecrypt($data, $key, $method) + { + $data = base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); + $ivSize = openssl_cipher_iv_length($method); + $iv = substr($data, 0, $ivSize); + $data = openssl_decrypt(substr($data, $ivSize), $method, $key, OPENSSL_RAW_DATA, $iv); + + return $data; + } + + /** + * @param $nonce + * @param int $clockSkew + * @return bool + */ + private function verifyNonce($nonce, $clockSkew = 60) + { + $nonce = base64_decode( + str_pad( + strtr($nonce, '-_', '+/'), + strlen($nonce) % 4, + '=', + STR_PAD_RIGHT + ) + ); + + if (strlen($nonce) > 255) { + return false; + } + + $result = preg_match('/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z(.*)/', + $nonce, + $matches); + + if ($result != 1 || count($matches) != 8) { + return false; + } + + $stamp = gmmktime( + $matches[4], + $matches[5], + $matches[6], + $matches[2], + $matches[3], + $matches[1] + ); + + $time = time(); + if ($stamp < ($time - $clockSkew) + || $stamp > ($time + $clockSkew)) { + + return false; + } + + return true; + } + +} diff --git a/lib/Helpers/EmailHelper.php b/lib/Helpers/EmailHelper.php new file mode 100644 index 0000000..eb7a8ac --- /dev/null +++ b/lib/Helpers/EmailHelper.php @@ -0,0 +1,69 @@ +format('d-m-Y'); + } + + return $dob; + } + + /** + * Check if the value is a valid date + * @param mixed $value + * @return boolean + */ + public static function isDate($value) + { + if (!$value) { + return false; + } else { + $date = date_parse($value); + if($date['error_count'] == 0 && $date['warning_count'] == 0) { + return checkdate($date['month'], $date['day'], $date['year']); + } else { + return false; + } + } + } +} \ No newline at end of file diff --git a/lib/Helpers/EncryptionHelper.php b/lib/Helpers/EncryptionHelper.php new file mode 100644 index 0000000..53f966e --- /dev/null +++ b/lib/Helpers/EncryptionHelper.php @@ -0,0 +1,55 @@ + false, + 'stock' => [] + ]; + + if(is_array($variation)) + { + if(array_key_exists('variations', $variation) && isset($variation['variations'])) + { + $variationArr['variations'] = $variation['variations']; + } + else + { + $variationArr['vavriations'] = false; + } + + if(array_key_exists('stock', $variation) && isset($variation['stock'])) + { + $variationArr['stock'] = $variation['stock']; + } + } + + return $variationArr; + } +} \ No newline at end of file diff --git a/lib/Order.php b/lib/Order.php index aab1acb..760d22f 100644 --- a/lib/Order.php +++ b/lib/Order.php @@ -6,9 +6,279 @@ * Time: 08:03 */ -namespace Retargeting; +namespace RetargetingSDK; -class Order +use RetargetingSDK\Helpers\EmailHelper; + +class Order extends AbstractRetargetingSDK { + protected $orderNo; + protected $lastName = ''; + protected $firstName = ''; + protected $email = ''; + protected $phone = 0; + protected $state = ''; + protected $city = ''; + protected $address = ''; + protected $birthday = ''; + protected $discount = ''; + protected $discountCode = '0'; + protected $shipping = ''; + protected $total = 0; + + /** + * @return mixed + */ + public function getOrderNo() + { + return $this->orderNo; + } + + /** + * @param mixed $orderNo + */ + public function setOrderNo($orderNo) + { + $orderNo = $this->formatIntFloatString($orderNo); + + $this->orderNo = $orderNo; + } + + /** + * @return mixed + */ + public function getLastName() + { + return $this->lastName; + } + + /** + * @param mixed $lastName + */ + public function setLastName($lastName) + { + $lastName = $this->getProperFormattedString($lastName); + + $this->lastName = $lastName; + } + + /** + * @return mixed + */ + public function getFirstName() + { + return $this->firstName; + } + + /** + * @param mixed $firstName + */ + public function setFirstName($firstName) + { + $firstName = $this->getProperFormattedString($firstName); + + $this->firstName = $firstName; + } + + /** + * @return mixed + */ + public function getEmail() + { + return $this->email; + } + + /** + * @param mixed $email + */ + public function setEmail($email) + { + $email = EmailHelper::sanitize($email, 'email'); + + $this->email = $email; + } + + /** + * @return mixed + */ + public function getPhone() + { + return $this->phone; + } + + /** + * @param mixed $phone + */ + public function setPhone($phone) + { + $phone = $this->getProperFormattedString($phone); + + $this->phone = $phone; + } + + /** + * @return mixed + */ + public function getState() + { + return $this->state; + } + + /** + * @param mixed $state + */ + public function setState($state) + { + $state = $this->getProperFormattedString($state); + + $this->state = $state; + } + + /** + * @return mixed + */ + public function getCity() + { + return $this->city; + } + + /** + * @param mixed $city + */ + public function setCity($city) + { + $city = $this->getProperFormattedString($city); + + $this->city = $city; + } + + /** + * @return mixed + */ + public function getAddress() + { + return $this->address; + } + + /** + * @param mixed $address + */ + public function setAddress($address) + { + $address = $this->getProperFormattedString($address); + + $this->address = $address; + } + + /** + * @return string + */ + public function getBirthday() + { + return $this->birthday; + } + + /** + * @param $birthday + * @throws \Exception + */ + public function setBirthday($birthday) + { + $this->birthday = EmailHelper::validateBirthday($birthday); + } + + /** + * @return mixed + */ + public function getDiscount() + { + return $this->discount; + } + + /** + * @param mixed $discount + */ + public function setDiscount($discount) + { + $discount = $this->getProperFormattedString($discount); + + $this->discount = $discount; + } + + /** + * @return mixed + */ + public function getDiscountCode() + { + return $this->discountCode; + } + + /** + * @param mixed $discountCode + */ + public function setDiscountCode($discountCode) + { + $discountCode = $this->getProperFormattedString($discountCode); + + $this->discountCode = $discountCode; + } + + /** + * @return mixed + */ + public function getShipping() + { + return $this->shipping; + } + + /** + * @param mixed $shipping + */ + public function setShipping($shipping) + { + $shipping = $this->getProperFormattedString($shipping); + + $this->shipping = $shipping; + } + + /** + * @return mixed + */ + public function getTotal() + { + return $this->total; + } + + /** + * @param mixed $total + */ + public function setTotal($total) + { + $this->formatIntFloatString($total); + + $this->total = $total; + } + /** + * Prepare order information + * @return string + */ + public function prepareOrderInformation() + { + return $this->toJSON([ + 'order_no' => $this->getOrderNo(), + 'lastname' => $this->getLastName(), + 'firstname' => $this->getFirstName(), + 'email' => $this->getEmail(), + 'phone' => $this->getPhone(), + 'state' => $this->getState(), + 'city' => $this->getCity(), + 'address' => $this->getAddress(), + 'birthday' => $this->getBirthday(), + 'discount' => $this->getDiscount(), + 'discount_code' => $this->getDiscountCode(), + 'shipping' => $this->getShipping(), + 'total' => $this->getTotal() + ]); + } } \ No newline at end of file diff --git a/lib/Product.php b/lib/Product.php index bf61ff6..ad9e34f 100644 --- a/lib/Product.php +++ b/lib/Product.php @@ -5,36 +5,43 @@ * Date: 2019-02-19 * Time: 07:48 */ +namespace RetargetingSDK; -namespace Retargeting; +use RetargetingSDK\Helpers\BrandHelper; +use RetargetingSDK\Helpers\CategoryHelper; +use RetargetingSDK\Helpers\ProductFeedHelper; +use RetargetingSDK\Helpers\UrlHelper; +use RetargetingSDK\Helpers\VariationsHelper; class Product extends AbstractRetargetingSDK { - - protected $id; - protected $name; - protected $url; - protected $img; - protected $price; + protected $id = 0; + protected $name = ''; + protected $url = ''; + protected $img = ''; + protected $price = ''; protected $promo = 0; - protected $brand = null; + protected $brand = []; protected $category = []; protected $inventory = []; + protected $additionalImages = []; /** - * @param mixed $id + * @return mixed */ - public function setId($id) + public function getId() { - $this->id = $id; + return $this->id; } /** - * @return mixed + * @param mixed $id */ - public function getId() + public function setId($id) { - return $this->id; + $id = $this->formatIntFloatString($id); + + $this->id = $id; } /** @@ -48,8 +55,10 @@ public function getName() /** * @param mixed $name */ - public function setName($name): void + public function setName($name) { + $name = $this->getProperFormattedString($name); + $this->name = $name; } @@ -62,11 +71,13 @@ public function getUrl() } /** - * @param mixed $url + * @param $url + * @throws \Exception */ - public function setUrl($url): void + public function setUrl($url) { - //@todo: verifica daca url-ul incepe cu http sau https.... + $url = UrlHelper::validate($url); + $this->url = $url; } @@ -79,10 +90,13 @@ public function getImg() } /** - * @param mixed $img + * @param $img + * @throws \Exception */ - public function setImg($img): void + public function setImg($img) { + $img = UrlHelper::validate($img); + $this->img = $img; } @@ -95,31 +109,44 @@ public function getPrice() } /** - * @param mixed $price + * @param $price + * @throws \Exception */ - public function setPrice(int $price): void + public function setPrice($price) { + $price = ProductFeedHelper::formatPrice($price); + $this->price = $price; } /** * @return float */ - public function getPromo(): float + public function getPromo() { return $this->promo; } /** - * @param float $promo + * @param $promo + * @throws \Exception */ - public function setPromo(float $promo): void + public function setPromo($promo) { + if($promo > 0 && $promo < $this->getPrice()) + { + $promo = ProductFeedHelper::formatPrice($promo); + } + else + { + $promo = 0; + } + $this->promo = $promo; } /** - * @return null + * @return array */ public function getBrand() { @@ -127,17 +154,19 @@ public function getBrand() } /** - * @param null $brand + * @param array $brand */ - public function setBrand($brand): void + public function setBrand($brand) { + $brand = BrandHelper::validate($brand); + $this->brand = $brand; } /** * @return array */ - public function getCategory(): array + public function getCategory() { return $this->category; } @@ -145,15 +174,17 @@ public function getCategory(): array /** * @param array $category */ - public function setCategory(array $category): void + public function setCategory($category) { + $category = CategoryHelper::validate($category); + $this->category = $category; } /** * @return array */ - public function getInventory(): array + public function getInventory() { return $this->inventory; } @@ -161,28 +192,72 @@ public function getInventory(): array /** * @param array $inventory */ - public function setInventory(array $inventory): void + public function setInventory($inventory) { + $inventory = VariationsHelper::validate($inventory); + $this->inventory = $inventory; } /** - * @return string + * @return array + */ + public function getAdditionalImages() + { + return $this->additionalImages; + } + + /** + * @param array $additionalImages + */ + public function setAdditionalImages($additionalImages) + { + $additionalImages = $this->validateArrayData($additionalImages); + + $this->additionalImages = $additionalImages; + } + + /** + * Prepare product info to array + * @return array + * @throws \Exception */ public function prepareProductInformation() { + return [ + 'id' => $this->getId(), + 'name' => $this->getName(), + 'url' => $this->getUrl(), + 'img' => $this->getImg(), + 'price' => $this->getPrice(), + 'promo' => $this->getPromo(), + 'brand' => $this->getBrand(), + 'category' => $this->getCategory(), + 'inventory' => $this->getInventory(), + 'images' => $this->getAdditionalImages() + ]; + } + + /** + * Prepare product info to array + * @return string + * @throws \Exception + */ + public function prepareProductInformationToJson() + { + $data = self::prepareProductInformation(); return $this->toJSON([ - 'id' => $this->id, - 'name' => $this->name, - 'url' => $this->url, - 'img' => $this->img, - 'price' => $this->price, - 'promo' => $this->promo, - 'brand' => $this->brand, - 'category' => $this->category, - 'inventory' => $this->inventory + 'id' => $data['id'], + 'name' => $data['name'], + 'url' => $data['url'], + 'img' => $data['img'], + 'price' => $data['price'], + 'promo' => $data['promo'], + 'brand' => $data['brand'], + 'category' => $data['category'], + 'inventory' => $data['inventory'], + 'images' => $data['images'] ]); - } } \ No newline at end of file diff --git a/lib/ProductFeed.php b/lib/ProductFeed.php index ec11174..d86b8c6 100644 --- a/lib/ProductFeed.php +++ b/lib/ProductFeed.php @@ -6,10 +6,35 @@ * Time: 08:04 */ -namespace Retargeting; +namespace RetargetingSDK; +use RetargetingSDK\Helpers\ProductFeedHelper; -class ProductFeed +class ProductFeed extends AbstractRetargetingSDK { + protected $productFeed = []; + /** + * @return array + */ + public function getProductFeed() + { + return $this->productFeed; + } + + /** + * @param array $productFeed + */ + public function setProductFeed($productFeed) + { + $this->productFeed = $productFeed; + } + + /** + * @return array|mixed + */ + public function prepareProductFeed() + { + return $this->toJSON(ProductFeedHelper::validate($this->getProductFeed())); + } } \ No newline at end of file diff --git a/lib/Variation.php b/lib/Variation.php index 1caac40..565b451 100644 --- a/lib/Variation.php +++ b/lib/Variation.php @@ -6,10 +6,74 @@ * Time: 08:03 */ -namespace Retargeting; +namespace RetargetingSDK; +use RetargetingSDK\Helpers\CodeHelper; -class Variation +class Variation extends AbstractRetargetingSDK { + protected $code = ''; + protected $stock = false; + protected $details = []; + /** + * @return mixed + */ + public function getCode() + { + return $this->code; + } + + /** + * @param mixed $code + */ + public function setCode($code) + { + $this->code = $code; + } + + /** + * @return int + */ + public function getStock(): int + { + return $this->stock; + } + + /** + * @param int $stock + */ + public function setStock(int $stock) + { + $this->stock = $stock; + } + + /** + * @return array + */ + public function getDetails() + { + return $this->details; + } + + /** + * @param array $details + */ + public function setDetails(array $details) + { + $this->details = $details; + } + + /** + * Prepare variation data + * @return string + */ + public function prepareVariationInfo() + { + return $this->toJSON([ + 'code' => $this->getCode(), + 'stock' => (bool)$this->getStock(), + 'details' => $this->getDetails() + ]); + } } \ No newline at end of file diff --git a/readme.md b/readme.md index 8c4c921..22af64d 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,157 @@ -# Retargeting SDK +# Retargeting SDK +## Overview +Retargeting SDK is a software development tool for E-Commerce platforms that simplifies the implementation of Retargeting extension. + +## Minimum requirements +The Retargeting SDK requires at least PHP version 5.4.0 and it's also compatible with PHP >= 7.0.0. + +## How to install +Clone the repository in your platform root folder. + +## Example + +### Product class for sendProduct implementation + +#### Sample request ```php -require "vendor/autoload.php"; +use Retargeting/Product; + +$brand = [ + 'id' => 8, + 'name' => 'Apple' +]; + +$category = [ + [ + "id" => 20, + "name" => "Desktop", + "parent" => false, + "breadcrumb" => [] + ], + [ + "id" => 28, + "name" => "Monitors", + "parent" => 25, + "breadcrumb" => [ + ["id" => 25, "name" => "Components", "parent" => false] + ] +]; + +$inventory = [ + 'variations' => true, + 'stock' => [ + 'Red' => true, + 'Small' => false, + 'Medium' => true, + ] +]; + +$additionalImages = [ + "http://localhost/upload/image/catalog/demo/canon_logo.jpg", + "http://localhost/upload/image/catalog/demo/hp_1.jpg", + "http://localhost/upload/image/catalog/demo/compaq_presario.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_1.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_2.jpg" +]; + +$product = new Product(); +$product->setId(42); +$product->setName('Shoes'); +$product->setUrl('http://localhost/upload/test'); +$product->setImg('http://localhost/upload/image/catalog/demo/apple_cinema_30.jpg'); +$product->setPrice(122); +$product->setPromo(90); +$product->setBrand($brand); +$product->setCategory($category); +$product->setInventory($inventory); +$product->setAdditionalImages($additionalImages) + +echo $product->prepareProductInformation(); +``` -$product = new \Retargeting\Product(); -$product->setId(123); -$product->setName('Fooo'); -$product->setUrl('https://retargeting.biz'); +#### Sample response +```json +[ + { + "id": 42, + "name": "Apple Cinema 30\"", + "url": "http://localhost/upload/test", + "img": "http://localhost/upload/image/catalog/demo/apple_cinema_30.jpg", + "price": 122, + "promo": 90, + "brand": { + "id": "8", + "name": "Apple" + }, + "category": [ + { + "id": "20", + "name": "Desktops", + "parent": false, + "breadcrumb": [] + }, + { + "id": "28", + "name": "Monitors", + "parent": "25", + "breadcrumb": [ + { + "id": "25", + "name": "Components", + "parent": false + } + ] + } + ], + "inventory": { + "variations": true, + "stock": { + "Small": true, + "Medium": true, + "Large": true, + "Checkbox 1": true, + "Checkbox 2": true, + "Checkbox 3": true, + "Checkbox 4": true, + "Red": true, + "Blue": true, + "Green": true, + "Yellow": true + } + }, + "images": [ + "http://localhost/upload/image/catalog/demo/canon_logo.jpg", + "http://localhost/upload/image/catalog/demo/hp_1.jpg", + "http://localhost/upload/image/catalog/demo/compaq_presario.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_1.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_2.jpg" + ] + } +] +``` -var_dump($product->prepareProductInformation()); -``` \ No newline at end of file +| **Method** | **Type** | **Required** | **Description** | +|---|---|---|---| +| setId | Number or text | Required | The product item identifier, ie. itemcode. It should identify to the sold product, but not necessarily some specific variant of the product. Must be unique in your site. | +| setName | Text | Required | The product name | +| setUrl | URL | Required | Complete URL of the item. Must start with http:// or https://. | +| setImg | URL | Required | Complete URL of an image of the item. | +| setPrice | Number or text | Required | Current product price. If the product is on promotion (price is reduced) then this parameter gets the value of the price before promotion was applied to the product (old price). | +| setPromo | Number or text | Optional | Promotional price (new price). When the product isn’t on promotion (no reduced price), send value 0. | | +| setBrand | Object | Required | Details about product brand. If the product does not belong to any brand, send false value. The object containing brand details, has the following properties: id, name. | +| brand.id | Number or text | Required | The brand item identifier. | +| brand.name | Text | Required | Brand name | +| setCategory | Object | Required | An object that contain details about products category. The object should contain the following properties: id, name, parent | +| category.id | Number or text | Required | The category identifier | +| category.name | Text | Required | Category name | +| category.parent | Number, text, false | Required | Id of parent category. If there isn’t any parent category, send false value. | +| setBreadcrumb | Array | Required | Array containing all the parent categories of the category to which the product belongs (in this array you must not add the product category). If the category does not have a parent category (category.parent is set false), send an empty array. Each parent category is sent as object and contains the following properties: id, name, parent. | +| breadcrumb.id | Number or text | Required | Category id | +| breadcrumb.name | Text | Required | Category Name | +| breadcrumb.parent | Number, text, false | Required | Id of parent category. If there isn’t any parent category, send false value. | +| setInventory | Object | Required | Inventory details | +| inventory.variations | True/False | Required | True for products with variations. False for products without variations. | +| inventory.stock | True/False/Object | Required | For product with variations, you should send an object with stock for each variations. | +| setAdditionalImages | Object | Required | All product images can be assigned here. Accepts an object of urls. +| callback_function | Function | Optional | With this parameter you can define a function that runs itself after the action’s parent function executes | diff --git a/tests/Unit/ApiCustomersTest.php b/tests/Unit/ApiCustomersTest.php new file mode 100644 index 0000000..4a4f504 --- /dev/null +++ b/tests/Unit/ApiCustomersTest.php @@ -0,0 +1,109 @@ + 'John', + 'lastName' => 'Doe', + 'email' => 'john.doe@example.com', + 'phone' => '0770000000', + 'status' => true + ]; + + /** + * @throws \Exception + */ + public function setUp(): void + { + $this->customersInstance = new Customers(self::TOKEN); + + $this->customersInstance->setToken(self::TOKEN); + $this->customersInstance->setData($this->customer); + $this->customersInstance->setCurrentPage(2); + $this->customersInstance->setLastPage(120); + $this->customersInstance->setPrevPage('https://www.example.com/api/retargetingtracker?page=1'); + $this->customersInstance->setNextPage('https://www.example.com/api/retargetingtracker?page=3'); + } + + /** + * Test if customer has data + */ + public function testIfCustomersHasData() + { + $this->assertNotEmpty($this->customersInstance->getData()); + } + + /** + * Test if token is not null + */ + public function testIfCustomerHasToken() + { + $this->assertNotNull($this->customersInstance->getToken()); + } + + /** + * Test if page related data is not empty + */ + public function testIfCustomerHasPageData() + { + $this->assertNotNull($this->customersInstance->getCurrentPage()); + $this->assertNotNull($this->customersInstance->getLastPage()); + $this->assertNotNull($this->customersInstance->getNextPage()); + $this->assertNotNull($this->customersInstance->getPrevPage()); + } + + /** + * Test if token is type of hashed + * @throws Exceptions\DecryptException + * @throws Exceptions\RTGException + */ + public function testIfCustomerDataIsHashed() + { + $encryption = new EncryptionHelper(self::TOKEN); + + $data = $encryption->encrypt(json_encode($this->customer, JSON_PRETTY_PRINT)); + + $this->customersInstance->setData($data); + + $decryption = new DecryptionHelper(self::TOKEN); + + $decryptedData = $decryption->decrypt($this->customersInstance->getData()); + + $this->assertEquals(json_decode($decryptedData, JSON_PRETTY_PRINT), $this->customer); + } + + /** + * Test if customer prepare api information has proper format + * @throws \Exception + */ + public function testIfCustomerPrepareApiInfoHasProperFormat() + { + $this->assertEquals($this->customersInstance->prepareCustomersApiInfo(), json_encode([ + 'data' => $this->customer, + 'current_page' => 2, + 'last_page' => 120, + 'next_page' => 'https://www.example.com/api/retargetingtracker?page=3', + 'prev_page' => 'https://www.example.com/api/retargetingtracker?page=1' + ], JSON_PRETTY_PRINT)); + } +} diff --git a/tests/Unit/BrandTest.php b/tests/Unit/BrandTest.php new file mode 100644 index 0000000..6b0d463 --- /dev/null +++ b/tests/Unit/BrandTest.php @@ -0,0 +1,65 @@ +brand = new Brand(); + } + + /** + * Check if brand has id + */ + public function testIfBrandHasId() + { + $this->brand->setId(33); + $this->assertNotNull($this->brand->getId()); + } + + /** + * Check if brand has name + */ + public function testIfBrandHasName() + { + $this->brand->setName('Nike'); + $this->assertNotNull($this->brand->getName()); + } + + /** + * Check if brand prepare information is json + */ + public function testIfBrandPrepareInformationIsJson() + { + $this->brand->setId(23); + $this->brand->setName('Apple'); + + $this->assertJson($this->brand->prepareBrandInformation()); + } + + /** + * Check if brand has proper json format + */ + public function testIfBrandHasProperFormat() + { + $this->brand->setId(9000); + $this->brand->setName('Adidas'); + + $this->assertEquals($this->brand->prepareBrandInformation(), json_encode(['id' => 9000, 'name' => 'Adidas'], JSON_PRETTY_PRINT)); + } +} diff --git a/tests/Unit/CategoryTest.php b/tests/Unit/CategoryTest.php new file mode 100644 index 0000000..ae0b871 --- /dev/null +++ b/tests/Unit/CategoryTest.php @@ -0,0 +1,136 @@ +category = new Category(); + + $this->category->setId(89); + $this->category->setName('Shoes'); + $this->category->setParent(''); + $this->category->setUrl('https://www.example.com/desktops/monitors'); + $this->category->setBreadcrumb([ + ["id" => 21, "name" => "Sneakers", "parent" => 20], + ["id" => 20, "name" => "Shoes", "parent" => false] + ]); + } + + /** + * Check if category has identifier + */ + public function testIfCategoryHasId() + { + $this->assertNotNull($this->category->getId()); + } + + /** + * Check if category has name + */ + public function testIfCategoryHasName() + { + $this->assertNotNull($this->category->getName()); + } + + /** + * Test if url is not empty + */ + public function testIfUrlIsNotEmpty() + { + $this->assertNotNull($this->category->getUrl()); + } + + /** + * Test if url has correct format + */ + public function testIfUrlHasProperFormat() + { + $this->assertEquals($this->category->getUrl(), 'https://www.example.com/desktops/monitors'); + } + + /** + * Check if category has parent or not. If not return false. + */ + public function testIfCategoryHasParent() + { + $this->assertNotNull($this->category->getParent()); + } + + /** + * Check if category has no parent category + */ + public function testIfCategoryHasNoParent() + { + $this->assertFalse($this->category->getParent()); + } + + /** + * Check if there no breadcrumb set up + */ + public function testIfCategoryHasNoBreadcrumb() + { + $this->category->setBreadcrumb([]); + + $this->assertEquals($this->category->getBreadcrumb(), []); + } + + /** + * Check if there is only one record for breadcrumb + */ + public function testIfCategoryHasOneCategoryBreadcrumb() + { + $this->category->setBreadcrumb([ + 'id' => 2, + 'name' => "Men's footwear", + 'parent' => false + ]); + + $this->assertEquals($this->category->getBreadcrumb(), [ + 'id' => 2, + 'name' => "Men's footwear", + 'parent' => false + ]); + } + + /** + * Check if there is more the on record for breadcrumb + */ + public function testIfCategoryHasTwoOreMoreCategoryBreadcrumb() + { + $this->assertEquals($this->category->getBreadcrumb(), [ + ["id" => 21, "name" => "Sneakers", "parent" => 20], + ["id" => 20, "name" => "Shoes", "parent" => false] + ]); + } + + /** + * Check if prepare category data return correct formed json + */ + public function testIfCategoryPrepareDataHasProperFormat() + { + $this->assertEquals($this->category->prepareCategoryData(), json_encode([ + 'id' => '89', + 'name' => 'Shoes', + 'url' => 'https://www.example.com/desktops/monitors', + 'parent' => false, + 'breadcrumb' => [ + ["id" => '21', "name" => "Sneakers", "parent" => 20], + ["id" => '20', "name" => "Shoes", "parent" => false] + ] + ], JSON_PRETTY_PRINT)); + } +} \ No newline at end of file diff --git a/tests/Unit/EmailTest.php b/tests/Unit/EmailTest.php new file mode 100644 index 0000000..a1c74c7 --- /dev/null +++ b/tests/Unit/EmailTest.php @@ -0,0 +1,153 @@ +email = new Email(); + + $this->email->setEmail('john.doe@mail.com'); + $this->email->setName('John Doe'); + $this->email->setPhone('(298) 407-4029'); + $this->email->setCity('Berlin'); + $this->email->setSex(0); + $this->email->setBirthday('20-02-1960'); + } + + /** + * Test if email is not empty + */ + public function test_if_email_is_not_empty() + { + $this->assertNotNull($this->email->getEmail()); + } + + /** + * Test if email has proper format + */ + public function test_if_email_has_proper_format() + { + $this->assertRegExp('/^.+\@\S+\.\S+$/', $this->email->getEmail()); + } + + /** + * Test if name is not empty + */ + public function test_if_name_is_not_empty() + { + $this->assertNotNull($this->email->getName()); + } + + /** + * Test if name is string + */ + public function test_if_name_is_string() + { + $this->assertIsString($this->email->getName()); + } + + /** + * Test if phone number is not empty + */ + public function test_if_phone_is_not_empty() + { + $this->assertNotNull($this->email->getPhone()); + } + + /** + * Test if phone number is not empty + */ + public function test_if_phone_is_string() + { + $this->assertIsString($this->email->getPhone()); + } + + /** + * Test if city number is not empty + */ + public function test_if_city_is_not_empty() + { + $this->assertNotNull($this->email->getCity()); + } + + /** + * Test if city number is not empty + */ + public function test_if_city_is_string() + { + $this->assertIsString($this->email->getCity()); + } + + /** + * Test if city has proper format + */ + public function test_if_city_has_proper_format() + { + $this->assertEquals($this->email->getCity(), 'Berlin'); + } + + /** + * Test if sex is not empty + */ + public function test_if_sex_is_not_empty() + { + $this->assertNotNull($this->email->getSex()); + } + + /** + * Test if sex is of type boolean + */ + public function test_if_sex_is_boolean() + { + $this->assertIsNumeric($this->email->getSex()); + } + + /** + * Test if birthday is not empty + * @throws \Exception + */ + public function test_if_birthday_is_not_empty() + { + $this->assertNotNull($this->email->getBirthday()); + } + + /** + * Test if birthday has correct format + */ + public function test_if_birthday_has_proper_format() + { + $this->assertEquals($this->email->getBirthday(), '20-02-1960'); + } + + /** + * Test if prepare email data return proper formatted json + * @throws \Exception + */ + public function test_if_prepare_email_data_has_proper_format() + { + $this->assertEquals($this->email->prepareEmailData(), + json_encode([ + 'email' => 'john.doe@mail.com', + 'name' => 'John Doe', + 'phone' => '(298) 407-4029', + 'city' => 'Berlin', + 'sex' => 0, + 'birthday' => '20-02-1960' + ], JSON_PRETTY_PRINT) + ); + } +} \ No newline at end of file diff --git a/tests/Unit/OrderTest.php b/tests/Unit/OrderTest.php new file mode 100644 index 0000000..b2ebc02 --- /dev/null +++ b/tests/Unit/OrderTest.php @@ -0,0 +1,182 @@ +order = new Order(); + $this->order->setOrderNo(28); + $this->order->setLastName('Doe'); + $this->order->setFirstName('John'); + $this->order->setEmail('john.doe@mail.com'); + $this->order->setPhone('40771445255'); + $this->order->setState('Germany'); + $this->order->setCity('Berlin'); + $this->order->setAddress('Sample address'); + $this->order->setBirthday('01-01-1990'); + $this->order->setDiscount(20); + $this->order->setDiscountCode('RAX204'); + $this->order->setShipping('Sample shipping street'); + $this->order->setTotal(396); + } + + /** + * Test if order has order number + */ + public function test_if_order_has_no() + { + $this->assertNotNull($this->order->getOrderNo()); + } + + /** + * Test if order has last name + */ + public function test_if_order_has_last_name() + { + $this->assertNotNull($this->order->getLastName()); + } + + /** + * Test if order has first name + */ + public function test_if_order_has_first_name() + { + $this->assertNotNull($this->order->getFirstName()); + } + + /** + * Test if order has email + */ + public function test_if_order_has_email() + { + $this->assertNotNull($this->order->getEmail()); + } + + /** + * Test if order email is valid + */ + public function test_if_order_has_valid_email() + { + $this->assertRegExp('/^.+\@\S+\.\S+$/', $this->order->getEmail()); + } + + /** + * Test if order has phone + */ + public function test_if_order_has_phone() + { + $this->assertNotNull($this->order->getPhone()); + } + + /** + * Test if order has state + */ + public function test_if_order_has_state() + { + $this->assertNotNull($this->order->getState()); + } + + /** + * Test if order has city + */ + public function test_if_order_has_city() + { + $this->assertNotNull($this->order->getCity()); + } + + /** + * Test if order has address + */ + public function test_if_order_has_address() + { + $this->assertNotNull($this->order->getAddress()); + } + + /** + * Test if birthday is not empty + * @throws \Exception + */ + public function test_if_birthday_is_not_empty() + { + $this->assertNotNull($this->order->getBirthday()); + } + + /** + * Test if birthday has correct format + */ + public function test_if_birthday_has_proper_format() + { + $this->assertEquals($this->order->getBirthday(), '01-01-1990'); + } + + + /** + * Test if order has discount + */ + public function test_if_order_has_discount() + { + $this->assertNotNull($this->order->getDiscount()); + } + + /** + * Test if order has discount code + */ + public function test_if_order_has_discount_code() + { + $this->assertNotNull($this->order->getDiscountCode()); + } + + /** + * Test if order has shipping + */ + public function test_if_order_has_shipping() + { + $this->assertNotNull($this->order->getShipping()); + } + + /** + * Test if order has total + */ + public function test_if_order_has_total() + { + $this->assertNotNull($this->order->getTotal()); + } + + /** + * Test if order prepare information has correct json format + */ + public function test_if_order_prepare_information_has_correct_json_format() + { + $order = [ + 'order_no' => 28, + 'lastname' => 'Doe', + 'firstname' => 'John', + 'email' => 'john.doe@mail.com', + 'phone' => '40771445255', + 'state' => 'Germany', + 'city' => 'Berlin', + 'address' => 'Sample address', + 'birthday' => '01-01-1990', + 'discount' => "20", + 'discount_code' => 'RAX204', + 'shipping' => 'Sample shipping street', + 'total' => 396 + ]; + + $this->assertEquals($this->order->prepareOrderInformation(), json_encode($order, JSON_PRETTY_PRINT)); + } +} \ No newline at end of file diff --git a/tests/Unit/ProductTest.php b/tests/Unit/ProductTest.php index a494bdd..27163a0 100644 --- a/tests/Unit/ProductTest.php +++ b/tests/Unit/ProductTest.php @@ -6,39 +6,394 @@ * Time: 10:25 */ -namespace Retargeting; - +namespace RetargetingSDK; use PHPUnit\Framework\TestCase; +use RetargetingSDK\Product; /** * @property Product product */ class ProductTest extends TestCase { - + /** + * @throws \Exception + */ public function setUp(): void { - parent::setUp(); // TODO: Change the autogenerated stub $this->product = new Product(); - $this->product->setUrl('http://google.ro'); + + $this->product->setUrl('http://www.google.ro'); + $this->product->setImg('https://www.google.com/img.png'); } + /** + * Test if product has product id + */ public function test_if_product_has_id() { $this->product->setId(123); $this->assertNotNull($this->product->getId()); } + /** + * Test if product has name + */ public function test_if_product_has_name() { - $this->product->setName('Fooo'); $this->assertNotNull($this->product->getName()); } - public function test_if_product_url_is_set(){ - $this->assertEquals($this->product->getUrl(), 'http://google.ro'); + /** + * Test if name is a string + */ + public function test_if_product_name_is_string() + { + $this->product->setName('Galaxy Tab 10.0'); + $this->assertIsString($this->product->getName(), 'Galaxy Tab 11.0'); + } + + /** + * Test if product url is set up + */ + public function test_if_product_url_is_set() + { + $this->assertEquals($this->product->getUrl(), 'http://www.google.ro'); + } + + /** + * Test if product has an image + */ + public function test_if_product_has_image() + { + $this->assertEquals($this->product->getImg(), 'https://www.google.com/img.png'); + } + + /** + * Test if product has price + */ + public function test_if_product_has_price() + { + $this->product->setPrice(100.20); + $this->assertNotNull($this->product->getPrice()); + } + + /** + * Test product price when is float + */ + public function test_when_product_price_is_float() + { + $this->product->setPrice('12.33'); + $this->assertEquals($this->product->getPrice(), 12.33); + } + + /** + * Test product price when is integer + */ + public function test_when_product_price_is_int() + { + $this->product->setPrice('12'); + $this->assertEquals($this->product->getPrice(), 12); + } + + public function test_when_product_promo_price_is_zero_and_promo_is_greater_than_price() + { + $this->product->setPrice(20); + $this->product->setPromo(80); + $this->assertEquals($this->product->getPromo(), 0); + } + + /** + * Test if product brand is array + */ + public function test_if_product_brand_is_array() + { + $this->product->setBrand([ + 'id' => 1, + 'name' => 'Apple' + ]); + + $this->assertIsArray($this->product->getBrand()); + } + + /** + * Test if product has brand + */ + public function test_if_product_has_brand() + { + $this->product->setBrand([ + 'id' => '1', + 'name' => 'Apple' + ]); + + $this->assertEquals($this->product->getBrand(), ['id' => 1, 'name' => 'Apple']); + } + + /** + * Test if product category has correct format with only one parent category without subcategory and breadcrumb + */ + public function test_if_product_category_has_correct_format_with_only_one_parent_category() + { + $this->product->setCategory([ + [ + "id" => 12, + "name" => "Women footwear", + "parent" => false, + "breadcrumb" => [] + ] + ]); + + $this->assertEquals($this->product->getCategory(), [ + "id" => 12, + "name" => "Women footwear", + "parent" => false, + "breadcrumb" => [] + ]); + } + + /** + * Test if product has category with parent category, subcategory and breadcrumb + */ + public function test_if_product_has_category_with_parent_category_and_breadcrumb() + { + $this->product->setCategory([ + [ + "id" => 75, + "name" => "Men footwear", + "parent" => false, + "breadcrumb" => [] + ], + [ + "id" => 22, + "name" => "Sport sneakers", + "parent" => 21, + "breadcrumb" => [ + ["id" => 21, "name" => "Sneakers", "parent" => 20], + ["id" => 20, "name" => "Shoes", "parent" => false] + ] + ] + ]); + + $this->assertEquals($this->product->getCategory(), [ + [ + "id" => 75, + "name" => "Men footwear", + "parent" => false, + "breadcrumb" => [] + ], + [ + "id" => 22, + "name" => "Sport sneakers", + "parent" => 21, + "breadcrumb" => [ + ["id" => 21, "name" => "Sneakers", "parent" => 20], + ["id" => 20, "name" => "Shoes", "parent" => false] + ] + ] + ]); + } + + /** + * Test if product inventory is array + */ + public function test_if_product_inventory_is_array() + { + $this->product->setInventory([ + "variations" => true, + "stock" => [ + "42-B" => true, + "42-W" => false, + "43-B" => true, + "43-W" => true + ] + ]); + + $this->assertIsArray($this->product->getInventory()); + } + + /** + * Test if product inventory is array + */ + public function test_if_product_inventory_has_correct_format() + { + $this->product->setInventory([ + "variations" => true, + "stock" => [ + "42-B" => true, + "42-W" => false, + "43-B" => true, + "43-W" => true + ] + ]); + + $this->assertEquals($this->product->getInventory(), [ + "variations" => true, + "stock" => [ + "42-B" => true, + "42-W" => false, + "43-B" => true, + "43-W" => true + ] + ]); + } + + /** + * Test if product additional images is not null + */ + public function test_if_product_has_additional_images() + { + $this->product->setAdditionalImages([ + 'https://www.example.com/image/product-test-1.png', + 'https://www.example.com/image/product-test-2.png', + 'https://www.example.com/image/product-test-3.png', + 'https://www.example.com/image/product-test-4.png', + ]); + + $this->assertNotNull($this->product->getAdditionalImages()); + } + + /** + * Check if images url have proper format and data is returned correctly + */ + public function test_if_product_additional_images_return_correct_format_array() + { + $this->product->setAdditionalImages([ + 'https://www.example.com/image/product-test-1.png', + 'https://www.example.com/image/product-test-2.png', + 'https://www.example.com/image/product-test-3.png', + 'https://www.example.com/image/product-test-4.png', + ]); + + $this->assertEquals($this->product->getAdditionalImages(), [ + 'https://www.example.com/image/product-test-1.png', + 'https://www.example.com/image/product-test-2.png', + 'https://www.example.com/image/product-test-3.png', + 'https://www.example.com/image/product-test-4.png', + ]); } + /** + * Check product prepare information returns correct array format + */ + public function test_if_product_prepare_information_return_correct_format_array() + { + $brand = [ + 'id' => "8", + 'name' => 'Apple' + ]; + + $category = [ + [ + "id" => "20", + "name" => "Desktops", + "parent" => false, + "breadcrumb" => [] + ], + [ + "id" => "28", + "name" => "Monitors", + "parent" => "25", + "breadcrumb" => [ + ["id" => "25", "name" => "Components", "parent" => false] + ] + ] + ]; + + $inventory = [ + 'variations' => true, + 'stock' => [ + "Small" => true, + "Medium" => true, + "Large" => true, + "Checkbox 1" => true, + "Checkbox 2" => true, + "Checkbox 3" => true, + "Checkbox 4" => true, + "Red" => true, + "Blue" => true, + "Green" => true, + "Yellow" => true + ] + ]; + + $additionalImages = [ + "http://localhost/upload/image/catalog/demo/canon_logo.jpg", + "http://localhost/upload/image/catalog/demo/hp_1.jpg", + "http://localhost/upload/image/catalog/demo/compaq_presario.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_1.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_2.jpg" + ]; + + $product = new Product(); + $product->setId(42); + $product->setName('Apple Cinema 30"'); + $product->setUrl('http://localhost/upload/test'); + $product->setImg('http://localhost/upload/image/catalog/demo/apple_cinema_30.jpg'); + $product->setPrice(122); + $product->setPromo(90); + $product->setBrand($brand); + $product->setCategory($category); + $product->setInventory($inventory); + $product->setAdditionalImages($additionalImages); + + $result = json_encode([ + "id" => 42, + "name" => "Apple Cinema 30\"", + "url" => "http://localhost/upload/test", + "img" => "http://localhost/upload/image/catalog/demo/apple_cinema_30.jpg", + "price" => 122, + "promo" => 90, + "brand" => [ + "id" => "8", + "name" => "Apple" + ], + "category" => [ + [ + "id" => "20", + "name" => "Desktops", + "parent" => false, + "breadcrumb" => [] + ], + [ + "id" => "28", + "name" => "Monitors", + "parent" => "25", + "breadcrumb" => [ + [ + "id" => "25", + "name" => "Components", + "parent" => false + ] + ] + ] + ], + "inventory" => [ + "variations" => true, + "stock" => [ + "Small" => true, + "Medium" => true, + "Large" => true, + "Checkbox 1" => true, + "Checkbox 2" => true, + "Checkbox 3" => true, + "Checkbox 4" => true, + "Red" => true, + "Blue" => true, + "Green" => true, + "Yellow" => true + ] + ], + "images" => [ + "http://localhost/upload/image/catalog/demo/canon_logo.jpg", + "http://localhost/upload/image/catalog/demo/hp_1.jpg", + "http://localhost/upload/image/catalog/demo/compaq_presario.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_1.jpg", + "http://localhost/upload/image/catalog/demo/canon_eos_5d_2.jpg" + ] + ], JSON_PRETTY_PRINT); + + $this->assertEquals($product->prepareProductInformationToJson(), $result); + } } + diff --git a/tests/Unit/StockManagementTest.php b/tests/Unit/StockManagementTest.php new file mode 100644 index 0000000..5b5d320 --- /dev/null +++ b/tests/Unit/StockManagementTest.php @@ -0,0 +1,115 @@ + 'HAF220', + 'name' => 'Samsung Galaxy Tab 10.0', + 'price' => '990.90', + 'promo' => '870.20', + 'image' => 'https://www.example.com/catalog/image/samsung-galaxy-tab.png', + 'url' => 'https://www.example.com/tablets/samsung-galaxy-tab', + 'stock' => true + ]; + + public function setUp(): void + { + $this->stock = new StockManagement(); + + $this->stock->setProductId('HAF220'); + $this->stock->setName('Samsung Galaxy Tab 10.0'); + $this->stock->setPrice(990.90); + $this->stock->setPromo(870.20); + $this->stock->setImage('https://www.example.com/catalog/image/samsung-galaxy-tab.png'); + $this->stock->setUrl('https://www.example.com/tablets/samsung-galaxy-tab'); + $this->stock->setStock(true); + } + +// protected $productId; +// protected $name; +// protected $price; +// protected $promo; +// protected $image; +// protected $url; +// protected $stock = false; + + /** + * Test if stock management has product Id + */ + public function testIfStockManagementHasProductId() + { + $this->assertNotNull($this->stock->getProductId()); + } + + /** + * Test if stock management has name + */ + public function testIfStockManagementHasName() + { + $this->assertNotNull($this->stock->getName()); + } + + /** + * Test if stock management has price + */ + public function testIfStockManagementHasPrice() + { + $this->assertNotNull($this->stock->getPrice()); + } + + /** + * Test if stock management has promo + */ + public function testIfStockManagementHasPromo() + { + $this->assertNotNull($this->stock->getPromo()); + } + + /** + * Test if stock management has image + */ + public function testIfStockManagementHasImage() + { + $this->assertNotNull($this->stock->getImage()); + } + + /** + * Test if stock management has url + */ + public function testIfStockManagementHasUrl() + { + $this->assertNotNull($this->stock->getUrl()); + } + + /** + * Test if stock management is bool + */ + public function testIfStockManagementIsBool() + { + $this->assertIsBool($this->stock->isStock()); + } + + /** + * Test if stock management prepare info has proper format + */ + public function testIfStockManagementPrepareStockInfoHasProperFormat() + { + $this->assertEquals($this->stock->prepareStockInfo(), $this->stockSample); + } +} \ No newline at end of file