// Refactoring of Hook class

git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@11998 b9a71923-0436-4b27-9f14-aed3839534dd
This commit is contained in:
rMalie
2012-01-02 14:42:05 +00:00
parent d56b86297c
commit 50e4dff4e5
8 changed files with 457 additions and 319 deletions

View File

@@ -74,8 +74,6 @@ abstract class ControllerCore
protected $redirect_after = null;
/** hook_list is used with liveEdit */
public $hook_list = array();
/**
* check that the controller is available for the current user/visitor
*/

View File

@@ -476,9 +476,7 @@ class FrontControllerCore extends Controller
));
if (Tools::isSubmit('live_edit'))
{
$this->context->smarty->assign('live_edit', $this->getLiveEditFooter());
}
// handle 1.4 theme (with layout.tpl missing)
if (file_exists(_PS_THEME_DIR_.'layout.tpl'))
@@ -659,7 +657,8 @@ class FrontControllerCore extends Controller
}
public function getLiveEditFooter(){
public function getLiveEditFooter()
{
if (Tools::isSubmit('live_edit')
&& ($ad = Tools::getValue('ad'))
&& (Tools::getValue('liveToken') == sha1(Tools::getValue('ad')._COOKIE_KEY_))
@@ -669,7 +668,7 @@ class FrontControllerCore extends Controller
$data->assign(array(
'ad' => $ad,
'live_edit' => true,
'hook_list' => $this->hook_list,
'hook_list' => Hook::$executed_hooks,
'id_shop' => $this->context->shop->getId(true)
));
return $this->context->smarty->createTemplate(_PS_ALL_THEMES_DIR_.'live_edit.tpl', $data)->fetch();

View File

@@ -52,6 +52,11 @@ class HookCore extends ObjectModel
*/
public $live_edit = false;
/**
* @var array List of executed hooks on this page
*/
public static $executed_hooks = array();
/**
* @see ObjectModel::$definition
*/
@@ -67,58 +72,40 @@ class HookCore extends ObjectModel
),
);
/** @var array Cache Var */
/**
* @deprecated 1.5.0
*/
protected static $_hook_modules_cache = null;
/**
* @deprecated 1.5.0
*/
protected static $_hook_modules_cache_exec = null;
static $_hook_alias = null;
/**
* Preload hook alias list
* Return Hooks List
*
* @return boolean preload_needed
* @param bool $position
* @return array Hooks List
*/
public static function preloadHookAlias()
public static function getHooks($position = false)
{
if (!is_null(self::$_hook_alias))
return false;
self::$_hook_alias = array();
$hook_alias_list = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'hook_alias`');
if ($hook_alias_list)
foreach ($hook_alias_list as $ha)
self::$_hook_alias[strtolower($ha['alias'])] = $ha['name'];
return true;
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT * FROM `'._DB_PREFIX_.'hook` h
'.($position ? 'WHERE h.`position` = 1' : '')
);
}
/**
* Return retrocompatible hook name
*
* @param string $hook_name Hook name
* @return integer Hook ID
*/
public static function getRetroHookName($hook_name)
{
$retro_hook_name = '';
self::preloadHookAlias();
if (isset(self::$_hook_alias[strtolower($hook_name)]))
$retro_hook_name = self::$_hook_alias[strtolower($hook_name)];
foreach (self::$_hook_alias as $alias => $name)
if ($hook_name == $name)
return $alias;
return $retro_hook_name;
}
/**
* Return hook ID from name
*
* @param string $hook_name Hook name
* @return integer Hook ID
* @return int Hook ID
*/
public static function getIdByName($hook_name)
{
if (!Validate::isHookName($hook_name))
die(Tools::displayError());
if (!Validate::isHookName($hook_name))
throw new PrestashopException('Invalid hook name');
$cache_id = 'hook_idbyname_'.$hook_name;
if (!Cache::isStored($cache_id))
@@ -136,95 +123,189 @@ class HookCore extends ObjectModel
}
/**
* Return Hooks List
* Get list of hook alias
*
* @param integer $position
* @return array Hooks List
* @since 1.5.0
* @return array
*/
public static function getHooks($position = false)
public static function getHookAliasList()
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT * FROM `'._DB_PREFIX_.'hook` h
'.($position ? 'WHERE h.`position` = 1' : ''));
}
/**
* Preload hook modules cache
*
* @return boolean preload_needed
*/
public static function preloadHookModulesCache()
{
if (!is_null(self::$_hook_modules_cache))
return false;
self::$_hook_modules_cache = array();
$sql = 'SELECT h.id_hook, h.name as h_name, title, description, h.position, live_edit, hm.position as hm_position, m.id_module, m.name, active
FROM `'._DB_PREFIX_.'hook` h
INNER JOIN `'._DB_PREFIX_.'hook_module` hm ON (h.id_hook = hm.id_hook)
INNER JOIN `'._DB_PREFIX_.'module` as m ON (m.id_module = hm.id_module)
WHERE hm.id_shop IN('.implode(', ', Context::getContext()->shop->getListOfID()).')
GROUP BY hm.id_hook, hm.id_module
ORDER BY hm.position';
$results = Db::getInstance()->executeS($sql);
foreach ($results as $result)
$cache_id = 'hook_alias';
if (!Cache::isStored($cache_id))
{
if (!isset(self::$_hook_modules_cache[$result['id_hook']]))
self::$_hook_modules_cache[$result['id_hook']] = array();
self::$_hook_modules_cache[$result['id_hook']][$result['id_module']] = array(
'id_hook' => $result['id_hook'],
'title' => $result['title'],
'description' => $result['description'],
'hm.position' => $result['position'],
'live_edit' => $result['live_edit'],
'm.position' => $result['hm_position'],
'id_module' => $result['id_module'],
'name' => $result['name'],
'active' => $result['active'],
);
$hook_alias_list = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'hook_alias`');
$hook_alias = array();
if ($hook_alias_list)
foreach ($hook_alias_list as $ha)
$hook_alias[strtolower($ha['alias'])] = $ha['name'];
Cache::store($cache_id, $hook_alias);
}
return true;
return Cache::retrieve($cache_id);
}
/**
* Return retrocompatible hook name
*
* @since 1.5.0
* @param string $hook_name Hook name
* @return int Hook ID
*/
public static function getRetroHookName($hook_name)
{
$alias_list = Hook::getHookAliasList();
if (isset($alias_list[strtolower($hook_name)]))
return $alias_list[strtolower($hook_name)];
$retro_hook_name = array_search($hook_name, $alias_list);
if ($retro_hook_name === false)
return '';
return $retro_hook_name;
}
/**
* Get list of all registered hooks with modules
*
* @since 1.5.0
* @return array
*/
public static function getHookModuleList()
{
$cache_id = 'hook_module_list';
if (!Cache::isStored($cache_id))
{
$sql = 'SELECT h.id_hook, h.name as h_name, title, description, h.position, live_edit, hm.position as hm_position, m.id_module, m.name, active
FROM `'._DB_PREFIX_.'hook` h
INNER JOIN `'._DB_PREFIX_.'hook_module` hm ON (h.id_hook = hm.id_hook)
INNER JOIN `'._DB_PREFIX_.'module` as m ON (m.id_module = hm.id_module)
WHERE hm.id_shop IN('.implode(', ', Context::getContext()->shop->getListOfID()).')
GROUP BY hm.id_hook, hm.id_module
ORDER BY hm.position';
$results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
$list = array();
foreach ($results as $result)
{
if (!isset($list[$result['id_hook']]))
$list[$result['id_hook']] = array();
$list[$result['id_hook']][$result['id_module']] = array(
'id_hook' => $result['id_hook'],
'title' => $result['title'],
'description' => $result['description'],
'hm.position' => $result['position'],
'live_edit' => $result['live_edit'],
'm.position' => $result['hm_position'],
'id_module' => $result['id_module'],
'name' => $result['name'],
'active' => $result['active'],
);
}
Cache::store($cache_id, $list);
// @todo remove this in 1.6, we keep it in 1.5 for retrocompatibility
Hook::$_hook_modules_cache = $list;
}
return Cache::retrieve($cache_id);
}
/**
* Return Hooks List
*
* @param integer $hookID
* @param integer $moduleID (optionnal)
* @since 1.5.0
* @param int $id_hook
* @param int $id_module
* @return array Modules List
*/
public static function getModulesFromHook($hookID, $moduleID = null)
public static function getModulesFromHook($id_hook, $id_module = null)
{
Hook::preloadHookModulesCache();
$hm_list = Hook::getHookModuleList();
$module_list = (isset($hm_list[$id_hook])) ? $hm_list[$id_hook] : array();
$list = (isset(self::$_hook_modules_cache[$hookID])) ? self::$_hook_modules_cache[$hookID] : array();
if ($moduleID)
return (isset($list[$moduleID])) ? array($list[$moduleID]) : array();
return $list;
if ($id_module)
return (isset($module_list[$id_module])) ? array($module_list[$id_module]) : array();
return $module_list;
}
/**
* Get Hook Module Cache Exec, testing hook name and retrocompatible hook name
* Get list of modules we can execute per hook
*
* @param string $hook_name Hook Name
* @param string $retro_hook_name Retrocompatible Hook Name
* @return string cache
* @since 1.5.0
* @param string $hook_name Get list of modules for this hook if given
* @return array
*/
public static function getHookModulesCacheExec($hook_name, $retro_hook_name)
public static function getHookModuleExecList($hook_name = null)
{
$hook_name = strtolower($hook_name);
$retro_hook_name = strtolower($retro_hook_name);
$context = Context::getContext();
$cache_id = 'hook_module_exec_list'.((isset($context->customer)) ? '_'.$context->customer->id : '');
if (!Cache::isStored($cache_id))
{
// Get shops and groups list
$shop_list = $context->shop->getListOfID();
if (isset($context->customer) && $context->customer->isLogged())
$groups = $context->customer->getGroups();
$return = array();
if (isset(self::$_hook_modules_cache_exec[$hook_name]))
$return = array_merge((array)$return, (array)self::$_hook_modules_cache_exec[$hook_name]);
if (isset(self::$_hook_modules_cache_exec[$retro_hook_name]))
$return = array_merge((array)$return, (array)self::$_hook_modules_cache_exec[$retro_hook_name]);
// SQL Request
$sql = new DbQuery();
$sql->select('h.`name` as hook, m.`id_module`, h.`id_hook`, m.`name` as module, h.`live_edit`');
$sql->from('module', 'm');
$sql->leftJoin('hook_module', 'hm', 'hm.`id_module` = m.`id_module`');
$sql->leftJoin('hook', 'h', 'hm.`id_hook` = h.`id_hook`');
$sql->where('(SELECT COUNT(*) FROM '._DB_PREFIX_.'module_shop ms WHERE ms.id_module = m.id_module AND ms.id_shop IN('.implode(', ', $shop_list).')) = '.count($shop_list));
$sql->where('hm.id_shop IN('.implode(', ', $shop_list).')');
if (count($return) > 0)
return $return;
return false;
if (isset($context->customer) && $context->customer->isLogged())
{
$sql->leftJoin('module_group', 'mg', 'mg.`id_module` = m.`id_module`');
$sql->where('mg.`id_group` IN('.implode(', ', $groups).')');
}
$sql->groupBy('hm.id_hook, hm.id_module');
$sql->orderBy('hm.`position`');
// Store results per hook name
$results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
$list = array();
if ($results)
foreach ($results as $row)
{
$row['hook'] = strtolower($row['hook']);
if (!isset($list[$row['hook']]))
$list[$row['hook']] = array();
$list[$row['hook']][] = array(
'id_hook' => $row['id_hook'],
'module' => $row['module'],
'id_module' => $row['id_module'],
'live_edit' => $row['live_edit'],
);
}
Cache::store($cache_id, $list);
// @todo remove this in 1.6, we keep it in 1.5 for retrocompatibility
self::$_hook_modules_cache_exec = $list;
}
else
$list = Cache::retrieve($cache_id);
// If hook_name is given, just get list of modules for this hook
if ($hook_name)
{
$retro_hook_name = Hook::getRetroHookName($hook_name);
$hook_name = strtolower($hook_name);
$return = array();
if (isset($list[$hook_name]))
$return = $list[$hook_name];
if (isset($list[$retro_hook_name]))
$return = array_merge($return, $list[$retro_hook_name]);
if (count($return) > 0)
return $return;
return false;
}
else
return $list;
}
/**
@@ -232,26 +313,23 @@ class HookCore extends ObjectModel
*
* @param string $hook_name Hook Name
* @param array $hookArgs Parameters for the functions
* @param int $id_module Execute hook for this module only
* @return string modules output
*/
public static function exec($hook_name, $hookArgs = array(), $id_module = NULL)
public static function exec($hook_name, $hookArgs = array(), $id_module = null)
{
// Check errors
// Check arguments validity
$context = Context::getContext();
if ((!empty($id_module) && !Validate::isUnsignedId($id_module)) || !Validate::isHookName($hook_name))
die(Tools::displayError());
if (($id_module && !Validate::isUnsignedId($id_module)) || !Validate::isHookName($hook_name))
throw new PrestashopException('Invalid id_module or hook_name');
// Check if hook exists
if (!Hook::getIdByName($hook_name))
if (!$id_hook = Hook::getIdByName($hook_name))
return false;
// Get retrocompatible hook name
$retro_hook_name = Hook::getRetroHookName($hook_name);
// Hook list for live edit
$ctrl = $context->controller;
if ($ctrl && !in_array($hook_name, $ctrl->hook_list));
$context->controller->hook_list[Hook::getIdByName($hook_name)] = $hook_name;
// Store list of executed hooks on this page
Hook::$executed_hooks[$id_hook] = $hook_name;
$live_edit = false;
if (!isset($hookArgs['cookie']) || !$hookArgs['cookie'])
@@ -259,53 +337,14 @@ class HookCore extends ObjectModel
if (!isset($hookArgs['cart']) || !$hookArgs['cart'])
$hookArgs['cart'] = $context->cart;
// If hook modules cache exec is empty, we load it
if (!isset(self::$_hook_modules_cache_exec))
{
// Get shops and groups list
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);
$list = $context->shop->getListOfID();
if (isset($context->customer) && $context->customer->isLogged())
$groups = $context->customer->getGroups();
// SQL Request
$sql = 'SELECT h.`name` as hook, m.`id_module`, h.`id_hook`, m.`name` as module, h.`live_edit`
FROM `'._DB_PREFIX_.'module` m
LEFT JOIN `'._DB_PREFIX_.'hook_module` hm ON hm.`id_module` = m.`id_module`';
if (isset($context->customer) && $context->customer->isLogged())
$sql .= 'LEFT JOIN `'._DB_PREFIX_.'module_group` mg ON mg.`id_module` = m.`id_module`';
$sql .= 'LEFT JOIN `'._DB_PREFIX_.'hook` h ON hm.`id_hook` = h.`id_hook`
WHERE (SELECT COUNT(*) FROM '._DB_PREFIX_.'module_shop ms WHERE ms.id_module = m.id_module AND ms.id_shop IN('.implode(', ', $list).')) = '.count($list).'
AND hm.id_shop IN('.implode(', ', $list).')';
if (isset($context->customer) && $context->customer->isLogged())
$sql .= 'AND (mg.`id_group` IN('.implode(', ', $groups).'))';
$sql .= 'GROUP BY hm.id_hook, hm.id_module
ORDER BY hm.`position`';
$results = $db->executeS($sql);
// Init cache var
self::$_hook_modules_cache_exec = array();
if ($results)
foreach ($results as $row)
{
$row['hook'] = strtolower($row['hook']);
if (!isset(self::$_hook_modules_cache_exec[$row['hook']]))
self::$_hook_modules_cache_exec[$row['hook']] = array();
self::$_hook_modules_cache_exec[$row['hook']][] = array('id_hook' => $row['id_hook'], 'module' => $row['module'], 'id_module' => $row['id_module'], 'live_edit' => $row['live_edit']);
}
}
// If no modules associated to hook_name or recompatible hook name, we stop the function
if (Hook::getHookModulesCacheExec($hook_name, $retro_hook_name) === false)
if (!$module_list = Hook::getHookModuleExecList($hook_name))
return '';
// We load the cache of the hook
$hookModulesCache = Hook::getHookModulesCacheExec($hook_name, $retro_hook_name);
// Look on modules list
$altern = 0;
$output = '';
foreach ($hookModulesCache as $array)
foreach ($module_list as $array)
{
// Check errors
if ($id_module && $id_module != $array['id_module'])
@@ -358,8 +397,14 @@ class HookCore extends ObjectModel
<a class="exclusive" href="#">Add a module</a></div>--><div id="'.$hook_name.'" class="dndHook" style="min-height:50px">' : '').$output.($live_edit ? '</div>' : '');
}
/**
* @deprecated 1.5.0
*/
public static function updateOrderStatus($newOrderStatusId, $id_order)
{
Tools::displayAsDeprecated();
$order = new Order((int)($id_order));
$newOS = new OrderState((int)($newOrderStatusId), $order->id_lang);
@@ -368,16 +413,24 @@ class HookCore extends ObjectModel
return $return;
}
/**
* @deprecated 1.5.0
*/
public static function postUpdateOrderStatus($newOrderStatusId, $id_order)
{
Tools::displayAsDeprecated();
$order = new Order((int)($id_order));
$newOS = new OrderState((int)($newOrderStatusId), $order->id_lang);
$return = Hook::exec('postUpdateOrderStatus', array('newOrderStatus' => $newOS, 'id_order' => (int)($order->id)));
return $return;
}
/**
* @deprecated 1.5.0
*/
public static function orderConfirmation($id_order)
{
Tools::displayAsDeprecated();
if (Validate::isUnsignedId($id_order))
{
$params = array();
@@ -398,8 +451,12 @@ class HookCore extends ObjectModel
return false;
}
/**
* @deprecated 1.5.0
*/
public static function paymentReturn($id_order, $id_module)
{
Tools::displayAsDeprecated();
if (Validate::isUnsignedId($id_order) AND Validate::isUnsignedId($id_module))
{
$params = array();
@@ -420,28 +477,57 @@ class HookCore extends ObjectModel
return false;
}
/**
* @deprecated 1.5.0
*/
public static function PDFInvoice($pdf, $id_order)
{
Tools::displayAsDeprecated();
if (!is_object($pdf) OR !Validate::isUnsignedId($id_order))
return false;
return Hook::exec('PDFInvoice', array('pdf' => $pdf, 'id_order' => $id_order));
}
/**
* @deprecated 1.5.0
*/
public static function backBeforePayment($module)
{
Tools::displayAsDeprecated();
$params['module'] = strval($module);
if (!$params['module'])
return false;
return Hook::exec('backBeforePayment', $params);
}
/**
* @deprecated 1.5.0
*/
public static function updateCarrier($id_carrier, $carrier)
{
if (!Validate::isUnsignedId($id_carrier) OR !is_object($carrier))
Tools::displayAsDeprecated();
if (!Validate::isUnsignedId($id_carrier) || !is_object($carrier))
return false;
return Hook::exec('updateCarrier', array('id_carrier' => $id_carrier, 'carrier' => $carrier));
}
/**
* Preload hook modules cache
*
* @deprecated 1.5.0 use Hook::getHookModuleList() instead
* @return boolean preload_needed
*/
public static function preloadHookModulesCache()
{
Tools::displayAsDeprecated();
if (!is_null(self::$_hook_modules_cache))
return false;
self::$_hook_modules_cache = Hook::getHookModuleList();
return true;
}
/**
* Return hook ID from name
*

View File

@@ -584,28 +584,26 @@ abstract class ModuleCore
{
// Check hook name validation and if module is installed
if (!Validate::isHookName($hook_name))
die(Tools::displayError());
if (!isset($this->id) OR !is_numeric($this->id))
throw new PrestashopException('Invalid hook name');
if (!isset($this->id) || !is_numeric($this->id))
return false;
// Retrocompatibility
Hook::preloadHookAlias();
if (isset(Hook::$_hook_alias[strtolower($hook_name)]))
$hook_name = Hook::$_hook_alias[strtolower($hook_name)];
if ($alias = Hook::getRetroHookName($hook_name))
$hook_name = $alias;
// Get hook id
$sql = 'SELECT `id_hook` FROM `'._DB_PREFIX_.'hook` WHERE `name` = \''.pSQL($hook_name).'\'';
$hookID = Db::getInstance()->getValue($sql);
$id_hook = Hook::getIdByName($hook_name);
// If hook does not exist, we create it
if (!$hookID)
if (!$id_hook)
{
$newHook = new Hook();
$newHook->name = pSQL($hook_name);
$newHook->title = pSQL($hook_name);
$newHook->add();
$hookID = $newHook->id;
if (!$hookID)
$new_hook = new Hook();
$new_hook->name = pSQL($hook_name);
$new_hook->title = pSQL($hook_name);
$new_hook->add();
$id_hook = $new_hook->id;
if (!$id_hook)
return false;
}
@@ -619,7 +617,7 @@ abstract class ModuleCore
// Check if already register
$sql = 'SELECT hm.`id_module`
FROM `'._DB_PREFIX_.'hook_module` hm, `'._DB_PREFIX_.'hook` h
WHERE hm.`id_module` = '.(int)($this->id).' AND h.`id_hook` = '.$hookID.'
WHERE hm.`id_module` = '.(int)($this->id).' AND h.`id_hook` = '.$id_hook.'
AND h.`id_hook` = hm.`id_hook` AND `id_shop` = '.(int)($shopID);
if (Db::getInstance()->getRow($sql))
continue;
@@ -627,14 +625,14 @@ abstract class ModuleCore
// Get module position in hook
$sql = 'SELECT MAX(`position`) AS position
FROM `'._DB_PREFIX_.'hook_module`
WHERE `id_hook` = '.(int)$hookID.' AND `id_shop` = '.(int)$shopID;
WHERE `id_hook` = '.(int)$id_hook.' AND `id_shop` = '.(int)$shopID;
if (!$position = Db::getInstance()->getValue($sql))
$position = 0;
// Register module in hook
$return &= Db::getInstance()->autoExecute(_DB_PREFIX_.'hook_module', array(
'id_module' => (int)$this->id,
'id_hook' => (int)$hookID,
'id_hook' => (int)$id_hook,
'id_shop' => (int)$shopID,
'position' => (int)($position + 1),
), 'INSERT');
@@ -646,7 +644,7 @@ abstract class ModuleCore
/**
* Unregister module from hook
*
* @param int $id_hook Hook id (can be a hook name since 1.5.0)
* @param mixed $id_hook Hook id (can be a hook name since 1.5.0)
* @param array $shopList List of shop
* @return boolean result
*/
@@ -656,15 +654,7 @@ abstract class ModuleCore
if (!is_numeric($hook_id))
{
// Retrocompatibility
Hook::preloadHookAlias();
if (isset(Hook::$_hook_alias[strtolower($hook_id)]))
$hook_id = Hook::$_hook_alias[strtolower($hook_id)];
// Unregister module on hook by name
$sql = 'SELECT `id_hook`
FROM `'._DB_PREFIX_.'hook`
WHERE `name` = \''.pSQL($hook_id).'\'';
$hook_id = Db::getInstance()->getValue($sql);
$hook_id = Hook::getIdByName($hook_id);
if (!$hook_id)
return false;
}
@@ -738,14 +728,14 @@ abstract class ModuleCore
* @param array $excepts List of shopID and file name
* @return boolean result
*/
public function editExceptions($hookID, $excepts)
public function editExceptions($id_hook, $excepts)
{
$result = true;
foreach ($excepts as $shopID => $except)
{
$shopList = ($shopID == 0) ? Context::getContext()->shop->getListOfID() : array($shopID);
$this->unregisterExceptions($hookID, $shopList);
$result &= $this->registerExceptions($hookID, $except, $shopList);
$this->unregisterExceptions($id_hook, $shopList);
$result &= $this->registerExceptions($id_hook, $except, $shopList);
}
return $result;
@@ -1165,7 +1155,6 @@ abstract class ModuleCore
public static function getPaymentModules()
{
$context = Context::getContext();
$id_customer = $context->customer->id;
$billing = new Address((int)$context->cart->id_address_invoice);
if (isset($context->customer))
$groups = $context->customer->getGroups();

View File

@@ -67,140 +67,153 @@ class OrderHistoryCore extends ObjectModel
public function changeIdOrderState($new_order_state, $id_order)
{
if ($new_order_state != NULL)
{
Hook::updateOrderStatus((int)($new_order_state), (int)$id_order);
$order = new Order((int)($id_order));
if (!$new_order_state)
return;
/* Best sellers */
$newOS = new OrderState((int)($new_order_state), $order->id_lang);
$oldOrderStatus = OrderHistory::getLastOrderState((int)$id_order);
$isValidated = $this->isValidated();
if (Validate::isLoadedObject($order))
foreach ($order->getProductsDetail() as $product)
$order = new Order($id_order);
$newOS = new OrderState((int)$new_order_state, $order->id_lang);
// Execute pre hooks
if ($newOS->id == Configuration::get('PS_OS_PAYMENT'))
Hook::exec('actionPaymentConfirmation', array(
'id_order' => (int)$order->id
));
Hook::exec('actionOrderStatusUpdate', array(
'newOrderStatus' => $newOS,
'id_order' => (int)$order->id
));
$oldOrderStatus = OrderHistory::getLastOrderState((int)$id_order);
$isValidated = $this->isValidated();
if (Validate::isLoadedObject($order))
foreach ($order->getProductsDetail() as $product)
{
/* If becoming logable => adding sale */
if ($newOS->logable
&& !($oldOrderStatus instanceof OrderState
&& $oldOrderStatus->logable))
{
/* If becoming logable => adding sale */
if ($newOS->logable
&& !($oldOrderStatus instanceof OrderState
&& $oldOrderStatus->logable))
{
ProductSale::addProductSale($product['product_id'], $product['product_quantity']);
}
/* If becoming unlogable => removing sale */
else if (!$newOS->logable
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->logable)
{
ProductSale::removeProductSale($product['product_id'], $product['product_quantity']);
// @since 1.5.0
if ($newOS->id == Configuration::get('PS_OS_ERROR') || $newOS->id == Configuration::get('PS_OS_CANCELED'))
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['product_quantity'], $order->id_shop);
}
if ((!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') || (int)$product['advanced_stock_management'] != 1)
&& !$isValidated
&& $newOS->logable
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->id == Configuration::get('PS_OS_ERROR')
)
ProductSale::addProductSale($product['product_id'], $product['product_quantity']);
}
/* If becoming unlogable => removing sale */
else if (!$newOS->logable
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->logable)
{
ProductSale::removeProductSale($product['product_id'], $product['product_quantity']);
// @since 1.5.0
if ($newOS->id == Configuration::get('PS_OS_ERROR') || $newOS->id == Configuration::get('PS_OS_CANCELED'))
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['product_quantity'], $order->id_shop);
// If order is shipped for the first time and
// if we use advanced stock management system, decrement stock preperly.
// The product is removed from the physical stock. $id_warehouse is needed
// @TODO Checks $id_warehouse
else if ($newOS->shipped == 1
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->shipped == 0
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
&& (int)$product['advanced_stock_management'] == 1)
{
$manager = StockManagerFactory::getManager();
$warehouse = new Warehouse($product['id_warehouse']);
$manager->removeProduct(
$product['product_id'],
$product['product_attribute_id'],
$warehouse,
$product['product_quantity'],
Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'),
true,
(int)$id_order
);
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
StockAvailable::synchronize($product['product_id']);
else
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop);
}
else if ($newOS->shipped == 0
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->shipped == 1
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
&& (int)$product['advanced_stock_management'] == 1
)
{
$manager = StockManagerFactory::getManager();
$mvts = StockMvt::getNegativeStockMvts($order->id, $product['product_id'], $product['product_attribute_id'], $product['product_quantity']);
foreach ($mvts as $mvt)
{
$manager->addProduct(
$product['product_id'],
$product['product_attribute_id'],
new Warehouse($mvt['id_warehouse']),
$mvt['physical_quantity'],
null,
$mvt['price_te'],
true
);
}
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
StockAvailable::synchronize($product['product_id']);
else
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['physical_quantity'], $order->id_shop);
}
}
$this->id_order_state = (int)($new_order_state);
/* Change invoice number of order ? */
if (!Validate::isLoadedObject($newOS) OR !Validate::isLoadedObject($order))
die(Tools::displayError('Invalid new order state'));
/* The order is valid only if the invoice is available and the order is not cancelled */
$order->valid = $newOS->logable;
$order->update();
if ($newOS->invoice AND !$order->invoice_number)
$order->setInvoice();
// Set order as paid
if ($newOS->paid == 1)
{
$invoices = $order->getInvoicesCollection();
$payment_method = Module::getInstanceByName($order->module);
foreach ($invoices as $invoice)
if ((!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') || (int)$product['advanced_stock_management'] != 1)
&& !$isValidated
&& $newOS->logable
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->id == Configuration::get('PS_OS_ERROR')
)
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['product_quantity'], $order->id_shop);
// If order is shipped for the first time and
// if we use advanced stock management system, decrement stock preperly.
// The product is removed from the physical stock. $id_warehouse is needed
// @TODO Checks $id_warehouse
else if ($newOS->shipped == 1
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->shipped == 0
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
&& (int)$product['advanced_stock_management'] == 1)
{
$rest_paid = $invoice->getRestPaid();
if ($rest_paid)
$manager = StockManagerFactory::getManager();
$warehouse = new Warehouse($product['id_warehouse']);
$manager->removeProduct(
$product['product_id'],
$product['product_attribute_id'],
$warehouse,
$product['product_quantity'],
Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'),
true,
(int)$id_order
);
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
StockAvailable::synchronize($product['product_id']);
else
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop);
}
else if ($newOS->shipped == 0
&& $oldOrderStatus instanceof OrderState
&& $oldOrderStatus->shipped == 1
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
&& (int)$product['advanced_stock_management'] == 1
)
{
$manager = StockManagerFactory::getManager();
$mvts = StockMvt::getNegativeStockMvts($order->id, $product['product_id'], $product['product_attribute_id'], $product['product_quantity']);
foreach ($mvts as $mvt)
{
$payment = new OrderPayment();
$payment->id_order = $order->id;
$payment->id_order_invoice = $invoice->id;
$payment->id_currency = $order->id_currency;
$payment->amount = $rest_paid;
$payment->payment_method = $payment_method->displayName;
$payment->conversion_rate = 1;
$payment->save();
$manager->addProduct(
$product['product_id'],
$product['product_attribute_id'],
new Warehouse($mvt['id_warehouse']),
$mvt['physical_quantity'],
null,
$mvt['price_te'],
true
);
}
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
StockAvailable::synchronize($product['product_id']);
else
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['physical_quantity'], $order->id_shop);
}
}
// Update delivery date even if it was already set by another state change
if ($newOS->delivery)
$order->setDelivery();
Hook::postUpdateOrderStatus((int)($new_order_state), (int)($id_order));
$this->id_order_state = (int)($new_order_state);
/* Change invoice number of order ? */
if (!Validate::isLoadedObject($newOS) OR !Validate::isLoadedObject($order))
die(Tools::displayError('Invalid new order state'));
/* The order is valid only if the invoice is available and the order is not cancelled */
$order->valid = $newOS->logable;
$order->update();
if ($newOS->invoice AND !$order->invoice_number)
$order->setInvoice();
// Set order as paid
if ($newOS->paid == 1)
{
$invoices = $order->getInvoicesCollection();
$payment_method = Module::getInstanceByName($order->module);
foreach ($invoices as $invoice)
{
$rest_paid = $invoice->getRestPaid();
if ($rest_paid)
{
$payment = new OrderPayment();
$payment->id_order = $order->id;
$payment->id_order_invoice = $invoice->id;
$payment->id_currency = $order->id_currency;
$payment->amount = $rest_paid;
$payment->payment_method = $payment_method->displayName;
$payment->conversion_rate = 1;
$payment->save();
}
}
}
// Update delivery date even if it was already set by another state change
if ($newOS->delivery)
$order->setDelivery();
Hook::exec('actionOrderStatusPostUpdate', array(
'newOrderStatus' => $newOS,
'id_order' => (int)$order->id,
));
}
public static function getLastOrderState($id_order)

View File

@@ -474,7 +474,10 @@ class AdminCarriersControllerCore extends AdminController
if (Validate::isLoadedObject($object_new))
{
$this->afterDelete($object_new, $object->id);
Hook::updateCarrier((int)$object->id, $object_new);
Hook::exec('actionCarrierUpdate', array(
'id_carrier' => (int)$object->id,
'carrier' => $object_new,
));
}
$this->changeGroups($object_new->id);
if (!$result)

View File

@@ -72,8 +72,8 @@ class OrderConfirmationControllerCore extends FrontController
{
$this->context->smarty->assign(array(
'is_guest' => $this->context->customer->is_guest,
'HOOK_ORDER_CONFIRMATION' => Hook::orderConfirmation((int)($this->id_order)),
'HOOK_PAYMENT_RETURN' => Hook::paymentReturn((int)($this->id_order), (int)($this->id_module))
'HOOK_ORDER_CONFIRMATION' => $this->displayOrderConfirmation(),
'HOOK_PAYMENT_RETURN' => $this->displayPaymentReturn()
));
if ($this->context->customer->is_guest)
@@ -89,5 +89,55 @@ class OrderConfirmationControllerCore extends FrontController
$this->setTemplate(_PS_THEME_DIR_.'order-confirmation.tpl');
parent::initContent();
}
/**
* Execute the hook displayPaymentReturn
*/
public function displayPaymentReturn()
{
if (Validate::isUnsignedId($this->id_order) && Validate::isUnsignedId($this->id_module))
{
$params = array();
$order = new Order($this->id_order);
$currency = new Currency($order->id_currency);
if (Validate::isLoadedObject($order))
{
$cart = new Cart((int)$order->id_cart);
$params['total_to_pay'] = $cart->getOrderTotal();
$params['currency'] = $currency->sign;
$params['objOrder'] = $order;
$params['currencyObj'] = $currency;
return Hook::exec('displayPaymentReturn', $params, $this->id_module);
}
}
return false;
}
/**
* Execute the hook displayOrderConfirmation
*/
public function displayOrderConfirmation()
{
if (Validate::isUnsignedId($this->id_order))
{
$params = array();
$order = new Order($this->id_order);
$currency = new Currency($order->id_currency);
if (Validate::isLoadedObject($order))
{
$cart = new Cart($order->id_cart);
$params['total_to_pay'] = $cart->getOrderTotal();
$params['currency'] = $currency->sign;
$params['objOrder'] = $order;
$params['currencyObj'] = $currency;
return Hook::exec('displayOrderConfirmation', $params);
}
}
return false;
}
}

View File

@@ -295,7 +295,7 @@ class OrderControllerCore extends ParentOrderController
global $orderTotal;
// Redirect instead of displaying payment modules if any module are grefted on
Hook::backBeforePayment('order.php?step=3');
Hook::exec('displayBeforePayment', array('module' => 'order.php?step=3'));
/* We may need to display an order summary */
$this->context->smarty->assign($this->context->cart->getSummaryDetails());