commit changes made during the last 2 months

This commit is contained in:
root 2017-01-26 10:34:09 +01:00
parent 58c8eb20c1
commit 2a5c988bce
29 changed files with 6589 additions and 66 deletions

View File

@ -266,6 +266,7 @@
</p>
{/if}
</div>
{*
<div class="panel">
<div class="panel-heading">
@ -302,6 +303,7 @@
</p>
{/if}
</div>
*}
{if $products AND count($products)}
<div class="panel">
<div class="panel-heading">

4346
cache/__class_index.php vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1251,6 +1251,7 @@ class CartCore extends ObjectModel
*/
public function deleteProduct($id_product, $id_product_attribute = null, $id_customization = null, $id_address_delivery = 0)
{
if (isset(self::$_nbProducts[$this->id])) {
unset(self::$_nbProducts[$this->id]);
}
@ -1262,18 +1263,18 @@ class CartCore extends ObjectModel
if ((int)$id_customization) {
$product_total_quantity = (int)Db::getInstance()->getValue(
'SELECT `quantity`
FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_product` = '.(int)$id_product.'
AND `id_cart` = '.(int)$this->id.'
AND `id_product_attribute` = '.(int)$id_product_attribute);
FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_product` = '.(int)$id_product.'
AND `id_cart` = '.(int)$this->id.'
AND `id_product_attribute` = '.(int)$id_product_attribute);
$customization_quantity = (int)Db::getInstance()->getValue('
SELECT `quantity`
FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.'
AND `id_product_attribute` = '.(int)$id_product_attribute.'
'.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
SELECT `quantity`
FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.'
AND `id_product_attribute` = '.(int)$id_product_attribute.'
'.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
if (!$this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute, (int)$id_address_delivery)) {
return false;
@ -1286,11 +1287,11 @@ class CartCore extends ObjectModel
/* Get customization quantity */
$result = Db::getInstance()->getRow('
SELECT SUM(`quantity`) AS \'quantity\'
FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.'
AND `id_product_attribute` = '.(int)$id_product_attribute);
SELECT SUM(`quantity`) AS \'quantity\'
FROM `'._DB_PREFIX_.'customization`
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.'
AND `id_product_attribute` = '.(int)$id_product_attribute);
if ($result === false) {
return false;
@ -1299,21 +1300,21 @@ class CartCore extends ObjectModel
/* If the product still possesses customization it does not have to be deleted */
if (Db::getInstance()->NumRows() && (int)$result['quantity']) {
return Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'cart_product`
SET `quantity` = '.(int)$result['quantity'].'
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.
UPDATE `'._DB_PREFIX_.'cart_product`
SET `quantity` = '.(int)$result['quantity'].'
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.
($id_product_attribute != null ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '')
);
}
/* Product deletion */
$result = Db::getInstance()->execute('
DELETE FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_product` = '.(int)$id_product.'
'.(!is_null($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
AND `id_cart` = '.(int)$this->id.'
'.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
DELETE FROM `'._DB_PREFIX_.'cart_product`
WHERE `id_product` = '.(int)$id_product.'
'.(!is_null($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
AND `id_cart` = '.(int)$this->id.'
'.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : ''));
if ($result) {
$return = $this->update();
@ -1339,8 +1340,8 @@ class CartCore extends ObjectModel
{
$result = true;
$customization = Db::getInstance()->getRow('SELECT *
FROM `'._DB_PREFIX_.'customization`
WHERE `id_customization` = '.(int)$id_customization);
FROM `'._DB_PREFIX_.'customization`
WHERE `id_customization` = '.(int)$id_customization);
if ($customization) {
$cust_data = Db::getInstance()->getRow('SELECT *
@ -1359,7 +1360,7 @@ class CartCore extends ObjectModel
if ($result) {
$result &= Db::getInstance()->execute(
'UPDATE `'._DB_PREFIX_.'cart_product`
'²TE `'._DB_PREFIX_.'cart_product`
SET `quantity` = `quantity` - '.(int)$customization['quantity'].'
WHERE `id_cart` = '.(int)$this->id.'
AND `id_product` = '.(int)$id_product.

View File

@ -148,6 +148,7 @@ class GroupReductionCore extends ObjectModel
FROM `'._DB_PREFIX_.'product_group_reduction_cache`
WHERE `id_product` = '.(int)$id_product.' AND `id_group` = '.(int)$id_group);
}
// Should return string (decimal in database) and not a float
return self::$reduction_cache[$id_product.'-'.$id_group];
}

View File

@ -337,12 +337,13 @@ class SpecificPriceCore extends ObjectModel
if (!SpecificPrice::isFeatureActive()) {
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 price must not change between the top and the bottom of the page
*/
//
// 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
//
$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)) {
$query_extra = self::computeExtraConditions($id_product, $id_product_attribute, $id_customer, $id_cart);
$query = '
@ -360,6 +361,7 @@ class SpecificPriceCore extends ObjectModel
SpecificPrice::$_specificPriceCache[$key] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query);
}
return SpecificPrice::$_specificPriceCache[$key];
}

View File

@ -418,6 +418,7 @@ abstract class DbCore
if (!$this->result && $this->getNumberError() == 2006) {
if ($this->connect()) {
$this->result = $this->_query($sql);
}
}

View File

@ -32,6 +32,11 @@ if (is_file($currentDir.'/defines_custom.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);
/* SSL configuration */

View File

@ -26,7 +26,12 @@
/* Debug only */
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 */
@ -40,7 +45,14 @@ if (_PS_MODE_DEV_ === true) {
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);
$currentDir = dirname(__FILE__);

View File

@ -1521,6 +1521,7 @@ class AdminOrdersControllerCore extends AdminController
$this->errors[] = Tools::displayError('You do not have permission to edit this.');
}
} elseif (Tools::getValue('syncherp') == 1) {
$id_order = Tools::getValue('id_order', false);
if ($id_order) {
$order = new Order((int)$id_order);
@ -1546,6 +1547,12 @@ class AdminOrdersControllerCore extends AdminController
if ($erporder) {
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.'"');
}
}
}

View File

@ -173,17 +173,19 @@ 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'].'")';
$d->execute($sql);
$tmp_path = _PS_TMP_IMG_DIR_.'odoo_tmp_image.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);
if (!empty($record['image'])) {
$tmp_path = _PS_TMP_IMG_DIR_.'odoo_tmp_image.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_.'*'));
}
array_map('unlink', glob(_PS_TMP_IMG_DIR_.'*'));
// set variant
foreach ($variants as $key => $variant) {

View File

@ -95,9 +95,60 @@ foreach ($ids_product as $key => $id) {
$d->execute($sql);
$sql = 'SELECT `id_product` FROM `'._DB_PREFIX_.'product` WHERE `id_erp` = '.pSQL($id);
$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) {
$id_variant = $variant['id'];

View 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 < && <=

View 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'),
),
);
}
?>

View 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>';
}
}
}
?>

View 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);
}
}
}

View File

@ -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
View 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&nbsp;MB', $bytes / 1048576);
} else {
if ($bytes > 1024) {
return sprintf('%.2f&nbsp;kB', $bytes / 1024);
} else {
return sprintf('%d&nbsp;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">&#10006; 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>

View File

@ -26,13 +26,13 @@ class Cart extends CartCore
// Build SELECT
$sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`,
pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`,
p.`id_manufacturer`, p.`nb_per_box`, p.`online_only`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`,
product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`,
stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`,
p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category,
CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery,
product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference');
pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`,
p.`id_manufacturer`, p.`nb_per_box`, p.`online_only`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`,
product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`,
stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`,
p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category,
CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery,
product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference');
// Build FROM
$sql->from('cart_product', 'cp');
@ -41,13 +41,13 @@ class Cart extends CartCore
$sql->leftJoin('product', 'p', 'p.`id_product` = cp.`id_product`');
$sql->innerJoin('product_shop', 'product_shop', '(product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)');
$sql->leftJoin('product_lang', 'pl', '
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop')
p.`id_product` = pl.`id_product`
AND pl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop')
);
$sql->leftJoin('category_lang', 'cl', '
product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop')
product_shop.`id_category_default` = cl.`id_category`
AND cl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop')
);
$sql->leftJoin('product_supplier', 'ps', 'ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`');
@ -76,21 +76,21 @@ class Cart extends CartCore
if (Combination::isFeatureActive()) {
$sql->select('
product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr,
IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference,
(p.`weight`+ pa.`weight`) weight_attribute,
IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13,
IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc,
IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity,
IF(product_attribute_shop.wholesale_price > 0, product_attribute_shop.wholesale_price, product_shop.`wholesale_price`) wholesale_price
');
product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr,
IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference,
(p.`weight`+ pa.`weight`) weight_attribute,
IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13,
IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc,
IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity,
IF(product_attribute_shop.wholesale_price > 0, product_attribute_shop.wholesale_price, product_shop.`wholesale_price`) wholesale_price
');
$sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cp.`id_product_attribute`');
$sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cp.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)');
} else {
$sql->select(
'p.`reference` AS reference, p.`ean13`,
p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity, product_shop.`wholesale_price` wholesale_price'
p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity, product_shop.`wholesale_price` wholesale_price'
);
}
@ -100,6 +100,7 @@ class Cart extends CartCore
$result = Db::getInstance()->executeS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries
$products_ids = array();
$pa_ids = array();

View File

@ -56,5 +56,4 @@ class Category extends CategoryCore
return $categories;
}
}

View 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();
}
}

View File

@ -4,6 +4,7 @@ class CartController extends CartControllerCore
{
protected function processChangeProductInCart()
{
$mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';
if ($this->qty == 0) {
@ -89,10 +90,11 @@ class CartController extends CartControllerCore
if(!Tools::getIsset('summary'))
{
$this->context->cart->deleteProduct($this->id_product, $this->id_product_attribute, $this->customization_id);
$this->context->cart->deleteProduct($this->id_product, $this->id_product_attribute, $this->customization_id);
}
$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 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;

View File

@ -155,7 +155,7 @@ var ajaxCart = {
// add a product in the cart via ajax
add : function(idProduct, idCombination, addedFromListing, callerElement, quantity){
emptyCustomizations();
$(callerElement).prop('disabled', 'disabled');

View 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;
}
}
}
}
}

View 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>";
}
}
}
}

View 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;

View 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();

View File

@ -0,0 +1,3 @@
<?php
require_once(__DIR__.'/debug/AntDebug.php');

View 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;

View File

@ -113,4 +113,77 @@ class Tools extends ToolsCore
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;
}
}