Custom filters

This commit is contained in:
max-baranikov 2021-05-28 15:51:15 +03:00 committed by GitHub
parent 6cdb1f48a0
commit 1206634b9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 297 additions and 8 deletions

3
.gitignore vendored
View File

@ -4,5 +4,6 @@ retailcrm/views/css/less/*.map
retailcrm/views/css/*.css retailcrm/views/css/*.css
retailcrm/views/css/*.map retailcrm/views/css/*.map
!retailcrm/views/css/*.min.css !retailcrm/views/css/*.min.css
retailcrm/config_*.xml retailcrm/config*.xml
retailcrm/custom
coverage.xml coverage.xml

View File

@ -26,7 +26,31 @@ Module allows integrate CMS Prestashop with [RetailCRM](https://www.retailcrm.pr
#### Customization #### Customization
If you want to change the default behavior of a module classes and be sure that these changes won't be overwritten during the module upgrade process, you should **copy the original classes** that you are going to customize to the `prestashop-root/modules/retailcrm_custom/classes` directory. ##### Filters
If you want to modify data, sent between CRM and CMS you can use custom filters.
There are list of available filters:
* *RetailcrmFilterProcessOrder* - order array, which will be sent to CRM
* *RetailcrmFilterProcessCustomer* - customer array, which will be sent to CRM
* *RetailcrmFilterProcessCustomerCorporate* - corporate customer array, which will be sent to CRM
* *RetailcrmFilterProcessAddress* - address array, which will be sent to CRM
* *RetailcrmFilterProcessOffer* - offer array, which will be sent to CRM (saved into Icml file)
* *RetailcrmFilterCustomersHistory* - array with assembled history for customer, loaded from CRM
* *RetailcrmFilterOrdersHistory* - array with assembled history for order, loaded from CRM
* *RetailcrmFilterSaveCustomer* - built customer object, which will be saved to CMS
* *RetailcrmFilterSaveCustomerAddress* - built customer address object, which will be saved to CMS
* *RetailcrmFilterSaveCorporateCustomer* - built corporate customer object, which will be saved to CMS
* *RetailcrmFilterSaveCorporateCustomerAddress* - built corporate customer address object, which will be saved to CMS
To use filters you should define a new class in `<prestashop-root>/modules/retailcrm/custom/hooks`. Filename and classname must match the filter name.
Filter class should implement interface *RetailcrmFilterInterface*. In filter class you must define *filter()* function, which will take initial `$object` and return customized `$object`.
##### Classes
If you want to change the default behavior of a module classes and be sure that these changes won't be overwritten during the module upgrade process, you should **copy the original classes** that you are going to customize to the `<prestashop-root>/modules/retailcrm/custom/classes` directory.
From here you can modify the methods of the classes for your own purposes, and they will not be affected during the module upgrade process. From here you can modify the methods of the classes for your own purposes, and they will not be affected during the module upgrade process.

View File

@ -87,6 +87,8 @@ class RetailcrmAutoloader
&& !class_exists($className) && !class_exists($className)
) { ) {
include_once $file->getPathname(); include_once $file->getPathname();
return;
} }
} }
} }
@ -101,6 +103,8 @@ class RetailcrmAutoloader
&& !class_exists($className) && !class_exists($className)
) { ) {
include_once $file->getPathname(); include_once $file->getPathname();
return;
} }
} }
} }
@ -139,6 +143,6 @@ class RetailcrmAutoloader
} }
RetailcrmAutoloader::setPath(realpath(dirname(__FILE__))); RetailcrmAutoloader::setPath(realpath(dirname(__FILE__)));
RetailcrmAutoloader::setPathCustom(realpath(_PS_MODULE_DIR_ . '/retailcrm_custom/classes')); RetailcrmAutoloader::setPathCustom(realpath(_PS_MODULE_DIR_ . '/retailcrm/custom'));
RetailcrmAutoloader::setFileExt('.php'); RetailcrmAutoloader::setFileExt('.php');
spl_autoload_register('RetailcrmAutoloader::loader'); spl_autoload_register('RetailcrmAutoloader::loader');

View File

@ -185,6 +185,14 @@ class RetailcrmAddressBuilder extends RetailcrmAbstractDataBuilder
} }
} }
$this->data = RetailcrmTools::filter(
'RetailcrmFilterProcessAddress',
$this->data,
array(
'address' => $this->address,
'mode' => $this->mode
));
return $this; return $this;
} }

View File

@ -287,7 +287,14 @@ class RetailcrmCatalog
} }
} }
yield $item; yield RetailcrmTools::filter(
'RetailcrmFilterProcessOffer',
$item,
array(
'product' => $product,
'offer' => $offer
)
);
} }
} else { } else {
@ -304,7 +311,7 @@ class RetailcrmCatalog
$quantity = (int)StockAvailable::getQuantityAvailableByProduct($product['id_product']); $quantity = (int)StockAvailable::getQuantityAvailableByProduct($product['id_product']);
} }
yield array( $item = array(
'id' => $product['id_product'], 'id' => $product['id_product'],
'productId' => $product['id_product'], 'productId' => $product['id_product'],
'productActivity' => ($available_for_order) ? 'Y' : 'N', 'productActivity' => ($available_for_order) ? 'Y' : 'N',
@ -321,6 +328,14 @@ class RetailcrmCatalog
'weight' => $weight, 'weight' => $weight,
'dimensions' => $dimensions 'dimensions' => $dimensions
); );
yield RetailcrmTools::filter(
'RetailcrmFilterProcessOffer',
$item,
array(
'product' => $product
)
);
} }
} }

View File

@ -201,6 +201,20 @@ class RetailcrmCorporateCustomerBuilder extends RetailcrmAbstractBuilder impleme
} }
} }
$this->corporateCustomer = RetailcrmTools::filter(
'RetailcrmFilterSaveCorporateCustomer',
$this->corporateCustomer,
array(
'dataCrm' => $this->dataCrm,
));
$this->corporateAddress = RetailcrmTools::filter(
'RetailcrmFilterSaveCorporateCustomerAddress',
$this->corporateAddress,
array(
'dataCrm' => $this->dataCrm,
));
return $this; return $this;
} }
} }

View File

@ -190,6 +190,13 @@ class RetailcrmCustomerAddressBuilder extends RetailcrmAbstractBuilder implement
$this->customerAddress->postcode = isset($this->dataCrm['index']) ? $this->dataCrm['index'] : ''; $this->customerAddress->postcode = isset($this->dataCrm['index']) ? $this->dataCrm['index'] : '';
$this->customerAddress->phone = !empty($this->phone) ? $this->phone : ''; $this->customerAddress->phone = !empty($this->phone) ? $this->phone : '';
$this->customerAddress = RetailcrmTools::filter(
'RetailcrmFilterSaveCustomerAddress',
$this->customerAddress,
array(
'dataCrm' => $this->dataCrm
));
return $this; return $this;
} }
} }

View File

@ -155,6 +155,13 @@ class RetailcrmCustomerBuilder extends RetailcrmAbstractBuilder implements Retai
$this->customer->passwd = Tools::substr(str_shuffle(Tools::strtolower(sha1(rand() . time()))), 0, 5); $this->customer->passwd = Tools::substr(str_shuffle(Tools::strtolower(sha1(rand() . time()))), 0, 5);
} }
$this->customer = RetailcrmTools::filter(
'RetailcrmFilterSaveCustomer',
$this->customer,
array(
'dataCrm' => $this->dataCrm,
));
return $this; return $this;
} }
} }

View File

@ -0,0 +1,47 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
interface RetailcrmFilterInterface
{
/**
* @param object|array|string $object
* @param array $parameters
* @return object|array|string
*/
public static function filter($object, array $parameters);
}

