commit changes made during the last 2 months
This commit is contained in:
parent
58c8eb20c1
commit
2a5c988bce
@ -266,6 +266,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{*
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
@ -302,6 +303,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
*}
|
||||||
{if $products AND count($products)}
|
{if $products AND count($products)}
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
4346
cache/__class_index.php
vendored
Normal file
4346
cache/__class_index.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1251,6 +1251,7 @@ class CartCore extends ObjectModel
|
|||||||
*/
|
*/
|
||||||
public function deleteProduct($id_product, $id_product_attribute = null, $id_customization = null, $id_address_delivery = 0)
|
public function deleteProduct($id_product, $id_product_attribute = null, $id_customization = null, $id_address_delivery = 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isset(self::$_nbProducts[$this->id])) {
|
if (isset(self::$_nbProducts[$this->id])) {
|
||||||
unset(self::$_nbProducts[$this->id]);
|
unset(self::$_nbProducts[$this->id]);
|
||||||
}
|
}
|
||||||
@ -1359,7 +1360,7 @@ class CartCore extends ObjectModel
|
|||||||
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$result &= Db::getInstance()->execute(
|
$result &= Db::getInstance()->execute(
|
||||||
'UPDATE `'._DB_PREFIX_.'cart_product`
|
'²TE `'._DB_PREFIX_.'cart_product`
|
||||||
SET `quantity` = `quantity` - '.(int)$customization['quantity'].'
|
SET `quantity` = `quantity` - '.(int)$customization['quantity'].'
|
||||||
WHERE `id_cart` = '.(int)$this->id.'
|
WHERE `id_cart` = '.(int)$this->id.'
|
||||||
AND `id_product` = '.(int)$id_product.
|
AND `id_product` = '.(int)$id_product.
|
||||||
|
@ -148,6 +148,7 @@ class GroupReductionCore extends ObjectModel
|
|||||||
FROM `'._DB_PREFIX_.'product_group_reduction_cache`
|
FROM `'._DB_PREFIX_.'product_group_reduction_cache`
|
||||||
WHERE `id_product` = '.(int)$id_product.' AND `id_group` = '.(int)$id_group);
|
WHERE `id_product` = '.(int)$id_product.' AND `id_group` = '.(int)$id_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should return string (decimal in database) and not a float
|
// Should return string (decimal in database) and not a float
|
||||||
return self::$reduction_cache[$id_product.'-'.$id_group];
|
return self::$reduction_cache[$id_product.'-'.$id_group];
|
||||||
}
|
}
|
||||||
|
@ -337,12 +337,13 @@ class SpecificPriceCore extends ObjectModel
|
|||||||
if (!SpecificPrice::isFeatureActive()) {
|
if (!SpecificPrice::isFeatureActive()) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
/*
|
//
|
||||||
** The date is not taken into account for the cache, but this is for the better because it keeps the consistency for the whole script.
|
// The date is not taken into account for the cache, but this is for the better because it keeps the consistency for the whole script.
|
||||||
** The price must not change between the top and the bottom of the page
|
// The price must not change between the top and the bottom of the page
|
||||||
*/
|
//
|
||||||
|
|
||||||
$key = ((int)$id_product.'-'.(int)$id_shop.'-'.(int)$id_currency.'-'.(int)$id_country.'-'.(int)$id_group.'-'.(int)$quantity.'-'.(int)$id_product_attribute.'-'.(int)$id_cart.'-'.(int)$id_customer.'-'.(int)$real_quantity);
|
$key = ((int)$id_product.'-'.(int)$id_shop.'-'.(int)$id_currency.'-'.(int)$id_country.'-'.(int)$id_group.'-'.(int)$quantity.'-'.(int)$id_product_attribute.'-'.(int)$id_cart.'-'.(int)$id_customer.'-'.(int)$real_quantity);
|
||||||
|
|
||||||
if (!array_key_exists($key, SpecificPrice::$_specificPriceCache)) {
|
if (!array_key_exists($key, SpecificPrice::$_specificPriceCache)) {
|
||||||
$query_extra = self::computeExtraConditions($id_product, $id_product_attribute, $id_customer, $id_cart);
|
$query_extra = self::computeExtraConditions($id_product, $id_product_attribute, $id_customer, $id_cart);
|
||||||
$query = '
|
$query = '
|
||||||
@ -360,6 +361,7 @@ class SpecificPriceCore extends ObjectModel
|
|||||||
|
|
||||||
SpecificPrice::$_specificPriceCache[$key] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query);
|
SpecificPrice::$_specificPriceCache[$key] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SpecificPrice::$_specificPriceCache[$key];
|
return SpecificPrice::$_specificPriceCache[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,6 +418,7 @@ abstract class DbCore
|
|||||||
if (!$this->result && $this->getNumberError() == 2006) {
|
if (!$this->result && $this->getNumberError() == 2006) {
|
||||||
if ($this->connect()) {
|
if ($this->connect()) {
|
||||||
$this->result = $this->_query($sql);
|
$this->result = $this->_query($sql);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,11 @@ if (is_file($currentDir.'/defines_custom.inc.php')) {
|
|||||||
}
|
}
|
||||||
require_once($currentDir.'/defines.inc.php');
|
require_once($currentDir.'/defines.inc.php');
|
||||||
|
|
||||||
|
if (file_exists(_PS_TOOL_DIR_.'/antadis_tools/include.php')) {
|
||||||
|
require_once(_PS_TOOL_DIR_.'/antadis_tools/include.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$start_time = microtime(true);
|
$start_time = microtime(true);
|
||||||
|
|
||||||
/* SSL configuration */
|
/* SSL configuration */
|
||||||
|
@ -26,7 +26,12 @@
|
|||||||
|
|
||||||
/* Debug only */
|
/* Debug only */
|
||||||
if (!defined('_PS_MODE_DEV_')) {
|
if (!defined('_PS_MODE_DEV_')) {
|
||||||
define('_PS_MODE_DEV_', true);
|
if (in_array($_SERVER['REMOTE_ADDR'], array('88.163.22.99'))) {
|
||||||
|
define('_PS_MODE_DEV_', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
define('_PS_MODE_DEV_', false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compatibility warning */
|
/* Compatibility warning */
|
||||||
@ -40,7 +45,14 @@ if (_PS_MODE_DEV_ === true) {
|
|||||||
define('_PS_DEBUG_SQL_', false);
|
define('_PS_DEBUG_SQL_', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
define('_PS_DEBUG_PROFILING_', false);
|
|
||||||
|
if (in_array($_SERVER['REMOTE_ADDR'], array('88.163.22.99')) && isset($_GET['profiling'])) {
|
||||||
|
define('_PS_DEBUG_PROFILING_', true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
define('_PS_DEBUG_PROFILING_', false);
|
||||||
|
}
|
||||||
|
|
||||||
define('_PS_MODE_DEMO_', false);
|
define('_PS_MODE_DEMO_', false);
|
||||||
|
|
||||||
$currentDir = dirname(__FILE__);
|
$currentDir = dirname(__FILE__);
|
||||||
|
@ -1521,6 +1521,7 @@ class AdminOrdersControllerCore extends AdminController
|
|||||||
$this->errors[] = Tools::displayError('You do not have permission to edit this.');
|
$this->errors[] = Tools::displayError('You do not have permission to edit this.');
|
||||||
}
|
}
|
||||||
} elseif (Tools::getValue('syncherp') == 1) {
|
} elseif (Tools::getValue('syncherp') == 1) {
|
||||||
|
|
||||||
$id_order = Tools::getValue('id_order', false);
|
$id_order = Tools::getValue('id_order', false);
|
||||||
if ($id_order) {
|
if ($id_order) {
|
||||||
$order = new Order((int)$id_order);
|
$order = new Order((int)$id_order);
|
||||||
@ -1546,6 +1547,12 @@ class AdminOrdersControllerCore extends AdminController
|
|||||||
if ($erporder) {
|
if ($erporder) {
|
||||||
return $erporder->hookActionOrderStatusPostUpdate($params);
|
return $erporder->hookActionOrderStatusPostUpdate($params);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$sql = 'SELECT `name` FROM `'._DB_PREFIX_.'order_state_lang` WHERE `id_order_state` IN (1,2,10) AND id_lang = 1';
|
||||||
|
$rows = Db::getInstance()->executeS($sql);
|
||||||
|
|
||||||
|
$txt .= implode('", "', array_column($rows, 'name'));
|
||||||
|
$this->errors[] = Tools::displayError('Pas de synchro possible, la commande doit avoir eu l\'un des status suivants : "'.$txt.'"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +173,7 @@ foreach ($ids_product as $key => $id) {
|
|||||||
$sql = 'INSERT INTO '._DB_PREFIX_.'image_lang (id_image, id_lang, legend) VALUES('.(int)$img_id.', 1, "'.$record['name'].'")';
|
$sql = 'INSERT INTO '._DB_PREFIX_.'image_lang (id_image, id_lang, legend) VALUES('.(int)$img_id.', 1, "'.$record['name'].'")';
|
||||||
$d->execute($sql);
|
$d->execute($sql);
|
||||||
|
|
||||||
|
if (!empty($record['image'])) {
|
||||||
$tmp_path = _PS_TMP_IMG_DIR_.'odoo_tmp_image.jpg';
|
$tmp_path = _PS_TMP_IMG_DIR_.'odoo_tmp_image.jpg';
|
||||||
$data = base64_decode($record['image']);
|
$data = base64_decode($record['image']);
|
||||||
file_put_contents($tmp_path, $data);
|
file_put_contents($tmp_path, $data);
|
||||||
@ -184,6 +185,7 @@ foreach ($ids_product as $key => $id) {
|
|||||||
ImageManager::resize($tmp_path, $new_path.'-'.stripslashes($imageType['name']).'.'.$image->image_format, $imageType['width'], $imageType['height'], $image->image_format);
|
ImageManager::resize($tmp_path, $new_path.'-'.stripslashes($imageType['name']).'.'.$image->image_format, $imageType['width'], $imageType['height'], $image->image_format);
|
||||||
}
|
}
|
||||||
array_map('unlink', glob(_PS_TMP_IMG_DIR_.'*'));
|
array_map('unlink', glob(_PS_TMP_IMG_DIR_.'*'));
|
||||||
|
}
|
||||||
|
|
||||||
// set variant
|
// set variant
|
||||||
foreach ($variants as $key => $variant) {
|
foreach ($variants as $key => $variant) {
|
||||||
|
@ -95,9 +95,60 @@ foreach ($ids_product as $key => $id) {
|
|||||||
|
|
||||||
$d->execute($sql);
|
$d->execute($sql);
|
||||||
|
|
||||||
|
|
||||||
$sql = 'SELECT `id_product` FROM `'._DB_PREFIX_.'product` WHERE `id_erp` = '.pSQL($id);
|
$sql = 'SELECT `id_product` FROM `'._DB_PREFIX_.'product` WHERE `id_erp` = '.pSQL($id);
|
||||||
$product_id = $d->getRow($sql)['id_product'];
|
$product_id = $d->getRow($sql)['id_product'];
|
||||||
|
|
||||||
|
$sql = 'SELECT `id_image` FROM '._DB_PREFIX_.'image WHERE `id_product` = '.(int)$product_id;
|
||||||
|
$id_image = $d->getValue($sql);
|
||||||
|
|
||||||
|
if ($id_image) {
|
||||||
|
$image = new Image($id_image);
|
||||||
|
$imagesTypes = ImageType::getImagesTypes('products');
|
||||||
|
$existing_path = $image->getExistingImgPath();
|
||||||
|
|
||||||
|
$image_exists = true;
|
||||||
|
foreach ($imagesTypes as $imageType) {
|
||||||
|
$image_exists = file_exists($existing_path.'-'.stripslashes($imageType['name']).'.'.$image->image_format);
|
||||||
|
if (!$image_exists) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$image_exists) {
|
||||||
|
$sql = 'DELETE FROM '._DB_PREFIX_.'image WHERE id_image = '.(int)$id_image;
|
||||||
|
$d->execute($sql);
|
||||||
|
$sql = 'DELETE FROM '._DB_PREFIX_.'image_shop WHERE id_image = '.(int)$id_image;
|
||||||
|
$d->execute($sql);
|
||||||
|
$sql = 'DELETE FROM '._DB_PREFIX_.'image_lang WHERE id_image = '.(int)$id_image;
|
||||||
|
$d->execute($sql);
|
||||||
|
$id_image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$id_image) {
|
||||||
|
// set image
|
||||||
|
$sql = 'INSERT INTO '._DB_PREFIX_.'image (id_product, position, cover) VALUES('.(int)$product_id.', 0, 1)';
|
||||||
|
$d->execute($sql);
|
||||||
|
$img_id = $d->Insert_ID();
|
||||||
|
$sql = 'INSERT INTO '._DB_PREFIX_.'image_shop (id_product, id_image, id_shop, cover) VALUES('.(int)$product_id.', '.$img_id.',1, 1)';
|
||||||
|
$d->execute($sql);
|
||||||
|
$sql = 'INSERT INTO '._DB_PREFIX_.'image_lang (id_image, id_lang, legend) VALUES('.(int)$img_id.', 1, "'.$record['name'].'")';
|
||||||
|
$d->execute($sql);
|
||||||
|
|
||||||
|
$tmp_path = _PS_TMP_IMG_DIR_.'odoo_tmp_image_update.jpg';
|
||||||
|
$data = base64_decode($record['image']);
|
||||||
|
file_put_contents($tmp_path, $data);
|
||||||
|
$image = new Image($img_id);
|
||||||
|
$new_path = $image->getPathForCreation();
|
||||||
|
ImageManager::resize($tmp_path, $image->getPathForCreation().'.'.$image->image_format);
|
||||||
|
$imagesTypes = ImageType::getImagesTypes('products');
|
||||||
|
foreach ($imagesTypes as $imageType) {
|
||||||
|
ImageManager::resize($tmp_path, $new_path.'-'.stripslashes($imageType['name']).'.'.$image->image_format, $imageType['width'], $imageType['height'], $image->image_format);
|
||||||
|
}
|
||||||
|
array_map('unlink', glob(_PS_TMP_IMG_DIR_.'*'));
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($variants as $key => $variant) {
|
foreach ($variants as $key => $variant) {
|
||||||
$id_variant = $variant['id'];
|
$id_variant = $variant['id'];
|
||||||
|
|
||||||
|
8
modules/customerautogroups/changelog.txt
Normal file
8
modules/customerautogroups/changelog.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
V 0.1.1 - 2015-11-13 : Compatiblité Prestashop 1.5 // Prestashop 1.5 compatibility
|
||||||
|
V 0.1.2 - 2015-11-14 : Correctif affichage conditions de type addresse déjà enregistrées // Display fix for existing rules with address condition
|
||||||
|
V 0.2.0 - 2015-12-07 : Ajout de la possibilité de definir le groupe par défaut, et de supprimer tous les autres groupes ( pour les règles stop processing)
|
||||||
|
New fonctionnalities allows you to define customer default group, and to delete others groups ( for stop processing rules )
|
||||||
|
V 0.2.1 - 2015-12-18 : Correction dans l'application des règles + maj readme // Rules apply correction
|
||||||
|
V 0.3.0 - 2016-01-11 : Nouvelles conditions de filtres (Like) // New filters condition ( Like)
|
||||||
|
V 0.3.1 - 2016-06-17 : Autorisation de paramètres exclus // allow excluded parameters
|
||||||
|
V 0.3.2 - 2016-06-18 : Correction conditions < && <=
|
73
modules/customerautogroups/classes/AutoGroupRule.php
Normal file
73
modules/customerautogroups/classes/AutoGroupRule.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2007-2014 PrestaShop
|
||||||
|
*
|
||||||
|
* NOTICE OF LICENSE
|
||||||
|
*
|
||||||
|
* This source file is subject to the Academic Free License (AFL 3.0)
|
||||||
|
* that is bundled with this package in the file LICENSE.txt.
|
||||||
|
* It is also available through the world-wide-web at this URL:
|
||||||
|
* http://opensource.org/licenses/afl-3.0.php
|
||||||
|
* If you did not receive a copy of the license and are unable to
|
||||||
|
* obtain it through the world-wide-web, please send an email
|
||||||
|
* to license@prestashop.com so we can send you a copy immediately.
|
||||||
|
*
|
||||||
|
* 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 Hennes Hervé <contact@h-hennes.fr>
|
||||||
|
* @copyright 2013-2015 Hennes Hervé
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* http://www.h-hennes.fr/blog/
|
||||||
|
*/
|
||||||
|
class AutoGroupRule extends ObjectModel
|
||||||
|
{
|
||||||
|
/** Différents types de règles */
|
||||||
|
const RULE_TYPE_CUSTOMER = 1;
|
||||||
|
const RULE_TYPE_ADDRESS = 2;
|
||||||
|
|
||||||
|
public $id;
|
||||||
|
public $name;
|
||||||
|
public $description;
|
||||||
|
public $condition_type;
|
||||||
|
public $condition_field;
|
||||||
|
public $condition_operator;
|
||||||
|
public $condition_value;
|
||||||
|
public $id_group;
|
||||||
|
public $active;
|
||||||
|
public $priority;
|
||||||
|
public $stop_processing;
|
||||||
|
public $default_group;
|
||||||
|
public $clean_groups;
|
||||||
|
public $date_add;
|
||||||
|
public $date_upd;
|
||||||
|
|
||||||
|
public static $definition = array(
|
||||||
|
'table' => 'autogroup_rule',
|
||||||
|
'primary' => 'id_rule',
|
||||||
|
'multilang' => true,
|
||||||
|
'fields' => array(
|
||||||
|
'condition_type' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
|
||||||
|
'condition_field' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml',),
|
||||||
|
'condition_operator' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml',),
|
||||||
|
'condition_value' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 254),
|
||||||
|
'id_group' => array('type' => self::TYPE_INT),
|
||||||
|
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
||||||
|
'priority' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
|
||||||
|
'stop_processing' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
||||||
|
'default_group' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
||||||
|
'clean_groups' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
|
||||||
|
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
|
||||||
|
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
|
||||||
|
// Lang fields
|
||||||
|
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 254),
|
||||||
|
'description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCleanHtml'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
365
modules/customerautogroups/controllers/admin/rules.php
Normal file
365
modules/customerautogroups/controllers/admin/rules.php
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* 2007-2014 PrestaShop
|
||||||
|
*
|
||||||
|
* NOTICE OF LICENSE
|
||||||
|
*
|
||||||
|
* This source file is subject to the Academic Free License (AFL 3.0)
|
||||||
|
* that is bundled with this package in the file LICENSE.txt.
|
||||||
|
* It is also available through the world-wide-web at this URL:
|
||||||
|
* http://opensource.org/licenses/afl-3.0.php
|
||||||
|
* If you did not receive a copy of the license and are unable to
|
||||||
|
* obtain it through the world-wide-web, please send an email
|
||||||
|
* to license@prestashop.com so we can send you a copy immediately.
|
||||||
|
*
|
||||||
|
* 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 Hennes Hervé <contact@h-hennes.fr>
|
||||||
|
* @copyright 2013-2015 Hennes Hervé
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* http://www.h-hennes.fr/blog/
|
||||||
|
*/
|
||||||
|
include_once dirname(__FILE__).'/../../classes/AutoGroupRule.php';
|
||||||
|
|
||||||
|
class RulesController extends ModuleAdminController
|
||||||
|
{
|
||||||
|
//Champs clients exclus de la condition
|
||||||
|
protected $_customerExcludedFields = array('id', 'secure_key', 'ip_registration_newsletter', 'id_default_group', 'last_passwd_gen', 'last_passwd_gen',
|
||||||
|
'passwd', 'definition');
|
||||||
|
|
||||||
|
//Champs clients
|
||||||
|
protected $customerFields;
|
||||||
|
|
||||||
|
//Champs addresse exclus de la condition
|
||||||
|
protected $_addressExcludedFields = array('force_id', 'id_customer', 'id_manufacturer', 'id_warehouse', 'id_supplier', 'deleted', 'definition');
|
||||||
|
|
||||||
|
//Champs adresse
|
||||||
|
protected $addressFields = array();
|
||||||
|
|
||||||
|
//Données du champ condition_field
|
||||||
|
protected $_conditionFieldDatas;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->bootstrap = true;
|
||||||
|
$this->table = 'autogroup_rule';
|
||||||
|
$this->identifier = 'id_rule';
|
||||||
|
$this->className = 'AutoGroupRule';
|
||||||
|
$this->lang = true;
|
||||||
|
$this->addRowAction('edit');
|
||||||
|
$this->addRowAction('delete');
|
||||||
|
$this->_orderWay = 'ASC';
|
||||||
|
|
||||||
|
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'icon' => 'icon-trash', 'confirm' => $this->l('Delete selected items?')));
|
||||||
|
|
||||||
|
$this->rules_types = array(1 => $this->l('Customer'), 2 => $this->l('Customer Address'));
|
||||||
|
|
||||||
|
$this->fields_list = array(
|
||||||
|
'id_rule' => array('title' => $this->l('ID'), 'align' => 'center', 'class' => 'fixed-width-xs'),
|
||||||
|
'name' => array('title' => $this->l('Name')),
|
||||||
|
'condition_type' => array(
|
||||||
|
'title' => $this->l('Condition Type'),
|
||||||
|
'align' => 'center',
|
||||||
|
'class' => 'fixed-width-xs',
|
||||||
|
'type' => 'select',
|
||||||
|
'list' => $this->rules_types,
|
||||||
|
'filter_key' => 'condition_type',
|
||||||
|
'filter_type' => 'int',
|
||||||
|
),
|
||||||
|
'id_group' => array('title' => $this->l('Id group'), 'class' => 'fixed-width-sm', 'align' => 'center',),
|
||||||
|
'priority' => array('title' => $this->l('Priority'), 'align' => 'center', 'class' => 'fixed-width-sm'),
|
||||||
|
'stop_processing' => array('title' => $this->l('Stop processing'), 'active' => 'stop_processing', 'type' => 'bool', 'align' => 'center'),
|
||||||
|
'default_group' => array('title' => $this->l('Default customer Group'), 'active' => 'default_group', 'type' => 'bool', 'align' => 'center'),
|
||||||
|
'clean_groups' => array('title' => $this->l('Delete all others groups'), 'active' => 'clean_groups', 'type' => 'bool', 'align' => 'center'),
|
||||||
|
'active' => array('title' => $this->l('Status'), 'active' => 'status', 'type' => 'bool', 'align' => 'center'),
|
||||||
|
);
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Définition des médias du controller
|
||||||
|
*/
|
||||||
|
public function setMedia()
|
||||||
|
{
|
||||||
|
parent::setMedia();
|
||||||
|
$this->addJS(_MODULE_DIR_.'customerautogroups/views/admin/js/customerautogroups.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affichage de la liste
|
||||||
|
*/
|
||||||
|
public function renderList()
|
||||||
|
{
|
||||||
|
$this->tpl_list_vars['condition_type'] = $this->rules_types;
|
||||||
|
return parent::renderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialisation des variables du formulaires
|
||||||
|
*/
|
||||||
|
protected function _initForm()
|
||||||
|
{
|
||||||
|
//Liste des cas de conditions
|
||||||
|
$this->conditionsType = array(
|
||||||
|
array('id' => AutoGroupRule::RULE_TYPE_CUSTOMER, 'value' => 'Customer'),
|
||||||
|
array('id' => AutoGroupRule::RULE_TYPE_ADDRESS, 'value' => 'Address'),
|
||||||
|
);
|
||||||
|
|
||||||
|
//Liste des champs disponibles pour la classe Customer
|
||||||
|
$fields = get_class_vars('Customer');
|
||||||
|
$this->customerFields = array();
|
||||||
|
foreach ($fields as $key => $value) {
|
||||||
|
if (!in_array($key, $this->_customerExcludedFields)) {
|
||||||
|
$this->customerFields[] = array('id' => $key, 'value' => $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Liste des champs disponibles pour la classe Customer
|
||||||
|
$afields = get_class_vars('Address');
|
||||||
|
foreach ($afields as $key => $value) {
|
||||||
|
if (!in_array($key, $this->_addressExcludedFields)) {
|
||||||
|
$this->addressFields[] = array('id' => $key, 'value' => $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gestion de l'affichage du champ "condition_field" pour les règles déjà existantes
|
||||||
|
if ( Tools::getValue('id_rule')) {
|
||||||
|
$rule = new AutoGroupRule(Tools::getValue('id_rule'));
|
||||||
|
if ( $rule->condition_type == AutoGroupRule::RULE_TYPE_CUSTOMER )
|
||||||
|
$this->_conditionFieldDatas = $this->customerFields;
|
||||||
|
else
|
||||||
|
$this->_conditionFieldDatas = $this->addressFields;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->_conditionFieldDatas = $this->customerFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affichage du formulaire d'édition
|
||||||
|
*/
|
||||||
|
public function renderForm()
|
||||||
|
{
|
||||||
|
$this->_initForm();
|
||||||
|
|
||||||
|
//Liste des priorités
|
||||||
|
$priorities = array();
|
||||||
|
for ($i = 0; $i <= 10; $i++)
|
||||||
|
$priorities[] = array('id' => $i, 'value' => $i);
|
||||||
|
|
||||||
|
//Liste des groupes clients
|
||||||
|
$customerGroups = Group::getGroups($this->context->language->id);
|
||||||
|
|
||||||
|
//Liste des opérateurs
|
||||||
|
$operatorsList = array(
|
||||||
|
array('id' => 'eq', 'value' => '='),
|
||||||
|
array('id' => 'ne', 'value' => '!='),
|
||||||
|
array('id' => 'gt', 'value' => '>'),
|
||||||
|
array('id' => 'ge', 'value' => '>='),
|
||||||
|
array('id' => 'lt', 'value' => '<'),
|
||||||
|
array('id' => 'le', 'value' => '<='),
|
||||||
|
array('id' => 'LIKE %', 'value' => 'LIKE %'),
|
||||||
|
);
|
||||||
|
|
||||||
|
//Avec Prestashop < 1.6 le type switch n'existe pas il faut le remplacer par un radio
|
||||||
|
if ( _PS_VERSION_ < '1.6') {
|
||||||
|
$switch_type = 'radio';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$switch_type = 'switch';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->fields_form = array(
|
||||||
|
'legend' => array(
|
||||||
|
'title' => $this->l('Edit Rule'),
|
||||||
|
'icon' => 'icon-cog'
|
||||||
|
),
|
||||||
|
'input' => array(
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'label' => $this->l('name'),
|
||||||
|
'name' => 'name',
|
||||||
|
'lang' => true,
|
||||||
|
'required' => true
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'textarea',
|
||||||
|
'label' => $this->l('description'),
|
||||||
|
'name' => 'description',
|
||||||
|
'lang' => true,
|
||||||
|
'required' => true
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'select',
|
||||||
|
'label' => $this->l('Condition type'),
|
||||||
|
'name' => 'condition_type',
|
||||||
|
'required' => true,
|
||||||
|
'class' => 'condition_type',
|
||||||
|
'options' => array(
|
||||||
|
'query' => $this->conditionsType,
|
||||||
|
'id' => 'id',
|
||||||
|
'name' => 'value',
|
||||||
|
),
|
||||||
|
'hint' => $this->l('The condition fields depend from the type')
|
||||||
|
),
|
||||||
|
//Le changement du select précédent entraine le changement de celui-ci
|
||||||
|
array(
|
||||||
|
'type' => 'select',
|
||||||
|
'label' => $this->l('Condition Field'),
|
||||||
|
'name' => 'condition_field',
|
||||||
|
'class' => 'condition_field',
|
||||||
|
'required' => true,
|
||||||
|
'options' => array(
|
||||||
|
'query' => $this->_conditionFieldDatas,
|
||||||
|
'id' => 'id',
|
||||||
|
'name' => 'value',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'select',
|
||||||
|
'label' => $this->l('Condition Operator'),
|
||||||
|
'name' => 'condition_operator',
|
||||||
|
'required' => true,
|
||||||
|
'options' => array(
|
||||||
|
'query' => $operatorsList,
|
||||||
|
'id' => 'id',
|
||||||
|
'name' => 'value',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'label' => $this->l('Condition Value'),
|
||||||
|
'name' => 'condition_value',
|
||||||
|
'required' => true
|
||||||
|
),
|
||||||
|
//Bug sur la récupération du groupe
|
||||||
|
array(
|
||||||
|
'type' => 'select',
|
||||||
|
'label' => $this->l('Customer Group'),
|
||||||
|
'name' => 'id_group',
|
||||||
|
'required' => true,
|
||||||
|
'options' => array(
|
||||||
|
'query' => $customerGroups,
|
||||||
|
'id' => 'id_group',
|
||||||
|
'name' => 'name',
|
||||||
|
),
|
||||||
|
'hint' => $this->l('Select the group in which the customer will be added')
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'select',
|
||||||
|
'label' => $this->l('Priority'),
|
||||||
|
'name' => 'priority',
|
||||||
|
'required' => true,
|
||||||
|
'options' => array(
|
||||||
|
'query' => $priorities,
|
||||||
|
'id' => 'id',
|
||||||
|
'name' => 'value',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => $switch_type,
|
||||||
|
'label' => $this->l('Active'),
|
||||||
|
'name' => 'active',
|
||||||
|
'class' => 't',
|
||||||
|
'required' => true,
|
||||||
|
'values' => array(
|
||||||
|
array('id' => 'on', 'value' => 1, 'label' => $this->l('Yes')),
|
||||||
|
array('id' => 'off', 'value' => 0, 'label' => $this->l('No')),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => $switch_type,
|
||||||
|
'label' => $this->l('Stop processing further rules'),
|
||||||
|
'name' => 'stop_processing',
|
||||||
|
'class' => 't',
|
||||||
|
'required' => true,
|
||||||
|
'values' => array(
|
||||||
|
array('id' => 'on', 'value' => 1, 'label' => $this->l('Yes')),
|
||||||
|
array('id' => 'off', 'value' => 0, 'label' => $this->l('No')),
|
||||||
|
),
|
||||||
|
'hint' => $this->l('If enable this rule will be the latest processed')
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => $switch_type,
|
||||||
|
'label' => $this->l('Default customer Group'),
|
||||||
|
'name' => 'default_group',
|
||||||
|
'class' => 't',
|
||||||
|
'required' => true,
|
||||||
|
'values' => array(
|
||||||
|
array('id' => 'on', 'value' => 1, 'label' => $this->l('Yes')),
|
||||||
|
array('id' => 'off', 'value' => 0, 'label' => $this->l('No')),
|
||||||
|
),
|
||||||
|
'hint' => $this->l('Only works for rule which stop processing')
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => $switch_type,
|
||||||
|
'label' => $this->l('Delete all others groups'),
|
||||||
|
'name' => 'clean_groups',
|
||||||
|
'class' => 't',
|
||||||
|
'required' => true,
|
||||||
|
'values' => array(
|
||||||
|
array('id' => 'on', 'value' => 1, 'label' => $this->l('Yes')),
|
||||||
|
array('id' => 'off', 'value' => 0, 'label' => $this->l('No')),
|
||||||
|
),
|
||||||
|
'hint' => $this->l('Only works for rule which stop processing')
|
||||||
|
),
|
||||||
|
//Token pour action ajax
|
||||||
|
array(
|
||||||
|
'type' => 'hidden',
|
||||||
|
'label' => 'token',
|
||||||
|
'name' => 'token',
|
||||||
|
'value' => $this->token,
|
||||||
|
'required'=> false,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'submit' => array(
|
||||||
|
'title' => $this->l('Save')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return parent::renderForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajout du bouton d'ajout dans la toolbar
|
||||||
|
*/
|
||||||
|
public function initPageHeaderToolbar()
|
||||||
|
{
|
||||||
|
$this->page_header_toolbar_btn['new_rule'] = array(
|
||||||
|
'href' => self::$currentIndex.'&addautogroup_rule&token='.$this->token,
|
||||||
|
'desc' => $this->l('Add new rule', null, null, false),
|
||||||
|
'icon' => 'process-icon-new'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
parent::initPageHeaderToolbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mise à jour ajax des champs des règles en fonction du type
|
||||||
|
*/
|
||||||
|
public function displayAjaxUpdateConditionTypeSelect(){
|
||||||
|
|
||||||
|
$this->_initForm();
|
||||||
|
|
||||||
|
if ( Tools::getValue('condition_type') == AutoGroupRule::RULE_TYPE_CUSTOMER ) {
|
||||||
|
$fields = $this->customerFields;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$fields = $this->addressFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $fields as $field ) {
|
||||||
|
echo '<option value="'.$field['id'].'">'.$field['value'].'</option>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
267
modules/customerautogroups/customerautogroups.php
Normal file
267
modules/customerautogroups/customerautogroups.php
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2007-2014 PrestaShop
|
||||||
|
*
|
||||||
|
* NOTICE OF LICENSE
|
||||||
|
*
|
||||||
|
* This source file is subject to the Academic Free License (AFL 3.0)
|
||||||
|
* that is bundled with this package in the file LICENSE.txt.
|
||||||
|
* It is also available through the world-wide-web at this URL:
|
||||||
|
* http://opensource.org/licenses/afl-3.0.php
|
||||||
|
* If you did not receive a copy of the license and are unable to
|
||||||
|
* obtain it through the world-wide-web, please send an email
|
||||||
|
* to license@prestashop.com so we can send you a copy immediately.
|
||||||
|
*
|
||||||
|
* 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 Hennes Hervé <contact@h-hennes.fr>
|
||||||
|
* @copyright 2013-2015 Hennes Hervé
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* http://www.h-hennes.fr/blog/
|
||||||
|
*/
|
||||||
|
class customerautogroups extends Module
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->author = 'hhennes';
|
||||||
|
$this->name = 'customerautogroups';
|
||||||
|
$this->tab = 'hhennes';
|
||||||
|
$this->version = '0.3.2';
|
||||||
|
$this->need_instance = 0;
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->displayName = $this->l('Customers Auto groups');
|
||||||
|
$this->description = $this->l('Add automaticaly customers to groups depending from params after registration');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installation du module
|
||||||
|
*/
|
||||||
|
public function install()
|
||||||
|
{
|
||||||
|
if (!parent::install() || !$this->registerHook('actionCustomerAccountAdd'))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Création d'une tab prestashop
|
||||||
|
$tab = new Tab();
|
||||||
|
$tab->class_name = 'Rules';
|
||||||
|
$tab->module = $this->name;
|
||||||
|
$tab->id_parent = Tab::getIdFromClassName('AdminParentCustomer');
|
||||||
|
$languages = Language::getLanguages();
|
||||||
|
foreach ($languages as $lang) {
|
||||||
|
$tab->name[$lang['id_lang']] = 'Customer Auto Groups';
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$tab->save();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !$this->_installSql())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installation des tables du module
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected function _installSql()
|
||||||
|
{
|
||||||
|
$sqlRule = "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."autogroup_rule` (
|
||||||
|
`id_rule` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`condition_type` tinyint(2) NOT NULL,
|
||||||
|
`condition_field` varchar(255) NOT NULL,
|
||||||
|
`condition_operator` varchar(10) NOT NULL,
|
||||||
|
`condition_value` varchar(255) NOT NULL,
|
||||||
|
`id_group` int(11) NOT NULL,
|
||||||
|
`active` tinyint(1) unsigned NOT NULL,
|
||||||
|
`priority` tinyint(2) unsigned NOT NULL,
|
||||||
|
`stop_processing` tinyint(1) unsigned NOT NULL,
|
||||||
|
`default_group` tinyint(1) unsigned NOT NULL,
|
||||||
|
`clean_groups` tinyint(1) unsigned NOT NULL,
|
||||||
|
`date_add` datetime NOT NULL,
|
||||||
|
`date_upd` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id_rule`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;";
|
||||||
|
|
||||||
|
$sqlRuleLang = "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."autogroup_rule_lang` (
|
||||||
|
`id_rule` int(11) NOT NULL,
|
||||||
|
`id_lang` int(11) NOT NULL,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`description` text,
|
||||||
|
PRIMARY KEY (`id_rule`,`id_lang`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;" ;
|
||||||
|
|
||||||
|
if ( !Db::getInstance()->Execute($sqlRule) || !Db::getInstance()->Execute($sqlRuleLang))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Désinstalation du module
|
||||||
|
*/
|
||||||
|
public function uninstall()
|
||||||
|
{
|
||||||
|
//Suppression de la tab admin
|
||||||
|
$id_tab = Tab::getIdFromClassName('rules');
|
||||||
|
if ($id_tab) {
|
||||||
|
$tab = new Tab($id_tab);
|
||||||
|
$tab->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
Db::getInstance("DROP TABLE IF EXISTS `"._DB_PREFIX_."autogroup_rule`");
|
||||||
|
Db::getInstance("DROP TABLE IF EXISTS `"._DB_PREFIX_."autogroup_rule_lang`");
|
||||||
|
|
||||||
|
return parent::uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook Exécuté après la création d'un compte client
|
||||||
|
* @param array $params : informations du compte client créé
|
||||||
|
*/
|
||||||
|
public function hookActionCustomerAccountAdd($params)
|
||||||
|
{
|
||||||
|
$this->_processGroupRules($params['newCustomer']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traitement des règles
|
||||||
|
* @param Customer $customer
|
||||||
|
*/
|
||||||
|
protected function _processGroupRules(Customer $customer)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Inclusion de la classe des règles
|
||||||
|
include_once _PS_MODULE_DIR_.'/customerautogroups/classes/AutoGroupRule.php';
|
||||||
|
|
||||||
|
//Nombres d'adresses du client
|
||||||
|
$customer_addresses = Customer::getAddressesTotalById($customer->id);
|
||||||
|
|
||||||
|
//Si le client n'a pas d'adresse on ne peut pas traiter les règles liées aux données d'adresses.
|
||||||
|
if (!$customer_addresses) {
|
||||||
|
$sqlCond = ' AND condition_type = 1 ';
|
||||||
|
} else {
|
||||||
|
$sqlCond = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
//Récupération des règles applicables au client
|
||||||
|
$rules = Db::getInstance()->ExecuteS("SELECT * FROM "._DB_PREFIX_."autogroup_rule WHERE active=1 ".$sqlCond." ORDER BY priority");
|
||||||
|
|
||||||
|
$customerGroups = array();
|
||||||
|
foreach ($rules as $rule) {
|
||||||
|
|
||||||
|
//Traitement des règles de type "Client"
|
||||||
|
if ($rule['condition_type'] == AutoGroupRule::RULE_TYPE_CUSTOMER) {
|
||||||
|
$obj = $customer;
|
||||||
|
}
|
||||||
|
//Traitement des règles de type Adresse
|
||||||
|
else if ($rule['condition_type'] == AutoGroupRule::RULE_TYPE_ADDRESS ) {
|
||||||
|
//Normalement vu que le client vient d'être créé il ne peut avoir qu'une adresse
|
||||||
|
$id_address = Db::getInstance()->getValue("SELECT id_address FROM "._DB_PREFIX_."address WHERE id_customer=".$customer->id);
|
||||||
|
$obj = new Address($id_address);
|
||||||
|
}
|
||||||
|
//Type Inconnu : non traité
|
||||||
|
else {
|
||||||
|
//echo $this->l('Error : rule type unknow');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Il faut que la propriété de l'objet existe
|
||||||
|
if (!property_exists($obj, $rule['condition_field'])) {
|
||||||
|
//echo sprintf($this->l('Error : Unknow proprerty %s for class %'), $rule['condition_field'], get_class($obj));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//On teste la conditon
|
||||||
|
$ruleApplied = false;
|
||||||
|
$defaultGroup = false;
|
||||||
|
$cleanGroups = false;
|
||||||
|
|
||||||
|
switch ($rule['condition_operator']) {
|
||||||
|
|
||||||
|
case 'eq':
|
||||||
|
if ($obj->{$rule['condition_field']} == $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ne':
|
||||||
|
if ($obj->{$rule['condition_field']} != $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'gt':
|
||||||
|
if ($obj->{$rule['condition_field']} > $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ge':
|
||||||
|
if ($obj->{$rule['condition_field']} >= $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'lt':
|
||||||
|
if ($obj->{$rule['condition_field']} < $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'le':
|
||||||
|
if ($obj->{$rule['condition_field']} <= $rule['condition_value']) $ruleApplied = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'LIKE %':
|
||||||
|
if ( preg_match('#'.$rule['condition_value'].'#',$obj->{$rule['condition_field']}) )
|
||||||
|
$ruleApplied = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ruleApplied) {
|
||||||
|
//echo sprintf( $this->l('Rule %d applied for customer'),$rule['id_rule']).'<br />';
|
||||||
|
$customerGroups[] = $rule['id_group'];
|
||||||
|
|
||||||
|
//Si la règle doit être la dernière à être traitée, on sors de la boucle
|
||||||
|
if ($rule['stop_processing'] == 1) {
|
||||||
|
if ($rule['default_group'] == 1) {
|
||||||
|
$defaultGroup = $rule['id_group'];
|
||||||
|
}
|
||||||
|
if ($rule['clean_groups'] == 1) {
|
||||||
|
$cleanGroups = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Ajout du client aux groupes nécessaires
|
||||||
|
if ( sizeof($customerGroups)) {
|
||||||
|
|
||||||
|
//Si le flag de suppression des groupes
|
||||||
|
if ( $cleanGroups )
|
||||||
|
$customer->cleanGroups();
|
||||||
|
|
||||||
|
//Application du groupe par défaut
|
||||||
|
if ( $defaultGroup ) {
|
||||||
|
$customer->id_default_group = $defaultGroup;
|
||||||
|
try {
|
||||||
|
$customer->save();
|
||||||
|
} catch (PrestaShopException $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Suppression des doublons
|
||||||
|
$customerGroups = array_unique($customerGroups);
|
||||||
|
|
||||||
|
//Ajout du client aux groups nécessaires
|
||||||
|
$customer->addGroups($customerGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
$(function(){
|
||||||
|
|
||||||
|
//Changement du type de condition dans le formulaire
|
||||||
|
$('#condition_type').change(function(){
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url : currentIndex,
|
||||||
|
data : {
|
||||||
|
'ajax' : true,
|
||||||
|
'action' : 'UpdateConditionTypeSelect',
|
||||||
|
'token': $('#token').val(),
|
||||||
|
'condition_type' : $(this).val()
|
||||||
|
},
|
||||||
|
complete: function(msg){
|
||||||
|
$('#condition_field').html('').html(msg.responseText);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
744
opcache.php
Normal file
744
opcache.php
Normal file
@ -0,0 +1,744 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define('THOUSAND_SEPARATOR',true);
|
||||||
|
|
||||||
|
if (!extension_loaded('Zend OPcache')) {
|
||||||
|
echo '<div style="background-color: #F2DEDE; color: #B94A48; padding: 1em;">You do not have the Zend OPcache extension loaded, sample data is being shown instead.</div>';
|
||||||
|
require 'data-sample.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpCacheDataModel
|
||||||
|
{
|
||||||
|
private $_configuration;
|
||||||
|
private $_status;
|
||||||
|
private $_d3Scripts = array();
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->_configuration = opcache_get_configuration();
|
||||||
|
$this->_status = opcache_get_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPageTitle()
|
||||||
|
{
|
||||||
|
return 'PHP ' . phpversion() . " with OpCache {$this->_configuration['version']['version']}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStatusDataRows()
|
||||||
|
{
|
||||||
|
$rows = array();
|
||||||
|
foreach ($this->_status as $key => $value) {
|
||||||
|
if ($key === 'scripts') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value)) {
|
||||||
|
foreach ($value as $k => $v) {
|
||||||
|
if ($v === false) {
|
||||||
|
$value = 'false';
|
||||||
|
}
|
||||||
|
if ($v === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
if ($k === 'used_memory' || $k === 'free_memory' || $k === 'wasted_memory') {
|
||||||
|
$v = $this->_size_for_humans(
|
||||||
|
$v
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($k === 'current_wasted_percentage' || $k === 'opcache_hit_rate') {
|
||||||
|
$v = number_format(
|
||||||
|
$v,
|
||||||
|
2
|
||||||
|
) . '%';
|
||||||
|
}
|
||||||
|
if ($k === 'blacklist_miss_ratio') {
|
||||||
|
$v = number_format($v, 2) . '%';
|
||||||
|
}
|
||||||
|
if ($k === 'start_time' || $k === 'last_restart_time') {
|
||||||
|
$v = ($v ? date(DATE_RFC822, $v) : 'never');
|
||||||
|
}
|
||||||
|
if (THOUSAND_SEPARATOR === true && is_int($v)) {
|
||||||
|
$v = number_format($v);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = "<tr><th>$k</th><td>$v</td></tr>\n";
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($value === false) {
|
||||||
|
$value = 'false';
|
||||||
|
}
|
||||||
|
if ($value === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
$rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\n", $rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigDataRows()
|
||||||
|
{
|
||||||
|
$rows = array();
|
||||||
|
foreach ($this->_configuration['directives'] as $key => $value) {
|
||||||
|
if ($value === false) {
|
||||||
|
$value = 'false';
|
||||||
|
}
|
||||||
|
if ($value === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
if ($key == 'opcache.memory_consumption') {
|
||||||
|
$value = $this->_size_for_humans($value);
|
||||||
|
}
|
||||||
|
$rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\n", $rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScriptStatusRows()
|
||||||
|
{
|
||||||
|
foreach ($this->_status['scripts'] as $key => $data) {
|
||||||
|
$dirs[dirname($key)][basename($key)] = $data;
|
||||||
|
$this->_arrayPset($this->_d3Scripts, $key, array(
|
||||||
|
'name' => basename($key),
|
||||||
|
'size' => $data['memory_consumption'],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
asort($dirs);
|
||||||
|
|
||||||
|
$basename = '';
|
||||||
|
while (true) {
|
||||||
|
if (count($this->_d3Scripts) !=1) break;
|
||||||
|
$basename .= DIRECTORY_SEPARATOR . key($this->_d3Scripts);
|
||||||
|
$this->_d3Scripts = reset($this->_d3Scripts);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_d3Scripts = $this->_processPartition($this->_d3Scripts, $basename);
|
||||||
|
$id = 1;
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($dirs as $dir => $files) {
|
||||||
|
$count = count($files);
|
||||||
|
$file_plural = $count > 1 ? 's' : null;
|
||||||
|
$m = 0;
|
||||||
|
foreach ($files as $file => $data) {
|
||||||
|
$m += $data["memory_consumption"];
|
||||||
|
}
|
||||||
|
$m = $this->_size_for_humans($m);
|
||||||
|
|
||||||
|
if ($count > 1) {
|
||||||
|
$rows[] = '<tr>';
|
||||||
|
$rows[] = "<th class=\"clickable\" id=\"head-{$id}\" colspan=\"3\" onclick=\"toggleVisible('#head-{$id}', '#row-{$id}')\">{$dir} ({$count} file{$file_plural}, {$m})</th>";
|
||||||
|
$rows[] = '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($files as $file => $data) {
|
||||||
|
$rows[] = "<tr id=\"row-{$id}\">";
|
||||||
|
$rows[] = "<td>" . $this->_format_value($data["hits"]) . "</td>";
|
||||||
|
$rows[] = "<td>" . $this->_size_for_humans($data["memory_consumption"]) . "</td>";
|
||||||
|
$rows[] = $count > 1 ? "<td>{$file}</td>" : "<td>{$dir}/{$file}</td>";
|
||||||
|
$rows[] = '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
++$id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("\n", $rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScriptStatusCount()
|
||||||
|
{
|
||||||
|
return count($this->_status["scripts"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGraphDataSetJson()
|
||||||
|
{
|
||||||
|
$dataset = array();
|
||||||
|
$dataset['memory'] = array(
|
||||||
|
$this->_status['memory_usage']['used_memory'],
|
||||||
|
$this->_status['memory_usage']['free_memory'],
|
||||||
|
$this->_status['memory_usage']['wasted_memory'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$dataset['keys'] = array(
|
||||||
|
$this->_status['opcache_statistics']['num_cached_keys'],
|
||||||
|
$this->_status['opcache_statistics']['max_cached_keys'] - $this->_status['opcache_statistics']['num_cached_keys'],
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
$dataset['hits'] = array(
|
||||||
|
$this->_status['opcache_statistics']['misses'],
|
||||||
|
$this->_status['opcache_statistics']['hits'],
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$dataset['restarts'] = array(
|
||||||
|
$this->_status['opcache_statistics']['oom_restarts'],
|
||||||
|
$this->_status['opcache_statistics']['manual_restarts'],
|
||||||
|
$this->_status['opcache_statistics']['hash_restarts'],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (THOUSAND_SEPARATOR === true) {
|
||||||
|
$dataset['TSEP'] = 1;
|
||||||
|
} else {
|
||||||
|
$dataset['TSEP'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($dataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHumanUsedMemory()
|
||||||
|
{
|
||||||
|
return $this->_size_for_humans($this->getUsedMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHumanFreeMemory()
|
||||||
|
{
|
||||||
|
return $this->_size_for_humans($this->getFreeMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHumanWastedMemory()
|
||||||
|
{
|
||||||
|
return $this->_size_for_humans($this->getWastedMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsedMemory()
|
||||||
|
{
|
||||||
|
return $this->_status['memory_usage']['used_memory'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFreeMemory()
|
||||||
|
{
|
||||||
|
return $this->_status['memory_usage']['free_memory'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWastedMemory()
|
||||||
|
{
|
||||||
|
return $this->_status['memory_usage']['wasted_memory'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWastedMemoryPercentage()
|
||||||
|
{
|
||||||
|
return number_format($this->_status['memory_usage']['current_wasted_percentage'], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getD3Scripts()
|
||||||
|
{
|
||||||
|
return $this->_d3Scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _processPartition($value, $name = null)
|
||||||
|
{
|
||||||
|
if (array_key_exists('size', $value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array = array('name' => $name,'children' => array());
|
||||||
|
|
||||||
|
foreach ($value as $k => $v) {
|
||||||
|
$array['children'][] = $this->_processPartition($v, $k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _format_value($value)
|
||||||
|
{
|
||||||
|
if (THOUSAND_SEPARATOR === true) {
|
||||||
|
return number_format($value);
|
||||||
|
} else {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _size_for_humans($bytes)
|
||||||
|
{
|
||||||
|
if ($bytes > 1048576) {
|
||||||
|
return sprintf('%.2f MB', $bytes / 1048576);
|
||||||
|
} else {
|
||||||
|
if ($bytes > 1024) {
|
||||||
|
return sprintf('%.2f kB', $bytes / 1024);
|
||||||
|
} else {
|
||||||
|
return sprintf('%d bytes', $bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Borrowed from Laravel
|
||||||
|
private function _arrayPset(&$array, $key, $value)
|
||||||
|
{
|
||||||
|
if (is_null($key)) return $array = $value;
|
||||||
|
$keys = explode(DIRECTORY_SEPARATOR, ltrim($key, DIRECTORY_SEPARATOR));
|
||||||
|
while (count($keys) > 1) {
|
||||||
|
$key = array_shift($keys);
|
||||||
|
if ( ! isset($array[$key]) || ! is_array($array[$key])) {
|
||||||
|
$array[$key] = array();
|
||||||
|
}
|
||||||
|
$array =& $array[$key];
|
||||||
|
}
|
||||||
|
$array[array_shift($keys)] = $value;
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataModel = new OpCacheDataModel();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
width: 1024px;
|
||||||
|
margin: auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(even) {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab label {
|
||||||
|
background: #eee;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-left: -1px;
|
||||||
|
position: relative;
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab [type=radio] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab th, .tab td {
|
||||||
|
padding: 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
top: 28px;
|
||||||
|
left: 0;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
height: 450px;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content th, .tab:nth-child(3) td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content td {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=radio]:checked ~ label {
|
||||||
|
background: white;
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=radio]:checked ~ label ~ .content {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graph {
|
||||||
|
float: right;
|
||||||
|
width: 40%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graph > form {
|
||||||
|
position: absolute;
|
||||||
|
right: 60px;
|
||||||
|
top: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graph > svg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stats {
|
||||||
|
position: absolute;
|
||||||
|
right: 125px;
|
||||||
|
top: 145px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stats th, #stats td {
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#partition {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: #ddd;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-partition {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 20;
|
||||||
|
right: 15px;
|
||||||
|
top: 15px;
|
||||||
|
background: #f9373d;
|
||||||
|
color: #fff;
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-partition:hover {
|
||||||
|
background: #D32F33;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#partition rect {
|
||||||
|
stroke: #fff;
|
||||||
|
fill: #aaa;
|
||||||
|
fill-opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#partition rect.parent {
|
||||||
|
cursor: pointer;
|
||||||
|
fill: steelblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#partition text {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var hidden = {};
|
||||||
|
function toggleVisible(head, row) {
|
||||||
|
if (!hidden[row]) {
|
||||||
|
d3.selectAll(row).transition().style('display', 'none');
|
||||||
|
hidden[row] = true;
|
||||||
|
d3.select(head).transition().style('color', '#ccc');
|
||||||
|
} else {
|
||||||
|
d3.selectAll(row).transition().style('display');
|
||||||
|
hidden[row] = false;
|
||||||
|
d3.select(head).transition().style('color', '#000');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<title><?php echo $dataModel->getPageTitle(); ?></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<h1><?php echo $dataModel->getPageTitle(); ?></h1>
|
||||||
|
|
||||||
|
<div class="tabs">
|
||||||
|
|
||||||
|
<div class="tab">
|
||||||
|
<input type="radio" id="tab-status" name="tab-group-1" checked>
|
||||||
|
<label for="tab-status">Status</label>
|
||||||
|
<div class="content">
|
||||||
|
<table>
|
||||||
|
<?php echo $dataModel->getStatusDataRows(); ?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab">
|
||||||
|
<input type="radio" id="tab-config" name="tab-group-1">
|
||||||
|
<label for="tab-config">Configuration</label>
|
||||||
|
<div class="content">
|
||||||
|
<table>
|
||||||
|
<?php echo $dataModel->getConfigDataRows(); ?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab">
|
||||||
|
<input type="radio" id="tab-scripts" name="tab-group-1">
|
||||||
|
<label for="tab-scripts">Scripts (<?php echo $dataModel->getScriptStatusCount(); ?>)</label>
|
||||||
|
<div class="content">
|
||||||
|
<table style="font-size:0.8em;">
|
||||||
|
<tr>
|
||||||
|
<th width="10%">Hits</th>
|
||||||
|
<th width="20%">Memory</th>
|
||||||
|
<th width="70%">Path</th>
|
||||||
|
</tr>
|
||||||
|
<?php echo $dataModel->getScriptStatusRows(); ?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab">
|
||||||
|
<input type="radio" id="tab-visualise" name="tab-group-1">
|
||||||
|
<label for="tab-visualise">Visualise Partition</label>
|
||||||
|
<div class="content"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="graph">
|
||||||
|
<form>
|
||||||
|
<label><input type="radio" name="dataset" value="memory" checked> Memory</label>
|
||||||
|
<label><input type="radio" name="dataset" value="keys"> Keys</label>
|
||||||
|
<label><input type="radio" name="dataset" value="hits"> Hits</label>
|
||||||
|
<label><input type="radio" name="dataset" value="restarts"> Restarts</label>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="stats"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="close-partition">✖ Close Visualisation</div>
|
||||||
|
<div id="partition"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var dataset = <?php echo $dataModel->getGraphDataSetJson(); ?>;
|
||||||
|
|
||||||
|
var width = 400,
|
||||||
|
height = 400,
|
||||||
|
radius = Math.min(width, height) / 2,
|
||||||
|
colours = ['#B41F1F', '#1FB437', '#ff7f0e'];
|
||||||
|
|
||||||
|
d3.scale.customColours = function() {
|
||||||
|
return d3.scale.ordinal().range(colours);
|
||||||
|
};
|
||||||
|
|
||||||
|
var colour = d3.scale.customColours();
|
||||||
|
var pie = d3.layout.pie().sort(null);
|
||||||
|
|
||||||
|
var arc = d3.svg.arc().innerRadius(radius - 20).outerRadius(radius - 50);
|
||||||
|
var svg = d3.select("#graph").append("svg")
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
|
||||||
|
|
||||||
|
var path = svg.selectAll("path")
|
||||||
|
.data(pie(dataset.memory))
|
||||||
|
.enter().append("path")
|
||||||
|
.attr("fill", function(d, i) { return colour(i); })
|
||||||
|
.attr("d", arc)
|
||||||
|
.each(function(d) { this._current = d; }); // store the initial values
|
||||||
|
|
||||||
|
d3.selectAll("input").on("change", change);
|
||||||
|
set_text("memory");
|
||||||
|
|
||||||
|
function set_text(t) {
|
||||||
|
if (t === "memory") {
|
||||||
|
d3.select("#stats").html(
|
||||||
|
"<table><tr><th style='background:#B41F1F;'>Used</th><td><?php echo $dataModel->getHumanUsedMemory()?></td></tr>"+
|
||||||
|
"<tr><th style='background:#1FB437;'>Free</th><td><?php echo $dataModel->getHumanFreeMemory()?></td></tr>"+
|
||||||
|
"<tr><th style='background:#ff7f0e;' rowspan=\"2\">Wasted</th><td><?php echo $dataModel->getHumanWastedMemory()?></td></tr>"+
|
||||||
|
"<tr><td><?php echo $dataModel->getWastedMemoryPercentage()?>%</td></tr></table>"
|
||||||
|
);
|
||||||
|
} else if (t === "keys") {
|
||||||
|
d3.select("#stats").html(
|
||||||
|
"<table><tr><th style='background:#B41F1F;'>Cached keys</th><td>"+format_value(dataset[t][0])+"</td></tr>"+
|
||||||
|
"<tr><th style='background:#1FB437;'>Free Keys</th><td>"+format_value(dataset[t][1])+"</td></tr></table>"
|
||||||
|
);
|
||||||
|
} else if (t === "hits") {
|
||||||
|
d3.select("#stats").html(
|
||||||
|
"<table><tr><th style='background:#B41F1F;'>Misses</th><td>"+format_value(dataset[t][0])+"</td></tr>"+
|
||||||
|
"<tr><th style='background:#1FB437;'>Cache Hits</th><td>"+format_value(dataset[t][1])+"</td></tr></table>"
|
||||||
|
);
|
||||||
|
} else if (t === "restarts") {
|
||||||
|
d3.select("#stats").html(
|
||||||
|
"<table><tr><th style='background:#B41F1F;'>Memory</th><td>"+dataset[t][0]+"</td></tr>"+
|
||||||
|
"<tr><th style='background:#1FB437;'>Manual</th><td>"+dataset[t][1]+"</td></tr>"+
|
||||||
|
"<tr><th style='background:#ff7f0e;'>Keys</th><td>"+dataset[t][2]+"</td></tr></table>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function change() {
|
||||||
|
// Filter out any zero values to see if there is anything left
|
||||||
|
var remove_zero_values = dataset[this.value].filter(function(value) {
|
||||||
|
return value > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skip if the value is undefined for some reason
|
||||||
|
if (typeof dataset[this.value] !== 'undefined' && remove_zero_values.length > 0) {
|
||||||
|
$('#graph').find('> svg').show();
|
||||||
|
path = path.data(pie(dataset[this.value])); // update the data
|
||||||
|
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
|
||||||
|
// Hide the graph if we can't draw it correctly, not ideal but this works
|
||||||
|
} else {
|
||||||
|
$('#graph').find('> svg').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_text(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function arcTween(a) {
|
||||||
|
var i = d3.interpolate(this._current, a);
|
||||||
|
this._current = i(0);
|
||||||
|
return function(t) {
|
||||||
|
return arc(i(t));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function size_for_humans(bytes) {
|
||||||
|
if (bytes > 1048576) {
|
||||||
|
return (bytes/1048576).toFixed(2) + ' MB';
|
||||||
|
} else if (bytes > 1024) {
|
||||||
|
return (bytes/1024).toFixed(2) + ' KB';
|
||||||
|
} else return bytes + ' bytes';
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_value(value) {
|
||||||
|
if (dataset["TSEP"] == 1) {
|
||||||
|
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var w = window.innerWidth,
|
||||||
|
h = window.innerHeight,
|
||||||
|
x = d3.scale.linear().range([0, w]),
|
||||||
|
y = d3.scale.linear().range([0, h]);
|
||||||
|
|
||||||
|
var vis = d3.select("#partition")
|
||||||
|
.style("width", w + "px")
|
||||||
|
.style("height", h + "px")
|
||||||
|
.append("svg:svg")
|
||||||
|
.attr("width", w)
|
||||||
|
.attr("height", h);
|
||||||
|
|
||||||
|
var partition = d3.layout.partition()
|
||||||
|
.value(function(d) { return d.size; });
|
||||||
|
|
||||||
|
root = JSON.parse('<?php echo json_encode($dataModel->getD3Scripts()); ?>');
|
||||||
|
|
||||||
|
var g = vis.selectAll("g")
|
||||||
|
.data(partition.nodes(root))
|
||||||
|
.enter().append("svg:g")
|
||||||
|
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; })
|
||||||
|
.on("click", click);
|
||||||
|
|
||||||
|
var kx = w / root.dx,
|
||||||
|
ky = h / 1;
|
||||||
|
|
||||||
|
g.append("svg:rect")
|
||||||
|
.attr("width", root.dy * kx)
|
||||||
|
.attr("height", function(d) { return d.dx * ky; })
|
||||||
|
.attr("class", function(d) { return d.children ? "parent" : "child"; });
|
||||||
|
|
||||||
|
g.append("svg:text")
|
||||||
|
.attr("transform", transform)
|
||||||
|
.attr("dy", ".35em")
|
||||||
|
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; })
|
||||||
|
.text(function(d) { return d.name; })
|
||||||
|
|
||||||
|
d3.select(window)
|
||||||
|
.on("click", function() { click(root); })
|
||||||
|
|
||||||
|
function click(d) {
|
||||||
|
if (!d.children) return;
|
||||||
|
|
||||||
|
kx = (d.y ? w - 40 : w) / (1 - d.y);
|
||||||
|
ky = h / d.dx;
|
||||||
|
x.domain([d.y, 1]).range([d.y ? 40 : 0, w]);
|
||||||
|
y.domain([d.x, d.x + d.dx]);
|
||||||
|
|
||||||
|
var t = g.transition()
|
||||||
|
.duration(d3.event.altKey ? 7500 : 750)
|
||||||
|
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; });
|
||||||
|
|
||||||
|
t.select("rect")
|
||||||
|
.attr("width", d.dy * kx)
|
||||||
|
.attr("height", function(d) { return d.dx * ky; });
|
||||||
|
|
||||||
|
t.select("text")
|
||||||
|
.attr("transform", transform)
|
||||||
|
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; });
|
||||||
|
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function transform(d) {
|
||||||
|
return "translate(8," + d.dx * ky / 2 + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
function handleVisualisationToggle(close) {
|
||||||
|
|
||||||
|
$('#partition, #close-partition').fadeToggle();
|
||||||
|
|
||||||
|
// Is the visualisation being closed? If so show the status tab again
|
||||||
|
if (close) {
|
||||||
|
|
||||||
|
$('#tab-visualise').removeAttr('checked');
|
||||||
|
$('#tab-status').trigger('click');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$('label[for="tab-visualise"], #close-partition').on('click', function() {
|
||||||
|
|
||||||
|
handleVisualisationToggle(($(this).attr('id') === 'close-partition'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).keyup(function(e) {
|
||||||
|
|
||||||
|
if (e.keyCode == 27) handleVisualisationToggle(true);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -100,6 +100,7 @@ class Cart extends CartCore
|
|||||||
|
|
||||||
$result = Db::getInstance()->executeS($sql);
|
$result = Db::getInstance()->executeS($sql);
|
||||||
|
|
||||||
|
|
||||||
// Reset the cache before the following return, or else an empty cart will add dozens of queries
|
// Reset the cache before the following return, or else an empty cart will add dozens of queries
|
||||||
$products_ids = array();
|
$products_ids = array();
|
||||||
$pa_ids = array();
|
$pa_ids = array();
|
||||||
|
@ -56,5 +56,4 @@ class Category extends CategoryCore
|
|||||||
|
|
||||||
return $categories;
|
return $categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
173
override/controllers/admin/AdminCustomersController.php
Normal file
173
override/controllers/admin/AdminCustomersController.php
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?php
|
||||||
|
class AdminCustomersController extends AdminCustomersControllerCore
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
CHANGES Antadis :
|
||||||
|
got rid of "Carts" summary information part (too slow for some customer) :
|
||||||
|
- the loading from of carts infos is removed
|
||||||
|
- "cart" object is removed from smarty variables
|
||||||
|
*/
|
||||||
|
public function renderView()
|
||||||
|
{
|
||||||
|
/** @var Customer $customer */
|
||||||
|
if (!($customer = $this->loadObject())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->context->customer = $customer;
|
||||||
|
$gender = new Gender($customer->id_gender, $this->context->language->id);
|
||||||
|
$gender_image = $gender->getImage();
|
||||||
|
|
||||||
|
$customer_stats = $customer->getStats();
|
||||||
|
$sql = 'SELECT SUM(total_paid_real) FROM '._DB_PREFIX_.'orders WHERE id_customer = %d AND valid = 1';
|
||||||
|
if ($total_customer = Db::getInstance()->getValue(sprintf($sql, $customer->id))) {
|
||||||
|
$sql = 'SELECT SQL_CALC_FOUND_ROWS COUNT(*) FROM '._DB_PREFIX_.'orders WHERE valid = 1 AND id_customer != '.(int)$customer->id.' GROUP BY id_customer HAVING SUM(total_paid_real) > %d';
|
||||||
|
Db::getInstance()->getValue(sprintf($sql, (int)$total_customer));
|
||||||
|
$count_better_customers = (int)Db::getInstance()->getValue('SELECT FOUND_ROWS()') + 1;
|
||||||
|
} else {
|
||||||
|
$count_better_customers = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
$orders = Order::getCustomerOrders($customer->id, true);
|
||||||
|
$total_orders = count($orders);
|
||||||
|
for ($i = 0; $i < $total_orders; $i++) {
|
||||||
|
$orders[$i]['total_paid_real_not_formated'] = $orders[$i]['total_paid_real'];
|
||||||
|
$orders[$i]['total_paid_real'] = Tools::displayPrice($orders[$i]['total_paid_real'], new Currency((int)$orders[$i]['id_currency']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$messages = CustomerThread::getCustomerMessages((int)$customer->id);
|
||||||
|
|
||||||
|
$total_messages = count($messages);
|
||||||
|
for ($i = 0; $i < $total_messages; $i++) {
|
||||||
|
$messages[$i]['message'] = substr(strip_tags(html_entity_decode($messages[$i]['message'], ENT_NOQUOTES, 'UTF-8')), 0, 75);
|
||||||
|
$messages[$i]['date_add'] = Tools::displayDate($messages[$i]['date_add'], null, true);
|
||||||
|
if (isset(self::$meaning_status[$messages[$i]['status']])) {
|
||||||
|
$messages[$i]['status'] = self::$meaning_status[$messages[$i]['status']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$groups = $customer->getGroups();
|
||||||
|
$total_groups = count($groups);
|
||||||
|
for ($i = 0; $i < $total_groups; $i++) {
|
||||||
|
$group = new Group($groups[$i]);
|
||||||
|
$groups[$i] = array();
|
||||||
|
$groups[$i]['id_group'] = $group->id;
|
||||||
|
$groups[$i]['name'] = $group->name[$this->default_form_language];
|
||||||
|
}
|
||||||
|
|
||||||
|
$total_ok = 0;
|
||||||
|
$orders_ok = array();
|
||||||
|
$orders_ko = array();
|
||||||
|
foreach ($orders as $order) {
|
||||||
|
if (!isset($order['order_state'])) {
|
||||||
|
$order['order_state'] = $this->l('There is no status defined for this order.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($order['valid']) {
|
||||||
|
$orders_ok[] = $order;
|
||||||
|
$total_ok += $order['total_paid_real_not_formated'];
|
||||||
|
} else {
|
||||||
|
$orders_ko[] = $order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$products = $customer->getBoughtProducts();
|
||||||
|
|
||||||
|
$this->context->currency = Currency::getDefaultCurrency();
|
||||||
|
|
||||||
|
$sql = 'SELECT DISTINCT cp.id_product, c.id_cart, c.id_shop, cp.id_shop AS cp_id_shop
|
||||||
|
FROM '._DB_PREFIX_.'cart_product cp
|
||||||
|
JOIN '._DB_PREFIX_.'cart c ON (c.id_cart = cp.id_cart)
|
||||||
|
JOIN '._DB_PREFIX_.'product p ON (cp.id_product = p.id_product)
|
||||||
|
WHERE c.id_customer = '.(int)$customer->id.'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM '._DB_PREFIX_.'orders o
|
||||||
|
JOIN '._DB_PREFIX_.'order_detail od ON (o.id_order = od.id_order)
|
||||||
|
WHERE product_id = cp.id_product AND o.valid = 1 AND o.id_customer = '.(int)$customer->id.'
|
||||||
|
)';
|
||||||
|
$interested = Db::getInstance()->executeS($sql);
|
||||||
|
$total_interested = count($interested);
|
||||||
|
for ($i = 0; $i < $total_interested; $i++) {
|
||||||
|
$product = new Product($interested[$i]['id_product'], false, $this->default_form_language, $interested[$i]['id_shop']);
|
||||||
|
if (!Validate::isLoadedObject($product)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$interested[$i]['url'] = $this->context->link->getProductLink(
|
||||||
|
$product->id,
|
||||||
|
$product->link_rewrite,
|
||||||
|
Category::getLinkRewrite($product->id_category_default, $this->default_form_language),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
$interested[$i]['cp_id_shop']
|
||||||
|
);
|
||||||
|
$interested[$i]['id'] = (int)$product->id;
|
||||||
|
$interested[$i]['name'] = Tools::htmlentitiesUTF8($product->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$emails = $customer->getLastEmails();
|
||||||
|
|
||||||
|
$connections = $customer->getLastConnections();
|
||||||
|
if (!is_array($connections)) {
|
||||||
|
$connections = array();
|
||||||
|
}
|
||||||
|
$total_connections = count($connections);
|
||||||
|
for ($i = 0; $i < $total_connections; $i++) {
|
||||||
|
$connections[$i]['http_referer'] = $connections[$i]['http_referer'] ? preg_replace('/^www./', '', parse_url($connections[$i]['http_referer'], PHP_URL_HOST)) : $this->l('Direct link');
|
||||||
|
}
|
||||||
|
|
||||||
|
$referrers = Referrer::getReferrers($customer->id);
|
||||||
|
$total_referrers = count($referrers);
|
||||||
|
for ($i = 0; $i < $total_referrers; $i++) {
|
||||||
|
$referrers[$i]['date_add'] = Tools::displayDate($referrers[$i]['date_add'], null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$customerLanguage = new Language($customer->id_lang);
|
||||||
|
$shop = new Shop($customer->id_shop);
|
||||||
|
$this->tpl_view_vars = array(
|
||||||
|
'customer' => $customer,
|
||||||
|
'gender' => $gender,
|
||||||
|
'gender_image' => $gender_image,
|
||||||
|
// General information of the customer
|
||||||
|
'registration_date' => Tools::displayDate($customer->date_add, null, true),
|
||||||
|
'customer_stats' => $customer_stats,
|
||||||
|
'last_visit' => Tools::displayDate($customer_stats['last_visit'], null, true),
|
||||||
|
'count_better_customers' => $count_better_customers,
|
||||||
|
'shop_is_feature_active' => Shop::isFeatureActive(),
|
||||||
|
'name_shop' => $shop->name,
|
||||||
|
'customer_birthday' => Tools::displayDate($customer->birthday),
|
||||||
|
'last_update' => Tools::displayDate($customer->date_upd, null, true),
|
||||||
|
'customer_exists' => Customer::customerExists($customer->email),
|
||||||
|
'id_lang' => $customer->id_lang,
|
||||||
|
'customerLanguage' => $customerLanguage,
|
||||||
|
// Add a Private note
|
||||||
|
'customer_note' => Tools::htmlentitiesUTF8($customer->note),
|
||||||
|
// Messages
|
||||||
|
'messages' => $messages,
|
||||||
|
// Groups
|
||||||
|
'groups' => $groups,
|
||||||
|
// Orders
|
||||||
|
'orders' => $orders,
|
||||||
|
'orders_ok' => $orders_ok,
|
||||||
|
'orders_ko' => $orders_ko,
|
||||||
|
'total_ok' => Tools::displayPrice($total_ok, $this->context->currency->id),
|
||||||
|
// Products
|
||||||
|
'products' => $products,
|
||||||
|
// Addresses
|
||||||
|
'addresses' => $customer->getAddresses($this->default_form_language),
|
||||||
|
// Discounts
|
||||||
|
'discounts' => CartRule::getCustomerCartRules($this->default_form_language, $customer->id, false, false),
|
||||||
|
// Interested
|
||||||
|
'interested' => $interested,
|
||||||
|
// Emails
|
||||||
|
'emails' => $emails,
|
||||||
|
// Connections
|
||||||
|
'connections' => $connections,
|
||||||
|
// Referrers
|
||||||
|
'referrers' => $referrers,
|
||||||
|
'show_toolbar' => true
|
||||||
|
);
|
||||||
|
|
||||||
|
return AdminController::renderView();
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ class CartController extends CartControllerCore
|
|||||||
{
|
{
|
||||||
protected function processChangeProductInCart()
|
protected function processChangeProductInCart()
|
||||||
{
|
{
|
||||||
|
|
||||||
$mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';
|
$mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';
|
||||||
|
|
||||||
if ($this->qty == 0) {
|
if ($this->qty == 0) {
|
||||||
@ -93,6 +94,7 @@ class CartController extends CartControllerCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
$update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
|
$update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
|
||||||
|
|
||||||
if ($update_quantity < 0) {
|
if ($update_quantity < 0) {
|
||||||
// If product has attribute, minimal quantity is set with minimal quantity of attribute
|
// If product has attribute, minimal quantity is set with minimal quantity of attribute
|
||||||
$minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
|
$minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
|
||||||
|
124
tools/antadis_tools/debug/AntDebug.php
Normal file
124
tools/antadis_tools/debug/AntDebug.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
class AntDebug
|
||||||
|
{
|
||||||
|
const TXT = 1;
|
||||||
|
const HTML = 2;
|
||||||
|
const JSON = 3;
|
||||||
|
|
||||||
|
static function calledBy($class_name, $function_name)
|
||||||
|
{
|
||||||
|
if (!empty($class_name) && empty($function_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$found = false;
|
||||||
|
|
||||||
|
$trace_result = debug_backtrace();
|
||||||
|
|
||||||
|
foreach ($trace_result as $index => $row) {
|
||||||
|
if (!empty($class_name) && isset($row['class'])) {
|
||||||
|
$found = ($row['class'] == $class_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($row['function'])) {
|
||||||
|
$found = false;
|
||||||
|
}
|
||||||
|
elseif ((!empty($class_name) && $found) || empty($class_name)) {
|
||||||
|
$found = ($row['function'] == $function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($found) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $found;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function trace($type_output = AntDebug::HTML, $show_args = false)
|
||||||
|
{
|
||||||
|
static $nb_times = 0;
|
||||||
|
|
||||||
|
$newline = PHP_EOL;
|
||||||
|
if ($type_output == self::HTML) {
|
||||||
|
$newline = '<br />';
|
||||||
|
}
|
||||||
|
elseif ($type_output == self::JSON) {
|
||||||
|
$newline = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($show_args) {
|
||||||
|
$trace_result = debug_backtrace();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$trace_result = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($trace_result as $index => $row) {
|
||||||
|
if ((isset($row['class']) && $row['class'] != __CLASS__) || ($row['function'] != __FUNCTION__)) {
|
||||||
|
|
||||||
|
$res = '';
|
||||||
|
|
||||||
|
if (isset($row['class'])) {
|
||||||
|
$res .= $row['class'].'::';
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $row['file'];
|
||||||
|
if (isset($_SERVER['CONTEXT_DOCUMENT_ROOT'])) {
|
||||||
|
$file = str_replace($_SERVER['CONTEXT_DOCUMENT_ROOT'], '', $file);
|
||||||
|
}
|
||||||
|
$res = $res.$row['function'].'() --- ['.$file.':'.$row['line'].']';
|
||||||
|
|
||||||
|
if ($show_args && isset($row['args'])) {
|
||||||
|
$res .= ' with args : ';
|
||||||
|
if ($type_output == self::HTML) {
|
||||||
|
$res .= "<pre style='margin-top:0px;padding-left:60px'>";
|
||||||
|
}
|
||||||
|
$res .= print_r($row['args'], true);
|
||||||
|
if ($type_output == self::HTML) {
|
||||||
|
$res .= "</pre>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$results[] = $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($results)>0) {
|
||||||
|
krsort($results, SORT_NUMERIC);
|
||||||
|
|
||||||
|
$output = array();
|
||||||
|
if ($type_output == self::HTML) {
|
||||||
|
$output[] = "<div style='background-color:white;'>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = 0;
|
||||||
|
foreach ($results as $trace) {
|
||||||
|
$padding = str_pad('', $level*3, '-', STR_PAD_LEFT);
|
||||||
|
|
||||||
|
if ($level > 0) {
|
||||||
|
$padding = $padding.' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$output[] = "#".$level." ".$padding.$trace.$newline;
|
||||||
|
$level++;
|
||||||
|
}
|
||||||
|
$nb_times++;
|
||||||
|
$output[] = "Nb times : ".$nb_times;
|
||||||
|
$output[] = $newline.$newline;
|
||||||
|
|
||||||
|
if ($type_output == self::HTML) {
|
||||||
|
$output[] = "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type_output == self::JSON) {
|
||||||
|
echo json_encode($output);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach($output as $line) {
|
||||||
|
echo $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
80
tools/antadis_tools/debug/AntDebugger.php
Normal file
80
tools/antadis_tools/debug/AntDebugger.php
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!class_exists('AntDebugger')) {
|
||||||
|
class AntDebugger
|
||||||
|
{
|
||||||
|
static function backtrace($show_args = false, $output_html = true)
|
||||||
|
{
|
||||||
|
static $nb_times = 0;
|
||||||
|
|
||||||
|
$newline = PHP_EOL;
|
||||||
|
if ($output_html) {
|
||||||
|
$newline = '<br />';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($show_args) {
|
||||||
|
$result = debug_backtrace();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$result = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($result as $index => $rows) {
|
||||||
|
if ((isset($rows['class']) && $rows['class'] != 'AntDebugger') || $rows['function'] != 'backtrace') {
|
||||||
|
|
||||||
|
$res = '';
|
||||||
|
|
||||||
|
if (isset($rows['class'])) {
|
||||||
|
$res .= $rows['class'].'::';
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $rows['file'];
|
||||||
|
if (isset($_SERVER['CONTEXT_DOCUMENT_ROOT'])) {
|
||||||
|
$file = str_replace($_SERVER['CONTEXT_DOCUMENT_ROOT'], '', $file);
|
||||||
|
}
|
||||||
|
$res = $res.$rows['function'].'() --- ['.$file.':'.$rows['line'].']';
|
||||||
|
|
||||||
|
if ($show_args && isset($rows['args'])) {
|
||||||
|
$res .= ' with args : ';
|
||||||
|
if ($output_html) {
|
||||||
|
$res .= "<pre style='margin-top:0px;padding-left:60px'>";
|
||||||
|
}
|
||||||
|
$res .= print_r($rows['args'], true);
|
||||||
|
if ($output_html) {
|
||||||
|
$res .= "</pre>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[] = $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
krsort($results, SORT_NUMERIC);
|
||||||
|
|
||||||
|
if ($output_html) {
|
||||||
|
echo "<div style='background-color:white;'>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = 0;
|
||||||
|
foreach ($results as $trace) {
|
||||||
|
$padding = str_pad('', $level*3, '-', STR_PAD_LEFT);
|
||||||
|
|
||||||
|
if ($level > 0) {
|
||||||
|
$padding = $padding.' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "#".$level." ".$padding.$trace.$newline;
|
||||||
|
$level++;
|
||||||
|
}
|
||||||
|
$nb_times++;
|
||||||
|
echo "Nb times : ".$nb_times;
|
||||||
|
echo $newline;
|
||||||
|
echo $newline;
|
||||||
|
|
||||||
|
if ($output_html) {
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
tools/antadis_tools/debug/index.php
Normal file
35
tools/antadis_tools/debug/index.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* 2007-2015 PrestaShop
|
||||||
|
*
|
||||||
|
* NOTICE OF LICENSE
|
||||||
|
*
|
||||||
|
* This source file is subject to the Academic Free License (AFL 3.0)
|
||||||
|
* that is bundled with this package in the file LICENSE.txt.
|
||||||
|
* It is also available through the world-wide-web at this URL:
|
||||||
|
* http://opensource.org/licenses/afl-3.0.php
|
||||||
|
* If you did not receive a copy of the license and are unable to
|
||||||
|
* obtain it through the world-wide-web, please send an email
|
||||||
|
* to license@prestashop.com so we can send you a copy immediately.
|
||||||
|
*
|
||||||
|
* 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 PrestaShop SA <contact@prestashop.com>
|
||||||
|
* @copyright 2007-2015 PrestaShop SA
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* International Registered Trademark & Property of PrestaShop SA
|
||||||
|
*/
|
||||||
|
|
||||||
|
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||||
|
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||||
|
|
||||||
|
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||||
|
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||||
|
header("Pragma: no-cache");
|
||||||
|
|
||||||
|
header("Location: ../");
|
||||||
|
exit;
|
91
tools/antadis_tools/debug/tests/test_debug.php
Normal file
91
tools/antadis_tools/debug/tests/test_debug.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
require_once('../AntDebug.php');
|
||||||
|
|
||||||
|
function test_trace_txt()
|
||||||
|
{
|
||||||
|
AntDebug::trace();
|
||||||
|
echo PHP_EOL;
|
||||||
|
echo PHP_EOL;
|
||||||
|
|
||||||
|
AntDebug::trace(AntDebug::TXT);
|
||||||
|
echo PHP_EOL;
|
||||||
|
echo PHP_EOL;
|
||||||
|
|
||||||
|
AntDebug::trace(AntDebug::HTML);
|
||||||
|
echo PHP_EOL;
|
||||||
|
echo PHP_EOL;
|
||||||
|
|
||||||
|
AntDebug::trace(AntDebug::JSON);
|
||||||
|
echo PHP_EOL;
|
||||||
|
echo PHP_EOL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_all()
|
||||||
|
{
|
||||||
|
test_trace_txt();
|
||||||
|
}
|
||||||
|
|
||||||
|
function update()
|
||||||
|
{
|
||||||
|
if (AntDebug::calledBy('', 'order_update')) {
|
||||||
|
AntDebug::trace(AntDebug::TXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function order_update()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function payment_update()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
class cart_object
|
||||||
|
{
|
||||||
|
function update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class order_object
|
||||||
|
{
|
||||||
|
function save()
|
||||||
|
{
|
||||||
|
$this->save_deux();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function save_deux()
|
||||||
|
{
|
||||||
|
$obj = new cart_object();
|
||||||
|
$obj->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class payment_object extends order_object
|
||||||
|
{
|
||||||
|
protected function save_deux()
|
||||||
|
{
|
||||||
|
if (AntDebug::calledBy('order_object', 'save')) {
|
||||||
|
AntDebug::trace(AntDebug::TXT);
|
||||||
|
}
|
||||||
|
$obj = new cart_object();
|
||||||
|
$obj->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//test_all();
|
||||||
|
|
||||||
|
order_update();
|
||||||
|
payment_update();
|
||||||
|
|
||||||
|
$obj = new order_object();
|
||||||
|
$obj->save();
|
||||||
|
|
||||||
|
$obj = new payment_object();
|
||||||
|
$obj->save();
|
3
tools/antadis_tools/include.php
Normal file
3
tools/antadis_tools/include.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(__DIR__.'/debug/AntDebug.php');
|
35
tools/antadis_tools/index.php
Normal file
35
tools/antadis_tools/index.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* 2007-2015 PrestaShop
|
||||||
|
*
|
||||||
|
* NOTICE OF LICENSE
|
||||||
|
*
|
||||||
|
* This source file is subject to the Academic Free License (AFL 3.0)
|
||||||
|
* that is bundled with this package in the file LICENSE.txt.
|
||||||
|
* It is also available through the world-wide-web at this URL:
|
||||||
|
* http://opensource.org/licenses/afl-3.0.php
|
||||||
|
* If you did not receive a copy of the license and are unable to
|
||||||
|
* obtain it through the world-wide-web, please send an email
|
||||||
|
* to license@prestashop.com so we can send you a copy immediately.
|
||||||
|
*
|
||||||
|
* 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 PrestaShop SA <contact@prestashop.com>
|
||||||
|
* @copyright 2007-2015 PrestaShop SA
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* International Registered Trademark & Property of PrestaShop SA
|
||||||
|
*/
|
||||||
|
|
||||||
|
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
||||||
|
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
||||||
|
|
||||||
|
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||||
|
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||||
|
header("Pragma: no-cache");
|
||||||
|
|
||||||
|
header("Location: ../");
|
||||||
|
exit;
|
@ -113,4 +113,77 @@ class Tools extends ToolsCore
|
|||||||
Context::getContext()->controller->setRedirectAfter($url);
|
Context::getContext()->controller->setRedirectAfter($url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function displayPriceWithTaxTag($price)
|
||||||
|
{
|
||||||
|
return self::displayPriceWithTaxTagSmarty(array('price' => $price));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function displayPriceWithTaxTagSmarty($params)
|
||||||
|
{
|
||||||
|
$price = $params['price'];
|
||||||
|
$ttc = isset($params['ttc']) && $params['ttc'] == true;
|
||||||
|
$context = Context::getContext();
|
||||||
|
$currency = $context->currency;
|
||||||
|
|
||||||
|
$taxeTag = $ttc ? ' TTC' : ' HT';
|
||||||
|
|
||||||
|
if (!is_numeric($price)) {
|
||||||
|
return $price;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($currency)) {
|
||||||
|
$c_char = $currency['sign'];
|
||||||
|
$c_format = $currency['format'];
|
||||||
|
$c_decimals = (int)$currency['decimals'] * _PS_PRICE_DISPLAY_PRECISION_;
|
||||||
|
$c_blank = $currency['blank'];
|
||||||
|
} elseif (is_object($currency)) {
|
||||||
|
$c_char = $currency->sign;
|
||||||
|
$c_format = $currency->format;
|
||||||
|
$c_decimals = (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_;
|
||||||
|
$c_blank = $currency->blank;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blank = ($c_blank ? ' ' : '');
|
||||||
|
$ret = 0;
|
||||||
|
if (($is_negative = ($price < 0))) {
|
||||||
|
$price *= -1;
|
||||||
|
}
|
||||||
|
$price = Tools::ps_round($price, $c_decimals);
|
||||||
|
|
||||||
|
if (($c_format == 2) && ($context->language->is_rtl == 1)) {
|
||||||
|
$c_format = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($c_format) {
|
||||||
|
/* X 0,000.00 */
|
||||||
|
case 1:
|
||||||
|
$ret = $c_char.$blank.number_format($price, $c_decimals, '.', ',');
|
||||||
|
break;
|
||||||
|
/* 0 000,00 X*/
|
||||||
|
case 2:
|
||||||
|
$ret = number_format($price, $c_decimals, ',', ' ').$blank.$c_char.'<sup>' . $taxeTag . '</sup>';
|
||||||
|
break;
|
||||||
|
/* X 0.000,00 */
|
||||||
|
case 3:
|
||||||
|
$ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.');
|
||||||
|
break;
|
||||||
|
/* 0,000.00 X */
|
||||||
|
case 4:
|
||||||
|
$ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char;
|
||||||
|
break;
|
||||||
|
/* X 0'000.00 Added for the switzerland currency */
|
||||||
|
case 5:
|
||||||
|
$ret = number_format($price, $c_decimals, '.', "'").$blank.$c_char;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($is_negative) {
|
||||||
|
$ret = '-'.$ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user