// 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
+242 -156
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
*