From 769907d81290a1292dc81c8e3ac1644c550603f0 Mon Sep 17 00:00:00 2001 From: Dima Uryvskiy Date: Fri, 30 Sep 2022 17:50:15 +0300 Subject: [PATCH] Add generators in the ICML generation process --- CHANGELOG.md | 6 + README.md | 2 +- VERSION | 2 +- composer.json | 3 +- resources/pot/retailcrm-es_ES.pot | 3 + resources/pot/retailcrm-ru_RU.pot | 4 + .../class-wc-retailcrm-abstract-builder.php | 3 +- .../class-wc-retailcrm-abstracts-address.php | 3 +- .../class-wc-retailcrm-abstracts-data.php | 3 +- .../class-wc-retailcrm-abstracts-settings.php | 3 +- .../api/class-wc-retailcrm-client-v5.php | 23 +- .../api/class-wc-retailcrm-exception-curl.php | 3 +- .../api/class-wc-retailcrm-exception-json.php | 3 +- src/include/api/class-wc-retailcrm-proxy.php | 22 +- .../api/class-wc-retailcrm-request.php | 22 +- .../api/class-wc-retailcrm-response.php | 12 +- src/include/class-wc-retailcrm-base.php | 23 +- src/include/class-wc-retailcrm-customers.php | 22 +- .../class-wc-retailcrm-daemon-collector.php | 12 +- src/include/class-wc-retailcrm-ga.php | 22 +- src/include/class-wc-retailcrm-history.php | 23 +- src/include/class-wc-retailcrm-icml.php | 562 +++++------------- .../class-wc-retailcrm-inventories.php | 22 +- src/include/class-wc-retailcrm-orders.php | 22 +- src/include/class-wc-retailcrm-plugin.php | 9 +- src/include/class-wc-retailcrm-uploader.php | 22 +- .../class-wc-retailcrm-customer-switcher.php | 3 +- .../class-wc-retailcrm-history-assembler.php | 3 +- .../components/class-wc-retailcrm-logger.php | 21 +- .../class-wc-retailcrm-customer-address.php | 3 +- ...c-retailcrm-customer-corporate-address.php | 3 +- ...class-wc-retailcrm-wc-customer-builder.php | 2 +- .../icml/class-wc-retailcrm-icml-writer.php | 253 ++++++++ .../class-wc-retailcrm-builder-interface.php | 3 +- ...-wc-retailcrm-customer-switcher-result.php | 6 +- ...s-wc-retailcrm-customer-switcher-state.php | 10 +- .../class-wc-retailcrm-order-address.php | 3 +- .../order/class-wc-retailcrm-order-item.php | 2 +- .../class-wc-retailcrm-order-payment.php | 2 +- .../order/class-wc-retailcrm-order.php | 3 +- src/languages/retailcrm-es_ES.mo | Bin 9947 -> 9983 bytes src/languages/retailcrm-ru_RU.mo | Bin 12280 -> 12337 bytes src/readme.txt | 10 +- src/retailcrm.php | 13 +- src/uninstall.php | 2 +- .../test-wc-retailcrm-abstract-builder.php | 3 +- .../test-wc-retailcrm-customer-address.php | 3 +- ...c-retailcrm-customer-corporate-address.php | 3 +- .../test-wc-retailcrm-wc-customer-builder.php | 3 +- tests/datasets/data-base-retailcrm.php | 2 +- tests/datasets/data-customers-retailcrm.php | 2 +- tests/datasets/data-history-retailcrm.php | 2 +- tests/datasets/data-inventories-retailcrm.php | 2 +- .../class-wc-retailcrm-log-handler-stdout.php | 12 +- .../class-wc-retailcrm-response-helper.php | 12 +- .../class-wc-retailcrm-test-case-helper.php | 2 +- ...-wc-retailcrm-customer-switcher-result.php | 3 +- ...t-wc-retailcrm-customer-switcher-state.php | 3 +- .../order/test-wc-retailcrm-order-address.php | 3 +- tests/order/test-wc-retailcrm-order-item.php | 3 +- .../order/test-wc-retailcrm-order-payment.php | 3 +- tests/order/test-wc-retailcrm-order.php | 3 +- tests/test-wc-retailcrm-base.php | 2 +- tests/test-wc-retailcrm-customers.php | 2 +- tests/test-wc-retailcrm-daemon-collector.php | 3 +- tests/test-wc-retailcrm-ga.php | 3 +- tests/test-wc-retailcrm-history.php | 2 +- tests/test-wc-retailcrm-icml.php | 3 +- tests/test-wc-retailcrm-inventories.php | 2 +- tests/test-wc-retailcrm-orders.php | 3 +- tests/test-wc-retailcrm-plugin.php | 3 +- tests/test-wc-retailcrm-uploader.php | 3 +- 72 files changed, 672 insertions(+), 616 deletions(-) create mode 100644 src/include/icml/class-wc-retailcrm-icml-writer.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 496c79f..e5983d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2022-09-30 4.5.0 +* Fix path for js scripts +* Migrating to PHP 7.0. +* Change logic work with ICML catalog: added streaming generation, added generators in the ICML generation process. +* Change logic work with address + ## 2022-09-05 4.4.9 * Fix bug with product tax diff --git a/README.md b/README.md index 663d82d..2473833 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Build Status](https://github.com/retailcrm/woocommerce-module/workflows/woo/badge.svg)](https://github.com/retailcrm/woocommerce-module/actions) [![Coverage](https://img.shields.io/codecov/c/gh/retailcrm/woocommerce-module/master.svg?logo=github)](https://codecov.io/gh/retailcrm/woocommerce-module) [![GitHub release](https://img.shields.io/github/release/retailcrm/woocommerce-module.svg?logo=codecov)](https://github.com/retailcrm/woocommerce-module/releases) -[![PHP version](https://img.shields.io/badge/PHP->=5.4-blue.svg?logo=php)](https://php.net/) +[![PHP version](https://img.shields.io/badge/PHP->=7.0-blue.svg?logo=php)](https://php.net/) Woocommerce-module ================== diff --git a/VERSION b/VERSION index e49188c..ae15394 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.4.9 \ No newline at end of file +4.5.0 \ No newline at end of file diff --git a/composer.json b/composer.json index c287da6..afcdb46 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ ], "minimum-stability": "dev", "require": { - "ext-simplexml": "*" + "ext-simplexml": "*", + "ext-xmlwriter": "*" }, "require-dev": { "ext-json": "*", diff --git a/resources/pot/retailcrm-es_ES.pot b/resources/pot/retailcrm-es_ES.pot index 36b5a15..dcab8f6 100644 --- a/resources/pot/retailcrm-es_ES.pot +++ b/resources/pot/retailcrm-es_ES.pot @@ -339,3 +339,6 @@ msgstr "Borrar" msgid "Cron tasks cleared" msgstr "Trabajos cron borrados" + +msgid "Untitled" +msgstr "Intitulado" \ No newline at end of file diff --git a/resources/pot/retailcrm-ru_RU.pot b/resources/pot/retailcrm-ru_RU.pot index b40b676..375680b 100644 --- a/resources/pot/retailcrm-ru_RU.pot +++ b/resources/pot/retailcrm-ru_RU.pot @@ -348,3 +348,7 @@ msgstr "Очистить" msgid "Cron tasks cleared" msgstr "Cron задачи очищены" + +msgid "Untitled" +msgstr "Без названия" + diff --git a/src/include/abstracts/class-wc-retailcrm-abstract-builder.php b/src/include/abstracts/class-wc-retailcrm-abstract-builder.php index 1c6ad5f..a3651e9 100644 --- a/src/include/abstracts/class-wc-retailcrm-abstract-builder.php +++ b/src/include/abstracts/class-wc-retailcrm-abstract-builder.php @@ -1,6 +1,7 @@ - * @license https://opensource.org/licenses/MIT MIT License - * @link http://retailcrm.ru/docs/Developers/ApiVersion5 - */ - if (!class_exists('WC_Retailcrm_Request')) { include_once(WC_Integration_Retailcrm::checkCustomFile('include/api/class-wc-retailcrm-request.php')); } @@ -20,6 +8,17 @@ if (!class_exists('WC_Retailcrm_Response')) { include_once(WC_Integration_Retailcrm::checkCustomFile('include/api/class-wc-retailcrm-response.php')); } +/** + * PHP version 7.0 + * + * Class WC_Retailcrm_Client_V5 - Api Client V5 class. + * + * @category Integration + * @package WC_Retailcrm_Client + * @author RetailCRM + * @license https://opensource.org/licenses/MIT MIT License + * @link http://retailcrm.ru/docs/Developers/ApiVersion5 + */ class WC_Retailcrm_Client_V5 { protected $client; diff --git a/src/include/api/class-wc-retailcrm-exception-curl.php b/src/include/api/class-wc-retailcrm-exception-curl.php index 9e53624..0117de4 100644 --- a/src/include/api/class-wc-retailcrm-exception-curl.php +++ b/src/include/api/class-wc-retailcrm-exception-curl.php @@ -1,6 +1,7 @@ - * @license https://opensource.org/licenses/MIT MIT License - * @link http://retailcrm.ru/docs/Developers/ApiVersion5 - */ if (!class_exists('WC_Retailcrm_Proxy')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Proxy - RetailCRM Integration. + * + * @category Integration + * @package WC_Retailcrm_Proxy + * @author RetailCRM + * @license https://opensource.org/licenses/MIT MIT License + * @link http://retailcrm.ru/docs/Developers/ApiVersion5 + */ class WC_Retailcrm_Proxy { protected $retailcrm; diff --git a/src/include/api/class-wc-retailcrm-request.php b/src/include/api/class-wc-retailcrm-request.php index 9fdb45b..82d14d3 100644 --- a/src/include/api/class-wc-retailcrm-request.php +++ b/src/include/api/class-wc-retailcrm-request.php @@ -1,15 +1,4 @@ - * @license https://opensource.org/licenses/MIT MIT License - * @link http://retailcrm.ru/docs/Developers/ApiVersion5 - */ if (!class_exists('WC_Retailcrm_Exception_Curl')) { include_once(WC_Integration_Retailcrm::checkCustomFile('include/api/class-wc-retailcrm-exception-curl.php')); @@ -19,6 +8,17 @@ if (!class_exists('WC_Retailcrm_Response')) { include_once(WC_Integration_Retailcrm::checkCustomFile('include/api/class-wc-retailcrm-response.php')); } +/** + * PHP version 7.0 + * + * Class WC_Retailcrm_Request - Request class. + * + * @category Integration + * @package WC_Retailcrm_Request + * @author RetailCRM + * @license https://opensource.org/licenses/MIT MIT License + * @link http://retailcrm.ru/docs/Developers/ApiVersion5 + */ class WC_Retailcrm_Request { const METHOD_GET = 'GET'; diff --git a/src/include/api/class-wc-retailcrm-response.php b/src/include/api/class-wc-retailcrm-response.php index 6b2576f..48e4c9a 100644 --- a/src/include/api/class-wc-retailcrm-response.php +++ b/src/include/api/class-wc-retailcrm-response.php @@ -1,6 +1,11 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ - if (!class_exists('WC_Retailcrm_Base')) { if (!class_exists('WC_Retailcrm_Abstracts_Settings')) { include_once(WC_Integration_Retailcrm::checkCustomFile('include/abstracts/class-wc-retailcrm-abstracts-settings.php')); } + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Base - Main settings plugin. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Base extends WC_Retailcrm_Abstracts_Settings { /** @var WC_Retailcrm_Proxy|WC_Retailcrm_Client_V5|bool */ diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index f0a4211..c6c34a3 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -1,17 +1,17 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (!class_exists('WC_Retailcrm_Customers')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Customers - Allows transfer data customers with CMS. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Customers { /** @var bool | WC_Retailcrm_Proxy | \WC_Retailcrm_Client_V5 */ diff --git a/src/include/class-wc-retailcrm-daemon-collector.php b/src/include/class-wc-retailcrm-daemon-collector.php index cca9b53..670c5a3 100644 --- a/src/include/class-wc-retailcrm-daemon-collector.php +++ b/src/include/class-wc-retailcrm-daemon-collector.php @@ -1,6 +1,11 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (!class_exists('WC_Retailcrm_Google_Analytics')) { + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Google_Analytics - Integration with Google Analytics. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Google_Analytics { private static $instance; private $options; diff --git a/src/include/class-wc-retailcrm-history.php b/src/include/class-wc-retailcrm-history.php index 0157a86..96cc2e9 100644 --- a/src/include/class-wc-retailcrm-history.php +++ b/src/include/class-wc-retailcrm-history.php @@ -1,18 +1,17 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ - if (!class_exists('WC_Retailcrm_History')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_History - Allows transfer data orders/customers with CRM. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_History { const PAGE_LIMIT = 25; diff --git a/src/include/class-wc-retailcrm-icml.php b/src/include/class-wc-retailcrm-icml.php index 4dbbc8a..31d486a 100644 --- a/src/include/class-wc-retailcrm-icml.php +++ b/src/include/class-wc-retailcrm-icml.php @@ -1,25 +1,20 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ - if (!class_exists('WC_Retailcrm_Icml')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Icml - Generate ICML file (catalog). + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Icml { - protected $shop; - protected $file; - protected $tmpFile; - - protected $properties = [ + const OFFER_PROPERTIES = [ 'name', 'productName', 'price', @@ -31,19 +26,11 @@ if (!class_exists('WC_Retailcrm_Icml')) : 'productActivity' ]; - protected $xml; - - /** @var SimpleXMLElement $categories */ - protected $categories; - - /** @var SimpleXMLElement $categories */ - protected $offers; - - protected $chunk = 500; - protected $fileLifeTime = 3600; - - /** @var array */ + protected $shop; + protected $file; + protected $tmpFile; protected $settings; + protected $icmlWriter; /** * WC_Retailcrm_Icml constructor. @@ -51,410 +38,125 @@ if (!class_exists('WC_Retailcrm_Icml')) : */ public function __construct() { - $this->settings = get_option(WC_Retailcrm_Base::$option_key); - $this->shop = get_bloginfo('name'); - $this->file = ABSPATH . 'simla.xml'; - $this->tmpFile = sprintf('%s.tmp', $this->file); + $this->shop = get_bloginfo('name'); + $this->file = ABSPATH . 'simla.xml'; + $this->tmpFile = sprintf('%s.tmp', $this->file); + $this->settings = get_option(WC_Retailcrm_Base::$option_key); + $this->icmlWriter = new WC_Retailcrm_Icml_Writer($this->tmpFile); } /** - * Generate file + * Generate ICML catalog. */ public function generate() { - $categories = $this->get_wc_categories_taxonomies(); + $this->icmlWriter->writeHead($this->shop); - if (file_exists($this->tmpFile)) { - if (filectime($this->tmpFile) + $this->fileLifeTime < time()) { - unlink($this->tmpFile); - $this->writeHead(); - } - } else { - $this->writeHead(); + $categories = $this->prepareCategories(); + + if (empty($categories)) { + writeBaseLogs('Can`t get categories!'); + return; } - try { - if (!empty($categories)) { - $this->writeCategories($categories); - unset($categories); - } + $this->icmlWriter->writeCategories($categories); - $status_args = $this->checkPostStatuses(); - $this->get_wc_products_taxonomies($status_args); + $offers = $this->prepareOffers(); - $dom = dom_import_simplexml(simplexml_load_file($this->tmpFile))->ownerDocument; - - $dom->formatOutput = true; - - $formatted = $dom->saveXML(); - - unset($dom, $this->xml); - - file_put_contents($this->tmpFile, $formatted); - rename($this->tmpFile, $this->file); - } catch (Exception $e) { - unlink($this->tmpFile); - } - } - - /** - * Load tmp data - * - * @return \SimpleXMLElement - */ - private function loadXml() - { - return new SimpleXMLElement( - $this->tmpFile, - LIBXML_NOENT | LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE, - true - ); - } - - /** - * Generate xml header - */ - private function writeHead() - { - $string = sprintf( - '%s', - current_time('Y-m-d H:i:s'), - html_entity_decode($this->shop) - ); - - file_put_contents($this->tmpFile, $string, LOCK_EX); - } - - /** - * Write categories in file - * - * @param $categories - */ - private function writeCategories($categories) - { - $chunkCategories = array_chunk($categories, $this->chunk); - foreach ($chunkCategories as $categories) { - $this->xml = $this->loadXml(); - - $this->categories = $this->xml->shop->categories; - $this->addCategories($categories); - - $this->xml->asXML($this->tmpFile); + if (empty($offers)) { + writeBaseLogs('Can`t get offers!'); + return; } - unset($this->categories); + $this->icmlWriter->writeOffers($offers); + + $this->icmlWriter->writeEnd(); + $this->icmlWriter->formatXml($this->tmpFile); + + rename($this->tmpFile, $this->file); } /** - * Write products in file - * - * @param $offers - */ - private function writeOffers($offers) - { - $chunkOffers = array_chunk($offers, $this->chunk); - foreach ($chunkOffers as $offers) { - $this->xml = $this->loadXml(); - - $this->offers = $this->xml->shop->offers; - $this->addOffers($offers); - - $this->xml->asXML($this->tmpFile); - } - - unset($this->offers); - } - - /** - * Add categories - * - * @param $categories - */ - private function addCategories($categories) - { - $categories = self::filterRecursive($categories); - - foreach ($categories as $category) { - if (!array_key_exists('name', $category) || !array_key_exists('id', $category)) { - continue; - } - - /** @var SimpleXMLElement $e */ - /** @var SimpleXMLElement $cat */ - - $cat = $this->categories; - $e = $cat->addChild('category'); - - $e->addAttribute('id', $category['id']); - - if (array_key_exists('parentId', $category) && $category['parentId'] > 0) { - $e->addAttribute('parentId', $category['parentId']); - } - - $e->addChild('name', $category['name']); - - if (array_key_exists('picture', $category)) { - $e->addChild('picture', $category['picture']); - } - } - } - - /** - * Add offers - * - * @param $offers - */ - private function addOffers($offers) - { - $offers = self::filterRecursive($offers); - - foreach ($offers as $key => $offer) { - if (!array_key_exists('id', $offer)) { - continue; - } - - $e = $this->offers->addChild('offer'); - - $e->addAttribute('id', $offer['id']); - - if (!array_key_exists('productId', $offer) || empty($offer['productId'])) { - $offer['productId'] = $offer['id']; - } - $e->addAttribute('productId', $offer['productId']); - - if (!empty($offer['quantity'])) { - $e->addAttribute('quantity', (int) $offer['quantity']); - } else { - $e->addAttribute('quantity', 0); - } - - if (isset($offer['categoryId']) && $offer['categoryId']) { - if (is_array($offer['categoryId'])) { - foreach ($offer['categoryId'] as $categoryId) { - $e->addChild('categoryId', $categoryId); - } - } else { - $e->addChild('categoryId', $offer['categoryId']); - } - } - - if (!array_key_exists('name', $offer) || empty($offer['name'])) { - $offer['name'] = 'Без названия'; - } - - if (!array_key_exists('productName', $offer) || empty($offer['productName'])) { - $offer['productName'] = $offer['name']; - } - - if (array_key_exists('picture', $offer) && !empty($offer['picture'])) { - foreach ($offer['picture'] as $urlImage) { - $e->addChild('picture', $urlImage); - } - } - - unset($offer['id'], $offer['productId'], $offer['categoryId'], $offer['quantity'], $offer['picture']); - array_walk($offer, [$this, 'setOffersProperties'], $e); - - if (array_key_exists('params', $offer) && !empty($offer['params'])) { - array_walk($offer['params'], [$this, 'setOffersParams'], $e); - } - - if (array_key_exists('dimensions', $offer)) { - $e->addChild('dimensions', $offer['dimensions']); - } - - if (array_key_exists('weight', $offer)) { - $e->addChild('weight', $offer['weight']); - } - - if (array_key_exists('tax', $offer)) { - $e->addChild('vatRate', $offer['tax']); - } - - unset($offers[$key]); - } - } - - /** - * Set offer properties - * - * @param $value - * @param $key - * @param $e - */ - private function setOffersProperties($value, $key, &$e) - { - if (in_array($key, $this->properties) && $key != 'params') { - /** @var SimpleXMLElement $e */ - $e->addChild($key, htmlspecialchars($value)); - } - } - - /** - * Set offer params - * - * @param $value - * @param $key - * @param $e - */ - private function setOffersParams($value, $key, &$e) - { - if ( - array_key_exists('code', $value) && - array_key_exists('name', $value) && - array_key_exists('value', $value) && - !empty($value['code']) && - !empty($value['name']) && - !empty($value['value']) - ) { - /** @var SimpleXMLElement $e */ - $param = $e->addChild('param', htmlspecialchars($value['value'])); - $param->addAttribute('code', $value['code']); - $param->addAttribute('name', substr(htmlspecialchars($value['name']), 0, 200)); - unset($key); - } - } - - /** - * Filter result array - * - * @param $haystack - * - * @return mixed - */ - public static function filterRecursive($haystack) - { - foreach ($haystack as $key => $value) { - if (is_array($value)) { - $haystack[$key] = self::filterRecursive($haystack[$key]); - } - - if ( - is_null($haystack[$key]) - || $haystack[$key] === '' - || (is_array($haystack[$key]) && count($haystack[$key]) == 0) - ) { - unset($haystack[$key]); - } elseif (!is_array($value)) { - $haystack[$key] = trim($value); - } - } - - return $haystack; - } - - /** - * Get WC products + * Prepare WC offers for write. * * @return void */ - private function get_wc_products_taxonomies($status_args) + private function prepareOffers() { - if (!$status_args) { - $status_args = ['publish']; + $productStatuses = $this->getProductStatuses(); + + if (!$productStatuses) { + $productStatuses = ['publish']; } - $attribute_taxonomies = wc_get_attribute_taxonomies(); - $product_attributes = []; + $page = 1; + $offerAttributes = $this->getOfferAttributes(); - foreach ($attribute_taxonomies as $product_attribute) { - $attribute_id = wc_attribute_taxonomy_name_by_id(intval($product_attribute->attribute_id)); - $product_attributes[$attribute_id] = $product_attribute->attribute_label; - } + do { + $products = wc_get_products( + [ + 'limit' => 1000, + 'status' => $productStatuses, + 'page' => $page, + 'paginate' => true, + ] + ); - $full_product_list = []; - - $products = wc_get_products( - [ - 'limit' => -1, - 'status' => $status_args - ] - ); - - foreach ($products as $offer) { - $type = $offer->get_type(); - - if (strpos($type, 'variable') !== false || strpos($type, 'variation') !== false) { - foreach ($offer->get_children() as $child_id) { - $child_product = wc_get_product($child_id); - if (!$child_product) { - continue; - } - - $this->setOffer($full_product_list, $product_attributes, $child_product, $offer); - } - } else { - $this->setOffer($full_product_list, $product_attributes, $offer); + if (empty($products)) { + writeBaseLogs('Can`t get products!'); + return; } - } - if (isset($full_product_list) && $full_product_list) { - $this->writeOffers($full_product_list); - unset($full_product_list); - } + foreach ($products->products as $offer) { + $type = $offer->get_type(); + + if (strpos($type, 'variable') !== false || strpos($type, 'variation') !== false) { + foreach ($offer->get_children() as $childId) { + $childProduct = wc_get_product($childId); + + if (!$childProduct) { + continue; + } + + yield $this->getOffer($offerAttributes, $childProduct, $offer); + } + } else { + yield $this->getOffer($offerAttributes, $offer); + } + } + + $page++; + } while ($page <= $products->max_num_pages); } /** - * Get WC categories + * Get WC offer attributes. * * @return array */ - private function get_wc_categories_taxonomies() + private function getOfferAttributes() { - $categories = []; - $taxonomy = 'product_cat'; - $orderby = 'parent'; - $show_count = 0; // 1 for yes, 0 for no - $pad_counts = 0; // 1 for yes, 0 for no - $hierarchical = 1; // 1 for yes, 0 for no - $title = ''; - $empty = 0; + $offerAttributes = []; + $attributeTaxonomies = wc_get_attribute_taxonomies(); - $args = [ - 'taxonomy' => $taxonomy, - 'orderby' => $orderby, - 'show_count' => $show_count, - 'pad_counts' => $pad_counts, - 'hierarchical' => $hierarchical, - 'title_li' => $title, - 'hide_empty' => $empty - ]; - - $wcatTerms = get_categories($args); - - foreach ($wcatTerms as $term) { - $category = [ - 'id' => $term->term_id, - 'parentId' => $term->parent, - 'name' => $term->name - ]; - - $thumbnail_id = function_exists('get_term_meta') - ? get_term_meta($term->term_id, 'thumbnail_id', true) - : get_woocommerce_term_meta($term->term_id, 'thumbnail_id', true); - $picture = wp_get_attachment_url($thumbnail_id); - - if ($picture) { - $category['picture'] = $picture; - } - - $categories[] = $category; + foreach ($attributeTaxonomies as $productAttribute) { + $attributeId = wc_attribute_taxonomy_name_by_id(intval($productAttribute->attribute_id)); + $offerAttributes[$attributeId] = $productAttribute->attribute_label; } - return $categories; + return $offerAttributes; } /** - * Set offer for icml catalog + * Get offer for ICML catalog * - * @param array $full_product_list - * @param array $product_attributes + * @param array $productAttributes * @param WC_Product $product * @param bool | WC_Product_Variable $parent * - * @return void + * @return array */ - private function setOffer(&$full_product_list, $product_attributes, $product, $parent = false) + private function getOffer(array $productAttributes, WC_Product $product, $parent = false) { $idImages = array_merge([$product->get_image_id()], $product->get_gallery_image_ids()); @@ -482,12 +184,12 @@ if (!class_exists('WC_Retailcrm_Icml')) : $params = []; if (!empty($attributes)) { - foreach ($attributes as $attribute_name => $attribute) { - $attributeValue = $product->get_attribute($attribute_name); + foreach ($attributes as $attributeName => $attribute) { + $attributeValue = $product->get_attribute($attributeName); if ($attribute['is_visible'] == 1 && !empty($attributeValue)) { $params[] = [ - 'code' => $attribute_name, - 'name' => $product_attributes[$attribute_name], + 'code' => $attributeName, + 'name' => $productAttributes[$attributeName], 'value' => $attributeValue ]; } @@ -550,10 +252,10 @@ if (!class_exists('WC_Retailcrm_Icml')) : } if (isset($this->settings['product_description'])) { - $productDescription = $this->getDescription($product); + $productDescription = $this->getOfferDescription($product); if (empty($productDescription) && $parent instanceof WC_Product_Variable) { - $this->getDescription($parent); + $this->getOfferDescription($parent); } if ($productDescription != '') { @@ -572,43 +274,91 @@ if (!class_exists('WC_Retailcrm_Icml')) : ); if (isset($productData)) { - $full_product_list[] = $productData; + return $productData; } - - unset($productData); } /** - * Get product statuses + * Get product statuses. * * @return array */ - private function checkPostStatuses() + private function getProductStatuses() { - $status_args = []; + $statuses = []; foreach (get_post_statuses() as $key => $value) { if (isset($this->settings['p_' . $key]) && $this->settings['p_' . $key] == WC_Retailcrm_Base::YES) { - $status_args[] = $key; + $statuses[] = $key; } } - return $status_args; + return $statuses; } /** - * Get product description + * Get offer description. * * @param WC_Product | WC_Product_Variable $product WC product. * * @return string */ - private function getDescription($product) + private function getOfferDescription($product) { return $this->settings['product_description'] == 'full' ? $product->get_description() : $product->get_short_description(); } - } + /** + * Prepare WC categories for write. + * + * @return array + */ + private function prepareCategories() + { + $categories = []; + $taxonomy = 'product_cat'; + $orderby = 'parent'; + $show_count = 0; // 1 for yes, 0 for no + $pad_counts = 0; // 1 for yes, 0 for no + $hierarchical = 1; // 1 for yes, 0 for no + $title = ''; + $empty = 0; + + $args = [ + 'taxonomy' => $taxonomy, + 'orderby' => $orderby, + 'show_count' => $show_count, + 'pad_counts' => $pad_counts, + 'hierarchical' => $hierarchical, + 'title_li' => $title, + 'hide_empty' => $empty + ]; + + $wcTerms = get_categories($args); + + foreach ($wcTerms as $term) { + $category = [ + 'id' => $term->term_id, + 'parentId' => $term->parent, + 'name' => $term->name + ]; + + $thumbnailId = function_exists('get_term_meta') + ? get_term_meta($term->term_id, 'thumbnail_id', true) + : get_woocommerce_term_meta($term->term_id, 'thumbnail_id', true); + + $picture = wp_get_attachment_url($thumbnailId); + + if ($picture) { + $category['picture'] = $picture; + } + + $categories[] = $category; + } + + return $categories; + } + } endif; diff --git a/src/include/class-wc-retailcrm-inventories.php b/src/include/class-wc-retailcrm-inventories.php index ccccc65..d526d96 100644 --- a/src/include/class-wc-retailcrm-inventories.php +++ b/src/include/class-wc-retailcrm-inventories.php @@ -1,17 +1,17 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (!class_exists('WC_Retailcrm_Inventories')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Inventories - Allows manage stocks. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Inventories { /** @var WC_Retailcrm_Client_V5 */ diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 6ee45b8..1977b9d 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -1,17 +1,17 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (!class_exists('WC_Retailcrm_Orders')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Orders - Allows transfer data orders with CMS. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Orders { /** @var bool|WC_Retailcrm_Proxy|WC_Retailcrm_Client_V5 */ diff --git a/src/include/class-wc-retailcrm-plugin.php b/src/include/class-wc-retailcrm-plugin.php index d307268..1e9bdac 100644 --- a/src/include/class-wc-retailcrm-plugin.php +++ b/src/include/class-wc-retailcrm-plugin.php @@ -1,6 +1,7 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (class_exists('WC_Retailcrm_Uploader') === false) { + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Uploader - Allows upload archival orders/customers in CRM. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ class WC_Retailcrm_Uploader { const RETAILCRM_COUNT_OBJECT_UPLOAD = 50; diff --git a/src/include/components/class-wc-retailcrm-customer-switcher.php b/src/include/components/class-wc-retailcrm-customer-switcher.php index 3b4fe77..6afd466 100644 --- a/src/include/components/class-wc-retailcrm-customer-switcher.php +++ b/src/include/components/class-wc-retailcrm-customer-switcher.php @@ -1,6 +1,7 @@ - * @license http://retailcrm.ru Proprietary - * @link http://retailcrm.ru - * @see http://help.retailcrm.ru - */ if (!class_exists('WC_Retailcrm_Logger') && class_exists('WC_Log_Levels')) : + /** + * PHP version 7.0 + * + * Class WC_Retailcrm_Logger - Allows display important debug information. + * + * @category Integration + * @author RetailCRM + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru * @codeCoverageIgnore */ class WC_Retailcrm_Logger diff --git a/src/include/customer/class-wc-retailcrm-customer-address.php b/src/include/customer/class-wc-retailcrm-customer-address.php index 0e85f96..2d191bb 100644 --- a/src/include/customer/class-wc-retailcrm-customer-address.php +++ b/src/include/customer/class-wc-retailcrm-customer-address.php @@ -1,6 +1,7 @@ + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ + class WC_Retailcrm_Icml_Writer + { + private $writer; + + public function __construct($tmpFile) + { + $this->writer = new \XMLWriter(); + $this->writer->openUri($tmpFile); + } + + /** + * Write HEAD in ICML catalog. + * + * @param string $shop + * + * @return void + */ + public function writeHead(string $shop) + { + $this->writer->startDocument('1.0', 'UTF-8'); + $this->writer->startElement('yml_catalog'); // start + $this->writer->writeAttribute('date', date('Y-m-d H:i:s')); + $this->writer->startElement('shop'); // start + $this->writer->WriteElement('name', $shop); + } + + /** + * Write categories in ICML catalog. + * + * @param array $categories + * + * @return void + */ + public function writeCategories(array $categories) + { + $this->writer->startElement('categories'); // start + + $this->addCategories($categories); + + $this->writer->endElement(); // end + } + + /** + * Add category in ICML catalog. + * + * @param array $categories + * + * @return void + */ + private function addCategories(array $categories) + { + foreach ($categories as $category) { + if (!array_key_exists('name', $category) || !array_key_exists('id', $category)) { + continue; + } + + $this->writer->startElement('category'); // start + + $this->writer->writeAttribute('id', $category['id']); + + if (array_key_exists('parentId', $category) && 0 < $category['parentId']) { + $this->writer->writeAttribute('parentId', $category['parentId']); + } + + $this->writer->writeElement('name', $category['name']); + + if (array_key_exists('picture', $category) && $category['picture']) { + $this->writer->writeElement('picture', $category['picture']); + } + + $this->writer->endElement(); // end + } + } + + /** + * Write offers in ICML catalog. + * + * @return void + */ + public function writeOffers($offers) + { + $this->writer->startElement('offers'); // start + + $this->addOffers($offers); + + $this->writer->endElement(); // end + } + + /** + * Add offer in ICML catalog. + * + * @return void + */ + private function addOffers($offers) + { + foreach ($offers as $offer) { + if (!array_key_exists('id', $offer)) { + continue; + } + + $this->writer->startElement('offer'); // start + + if (!array_key_exists('productId', $offer) || empty($offer['productId'])) { + $offer['productId'] = $offer['id']; + } + + $this->writer->writeAttribute('id', $offer['id']); + $this->writer->writeAttribute('productId', $offer['productId']); + $this->writer->writeAttribute('quantity', (int) $offer['quantity'] ?? 0); + + if (isset($offer['categoryId'])) { + if (is_array($offer['categoryId'])) { + foreach ($offer['categoryId'] as $categoryId) { + $this->writer->writeElement('categoryId', $categoryId); + } + } else { + $this->writer->writeElement('categoryId', $offer['$categoryId']); + } + } + + if (!empty($offer['picture'])) { + foreach ($offer['picture'] as $urlImage) { + $this->writer->writeElement('picture', $urlImage); + } + } + + if (empty($offer['name'])) { + $offer['name'] = __('Untitled', 'retailcrm'); + } + + if (empty($offer['productName'])) { + $offer['productName'] = $offer['name']; + } + + unset($offer['id'], $offer['productId'], $offer['categoryId'], $offer['quantity'], $offer['picture']); + + $this->writeOffersProperties($offer); + + if (!empty($offer['params'])) { + $this->writeOffersParams($offer['params']); + } + + if (!empty($offer['dimensions'])) { + $this->writer->writeElement('dimensions', $offer['dimensions']); + } + + if (!empty($offer['weight'])) { + $this->writer->writeElement('weight', $offer['weight']); + } + + if (!empty($offer['tax'])) { + $this->writer->writeElement('vatRate', $offer['tax']); + } + + $this->writer->endElement(); // end + } + } + + /** + * Set offer properties. + * + * @param array $offerProperties + * + * @return void + */ + private function writeOffersProperties(array $offerProperties) + { + foreach ($offerProperties as $key => $value) { + if (!in_array($key, WC_Retailcrm_Icml::OFFER_PROPERTIES)) { + continue; + } + + if (is_array($value)) { + foreach ($value as $element) { + $this->writer->writeElement($key, $element); + } + } else { + $this->writer->writeElement($key, $value); + } + } + } + + /** + * Set offer params. + * + * @param array $offerParams + * + * @return void + */ + private function writeOffersParams(array $offerParams) + { + foreach ($offerParams as $param) { + if ( + empty($param['code']) + || empty($param['name']) + || empty($param['value']) + ) { + continue; + } + + $this->writer->startElement('param'); // start + + $this->writer->writeAttribute('code', $param['code']); + $this->writer->writeAttribute('name', $param['name']); + $this->writer->text($param['value']); + + $this->writer->endElement(); // end + } + } + + /** + * Write end tags in ICML catalog. + * + * @return void + */ + public function writeEnd() + { + $this->writer->endElement(); // end + $this->writer->endElement(); // end + $this->writer->endDocument(); + } + + /** + * Save ICML catalog. + * + * @return void + */ + public function formatXml($tmpfile) + { + $dom = dom_import_simplexml(simplexml_load_file($tmpfile))->ownerDocument; + $dom->formatOutput = true; + $formatted = $dom->saveXML(); + + unset($dom, $this->writer); + + file_put_contents($tmpfile, $formatted); + } + } +endif; diff --git a/src/include/interfaces/class-wc-retailcrm-builder-interface.php b/src/include/interfaces/class-wc-retailcrm-builder-interface.php index d3abfb9..8b27fb6 100644 --- a/src/include/interfaces/class-wc-retailcrm-builder-interface.php +++ b/src/include/interfaces/class-wc-retailcrm-builder-interface.php @@ -1,6 +1,7 @@ wcCustomer = $wcCustomer; $this->wcOrder = $wcOrder; - if ((!is_null($this->wcCustomer) && !($this->wcCustomer instanceof WC_Customer)) + if ( + (!is_null($this->wcCustomer) && !($this->wcCustomer instanceof WC_Customer)) || !($this->wcOrder instanceof WC_Order) ) { throw new \InvalidArgumentException(sprintf('Incorrect data provided to %s', __CLASS__)); diff --git a/src/include/models/class-wc-retailcrm-customer-switcher-state.php b/src/include/models/class-wc-retailcrm-customer-switcher-state.php index 26a69ce..b323175 100644 --- a/src/include/models/class-wc-retailcrm-customer-switcher-state.php +++ b/src/include/models/class-wc-retailcrm-customer-switcher-state.php @@ -1,6 +1,7 @@ ))D@M4iHwY-2^DQpY|X4H(Ay z<{BLb15c1SO%D#mk2ns0S-*#qwgN~*Wt54Na6cAf3npL~(Wqh>n1tDwhLxy=+fe~^ zVK(cVKXepv7ON`4B4o(y!eLl#jUPqUFlVjtYpCb$TlcSU4fh{$J}%+m46MOee2&BM zH%`W3Eap)LbLl9e%{UEfQ313gU-Q(ue}mJx|BN~wF_cYP5RW4;74=*$YJoMV1?y1r zG@|~09W(KfgZe8Y2ctTCk!Z)+s0q_iXQ2Rj#+0GRORw83in_N9!GY; zbfPNp7Dr(a*(jk2T-q?zLx&*EPt;Zf@~?6qCP7u^Dp4u3Hq?ZVQ5n5N9nN>C*C~LD z4sSGSJQ33{2Xz>aSe`)5dj{8`r;0lBBUk8dHT)n1yFh3-@9Y&SP~Q-mR#>sxSp_V!VgWH#*rEF}8m}H>x64sLYRH zK0ZM0z)_6M-tLeld>_yF=7fp2(SqU9YychLDHEO&8 zbp|e>Ub{QUc{7htZ$%GkuRo!-;5%~AO>9j6g0n3PFrD$;xB_qELJW3Ne=V5LiO^wj zqc0vomAoF=F4KtG+k0rk4rDF!40Tq%qe>ddBsyd(aSrZ4k~J-;t?a}X_#Tzm-B{9A zi95X?{8sz8y$k&>`)u-l^$+pc;0>^cCl~YE6xsmVESeTm#)Y)aH0^IGO_M2bZIjDe zV2^REr#F^XLerkoTcpnqw3ak;z5)tWqFd(fav-R*R*b(OWAb0+)# E104^@EdT%j delta 1919 zcmXZbTZmOv7zglmMn`9yyib~%WjY#ZI%PH~W$KWDl6kivFw09#Wh6-=rN=@dvxGPq zg;Z)nQDm5Ov8WyrlZ=ueMFk6bDUuK$DtoctKhNQ;^V@6fv)B5*Z>@b{&Z#-o(*wG1 zFFvca%eBqjO3A>P9)5hLHcnKG=h4--^S91tA*2iDvNc}yW!f!Z?6_Z@X z;qCEPsQzFM=0sYv%w_^v#LT~r z3G_J*wSL*{qQ8MJXs+@D`|u>M;_vnQEz(W^!k(%1%DY zEWD2i=m_t$e)-cyBA#m1M7WrS$}0Bd+WPorTBB^QkMCxl`>@{smdo@{at3eq@a^2d zF+9kD{DTvCfz@O%!K#Vq9!}&&CV+kPEnn69M>$FVG;=%#DqFT-C|fz6d9IULU>>tz zm6@l;{C^K;@ss}QpNuL-bNKqOiQ||FCoyMX7Clq$W%hIp^S>wSZe|vKk?q{UHXflQ z%ULFn{ESB{m#}l7`lm#%8AvIA;c))L1`ZO1?Jq-^3`R4VcQ6&3$}72ylevkiUk)%8 zILtx(n@OaPpU>DvF_oXIF0uvZxVB<4|4v0-7ELnR#Z34ClgXFNq5PhCjm|QMwpl0R zt?Xn6a|qYheVUnf3-9MEv}CECcac-w*U?O7R>zPaupNU#~jOJT)>L`P2h{zH}C%wE>fCjnM`X;hP#<9__RKLh^fF&lw3K( zXV~M4Qs!_Av+!}Y^J=T-(B8!a*2T%($pmzQ|G)p;M_gQRA(f%3I=KmKKC78{xr^L*xPGI`?9ofi>$Zo^ zS=r0H4TqS${*l>&Q*^*f?@<>Q99efdZ!^A>i}@C3@;tNNv^Mq6VOi*8G;lpr@~3FK z%JXdG+q6b`pE)B(nNt2s+h1-l$t|2qNtPFwE!@jvJjf)pW6Z_M?qx-Pe5p0`Tu>>s z#XaAvJW#7N4X&)L4QU#7vcIdfOq#&6P0MRtO{4lh>}rJ8 hrRB4t_IlIu#z$PO+TYmR*|L9L>tp@)A8DJ^@E?O+x6=Rs diff --git a/src/languages/retailcrm-ru_RU.mo b/src/languages/retailcrm-ru_RU.mo index c4ddf79656e730eb1b057fd47f321d4eec90d11e..9b8246da7b7df77d70d3aa186f79e7f38f607ed2 100644 GIT binary patch delta 2507 zcmYk;e@vBC9LMo5a6_(0DHlae=#d%yAqjU4AoF58`+{j1%y6OvH0I4KI1^uW=IXYd95u z#W@(y#RZsw_hJ+BdDy~K__H1kYw$Eq#NTi-#&DOrFco!vCaQyMOu|Y`#*JRP1*g+~ z5mWIfG6s7GHIVmE{fyu=?r%4#=mHu?S~lmG^lYY5-x>jCwH>uVORC zGO7jGippFMF2s|#9HXd=1?YSZ_qQx6)mVcX@d?xj2axaD=Xehed*?@yd)Z&!c^@C@ zx)jt5Gg04P%b@}5u?z>X9AoMHeyqT7fJz6IY}|*MNd(o=54afPNQ(xNhn%vNUVA;} z(r&_d>_IKX2~5F$)OACs{;#6$=i^K2XKFI}*993IDzFGOvjeEj*o_Hz5!K-bs6Fu& z(wE&pt?i$v@2Pj`N8LCX7h(|SVhxf6dmj0-{Q>fyMddiH4LF2K(Jbz!l!kC7?!s8? zMYfB*iJHNA)D1sGW#ALkUit!+!BI>@KcilX8OW+xBPt_1!c?YEIf?w)0Ef%?B{C`N z;zKP-FLuVT7f=~0=GoEaszhC1iyBZfX5dSxO?n2kc?Yoyf5au2%?@nBa3d96_?hST zsMP*~&*9&gj_piKBR+!q{>P{pev2h|3+H1lcMW1aY9PC@6whNZ-b7_!9_w4E=Rco{ zI^2o6(O%Sz&Z0UPM#kXQL8+Y1dOV7S7{pg_Ird=-{(*J4WfseXmvIGd;$q$B4SWzU zV4I%*8&no?qBc0TMtgA=?T=71DkOhQ&O)d?u^Tm@9^_uuj}Ktf`}{V}qdk%ItiuA- z#17$4*oR%%&B+(Izs+E4uEt}i8DIC>3HO<;qP-4F@i=zk2yzdr<{?(c9jFN$MP=Yq z)E>!UR12^KHK1)s_N^Nq#y$*d2DhjvH37b*j_2YLEce@a@P|x}bD8@~=CyV^&P`Sp5M=*(JtgHqc-loC%6T051+ z#2TVl4N4-RG?Og%lMKew<mC31-ZVhiys@g$K%#1W6*nZJ*Q-pgeK zo7epoJcA`fkeE&Uzv!`A;+v!j z4^NkS!RVZO@pvEdRJu*4ov-o~kxy(V>WGbmHWho-?IFFERhAOkOL~W>Xus7Eyw_|I zuVeT2YQa0DRh3AaKRrPL8RA?bxqj#5$>jq#@yfAYI~3B^l(v@ ziGkvYj-}+rz^*=&W!+0j^)?>LJ9#+o<6+#y20mH8ew)2q@8SS{&LRAXW7$h1$FP;Y zua$)=X?V4di@BaX`6c`E2X^M)_4}Rmng;r@2T$iwJimT@8IN{7kNvrd`YsPK19^&R zeLwOuWGvCi<2C$Hs(Hait4ld??p2}H9m&~o^NUq~V zZf7!fkVEue`s!smo0$=>Wk&ckJyTxik$ks){}bw??5p2D!2IqnW`=z{oae{*n9C`g zz*l%7_wz(H>7>?Mv24Tt?a_p%u=jnA8uiu z+sd@RgX!-8(~gI0)en04)l}C*nVH?fY{t9UjgK-7KFjQhx2TQsF|)RNndiQ*`wP?Y zpB%|Uht)}9yJmTXWzD9#C3w@iVxQi|y6!&k4-$YA@C+Z!sx-pUe3bkLNVg%7|}ce((%4 z!#8*y_iz|{>$Q>RF#~Dics|H+{E*2&SL=E<`%!zfGE*fT&1X7#fN9`O8bjH~r1B45 z#s=%r$fcafjaFQ`+S3_n2S>rJ(#Q^MWlqg>%4)fR8Q@y_D_eY=%lA2not*J2 z*}^71$7$R%LjJSqhWJQ>GdbfB$B$`nySGOg{D^K>&rWAfN_PL@!pW*;kLqpNBbEP^ z%zBRSI{2?7li7b&$?Q|cw^RKCs#mKQPDY!OGn|b5TV|_dfY}E&d{wd}DHn?i#gtqq zR $action, 'plugin' => $pluginSlug - ), + ], admin_url( 'update.php' ) ), $action.'_'.$pluginSlug @@ -205,5 +206,5 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : $plugin->register_activation_hook(); $plugin->register_deactivation_hook(); - add_action('plugins_loaded', array('WC_Integration_Retailcrm', 'get_instance'), 0); + add_action('plugins_loaded', ['WC_Integration_Retailcrm', 'get_instance'], 0); endif; diff --git a/src/uninstall.php b/src/uninstall.php index e7878dc..62e7508 100644 --- a/src/uninstall.php +++ b/src/uninstall.php @@ -16,7 +16,7 @@ * * @link https://wordpress.org/plugins/woo-retailcrm/ * - * @version 4.4.9 + * @version 4.5.0 * * @package RetailCRM */ diff --git a/tests/abstracts/test-wc-retailcrm-abstract-builder.php b/tests/abstracts/test-wc-retailcrm-abstract-builder.php index 5d0a476..15ae18f 100644 --- a/tests/abstracts/test-wc-retailcrm-abstract-builder.php +++ b/tests/abstracts/test-wc-retailcrm-abstract-builder.php @@ -1,6 +1,7 @@