View File

@ -79,6 +79,11 @@ class RetailcrmHistory
RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $customersHistory)); RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $customersHistory));
foreach ($customersHistory as $customerHistory) { foreach ($customersHistory as $customerHistory) {
$customerHistory = RetailcrmTools::filter(
'RetailcrmFilterCustomersHistory',
$customerHistory
);
if (isset($customerHistory['deleted']) && $customerHistory['deleted']) { if (isset($customerHistory['deleted']) && $customerHistory['deleted']) {
continue; continue;
} }
@ -217,6 +222,11 @@ class RetailcrmHistory
RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $orders)); RetailcrmLogger::writeDebugArray(__METHOD__, array('Assembled history:', $orders));
foreach ($orders as $order_history) { foreach ($orders as $order_history) {
$order_history = RetailcrmTools::filter(
'RetailcrmFilterOrdersHistory',
$order_history
);
if (isset($order_history['deleted']) && $order_history['deleted'] == true) { if (isset($order_history['deleted']) && $order_history['deleted'] == true) {
continue; continue;
} }

View File

@ -1070,7 +1070,14 @@ class RetailcrmOrderBuilder
} }
} }
return RetailcrmTools::clearArray($crmOrder); return RetailcrmTools::filter(
'RetailcrmFilterProcessOrder',
RetailcrmTools::clearArray($crmOrder),
array(
'order' => $order,
'customer' => $customer,
'cart' => $cart
));
} }
/** /**
@ -1142,7 +1149,7 @@ class RetailcrmOrderBuilder
*/ */
public static function buildCrmCustomer(Customer $object, $address = array()) public static function buildCrmCustomer(Customer $object, $address = array())
{ {
return array_filter(array_merge( $customer = array_filter(array_merge(
array( array(
'externalId' => !empty($object->id) ? $object->id : null, 'externalId' => !empty($object->id) ? $object->id : null,
'firstName' => $object->firstname, 'firstName' => $object->firstname,
@ -1159,6 +1166,14 @@ class RetailcrmOrderBuilder
), function ($value) { ), function ($value) {
return !($value === '' || $value === null || (is_array($value) ? count($value) == 0 : false)); return !($value === '' || $value === null || (is_array($value) ? count($value) == 0 : false));
}); });
return RetailcrmTools::filter(
'RetailcrmFilterProcessCustomer',
$customer,
array(
'customer' => $object,
'address' => $address
));
} }
public static function buildCrmCustomerCorporate( public static function buildCrmCustomerCorporate(
@ -1240,7 +1255,12 @@ class RetailcrmOrderBuilder
$customer['addresses'] = $customerAddresses; $customer['addresses'] = $customerAddresses;
} }
return RetailcrmTools::clearArray($customer); return RetailcrmTools::filter(
'RetailcrmFilterProcessCustomerCorporate',
RetailcrmTools::clearArray($customer),
array(
'customer' => $object
));
} }
/** /**

View File

@ -692,4 +692,32 @@ class RetailcrmTools
Shop::setContext(Shop::CONTEXT_SHOP, $id_shop); Shop::setContext(Shop::CONTEXT_SHOP, $id_shop);
Context::getContext()->shop = new Shop($id_shop); Context::getContext()->shop = new Shop($id_shop);
} }
/**
* Call custom filters for the object
*
* @param string $filter
* @param object|array|string $object
* @param array $parameters
*
* @return false|mixed
*/
public static function filter($filter, $object, $parameters = array())
{
if (class_exists($filter) && method_exists($filter, 'filter')) {
try {
$result = call_user_func_array(
array($filter, 'filter'),
array($object, $parameters)
);
return (null === $result || false === $result) ? $object : $result;
} catch (Exception $e) {
RetailcrmLogger::writeCaller(__METHOD__, 'Error in custom filter: ' . $e->getMessage());
RetailcrmLogger::writeDebug(__METHOD__, $e->getTraceAsString());
}
}
return $object;
}
} }

View File

@ -0,0 +1,104 @@
<?php
/**
* MIT License
*
* Copyright (c) 2020 DIGITAL RETAIL TECHNOLOGIES SL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author DIGITAL RETAIL TECHNOLOGIES SL <mail@simlachat.com>
* @copyright 2020 DIGITAL RETAIL TECHNOLOGIES SL
* @license https://opensource.org/licenses/MIT The MIT License
*
* Don't forget to prefix your containers with your own identifier
* to avoid any conflicts with others containers.
*/
if (!defined('_PS_VERSION_')) {
exit;
}
/**
* Upgrade module to version 3.2.7
*
* @param \RetailCRM $module
*
* @return bool
*/
function upgrade_module_3_2_7($module)
{
if ('retailcrm' != $module->name) {
return false;
}
$oldCustomFolder = _PS_MODULE_DIR_ . '/retailcrm_custom/classes';
$newCustomFolder = _PS_MODULE_DIR_ . '/retailcrm/custom/classes';
if (file_exists($oldCustomFolder)) {
if (!file_exists($newCustomFolder)) {
mkdir($newCustomFolder, 0777, true);
}
retailcrm_upgrade_recursive_copy($oldCustomFolder, $newCustomFolder);
}
return true;
}
function retailcrm_upgrade_recursive_copy($src, $dst, $childFolder = '')
{
$dir = opendir($src);
if(!file_exists($dst)) {
mkdir($dst);
}
if ($childFolder != '') {
if(!file_exists($dst . '/' . $childFolder))
mkdir($dst . '/' . $childFolder);
while (false !== ($file = readdir($dir))) {
if (($file != '.') && ($file != '..')) {
if (is_dir($src . '/' . $file)) {
retailcrm_upgrade_recursive_copy($src . '/' . $file, $dst . '/' . $childFolder . '/' . $file);
} else {
copy($src . '/' . $file, $dst . '/' . $childFolder . '/' . $file);
}
}
}
} else {
while (false !== ($file = readdir($dir))) {
if (($file != '.') && ($file != '..')) {
if (is_dir($src . '/' . $file)) {
retailcrm_upgrade_recursive_copy($src . '/' . $file, $dst . '/' . $file);
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
}
}
closedir($dir);
}