/** * Execute modules for specified hook * * @param string $hook_name Hook Name * @param array $hook_args Parameters for the functions * @param int $id_module Execute hook for this module only * @param bool $array_return If specified, module output will be set by name in an array * @param bool $check_exceptions Check permission exceptions * @param bool $use_push Force change to be refreshed on Dashboard widgets * @param int $id_shop If specified, hook will be execute the shop with this ID * * @throws PrestaShopException * * @return string/array modules output */ public static function exec($hook_name, $hook_args = array(), $id_module = null, $array_return = false, $check_exceptions = true, $use_push = false, $id_shop = null) { if (defined('PS_INSTALLATION_IN_PROGRESS')) { return; } static $disable_non_native_modules = null; if ($disable_non_native_modules === null) { $disable_non_native_modules = (bool) Configuration::get('PS_DISABLE_NON_NATIVE_MODULE'); } // Check arguments validity if ($id_module && !is_numeric($id_module) || !Validate::isHookName($hook_name)) { throw new PrestaShopException('Invalid id_module or hook_name'); } // If no modules associated to hook_name or recompatible hook name, we stop the function if (!($module_list = Hook::getHookModuleExecList($hook_name))) { return ''; } // Check if hook exists if (!($id_hook = Hook::getIdByName($hook_name))) { return false; } // Store list of executed hooks on this page Hook::$executed_hooks[$id_hook] = $hook_name; $live_edit = false; $context = Context::getContext(); if (!isset($hook_args['cookie']) || !$hook_args['cookie']) { $hook_args['cookie'] = $context->cookie; } if (!isset($hook_args['cart']) || !$hook_args['cart']) { $hook_args['cart'] = $context->cart; } $retro_hook_name = Hook::getRetroHookName($hook_name); // Look on modules list $altern = 0; $output = ''; if ($disable_non_native_modules && !isset(Hook::$native_module)) { Hook::$native_module = Module::getNativeModuleList(); } $different_shop = false; if ($id_shop !== null && Validate::isUnsignedId($id_shop) && $id_shop != $context->shop->getContextShopID()) { $old_context = $context->shop->getContext(); $old_shop = clone $context->shop; $shop = new Shop((int) $id_shop); if (Validate::isLoadedObject($shop)) { $context->shop = $shop; $context->shop->setContext(Shop::CONTEXT_SHOP, $shop->id); $different_shop = true; } } foreach ($module_list as $array) { // Check errors if ($id_module && $id_module != $array['id_module']) { continue; } if ((bool) $disable_non_native_modules && Hook::$native_module && count(Hook::$native_module) && !in_array($array['module'], Hook::$native_module)) { continue; } // Check permissions if ($check_exceptions) { $exceptions = Module::getExceptionsStatic($array['id_module'], $array['id_hook']); $controller = Dispatcher::getInstance()->getController(); $controller_obj = Context::getContext()->controller; //check if current controller is a module controller if (isset($controller_obj->module) && Validate::isLoadedObject($controller_obj->module)) { $controller = 'module-' . $controller_obj->module->name . '-' . $controller; } if (in_array($controller, $exceptions)) { continue; } //Backward compatibility of controller names $matching_name = array('authentication' => 'auth', 'productscomparison' => 'compare'); if (isset($matching_name[$controller]) && in_array($matching_name[$controller], $exceptions)) { continue; } if (Validate::isLoadedObject($context->employee) && !Module::getPermissionStatic($array['id_module'], 'view', $context->employee)) { continue; } } if (!($moduleInstance = Module::getInstanceByName($array['module']))) { continue; } if ($use_push && !$moduleInstance->allow_push) { continue; } // Check which / if method is callable $hook_callable = is_callable(array($moduleInstance, 'hook' . $hook_name)); $hook_retro_callable = is_callable(array($moduleInstance, 'hook' . $retro_hook_name)); if (($hook_callable || $hook_retro_callable) && Module::preCall($moduleInstance->name)) { $hook_args['altern'] = ++$altern; if ($use_push && isset($moduleInstance->push_filename) && file_exists($moduleInstance->push_filename)) { Tools::waitUntilFileIsModified($moduleInstance->push_filename, $moduleInstance->push_time_limit); } // Call hook method if ($hook_callable) { $display = Hook::coreCallHook($moduleInstance, 'hook' . $hook_name, $hook_args); } elseif ($hook_retro_callable) { $display = Hook::coreCallHook($moduleInstance, 'hook' . $retro_hook_name, $hook_args); } // Live edit if (!$array_return && $array['live_edit'] && Tools::isSubmit('live_edit') && Tools::getValue('ad') && Tools::getValue('liveToken') == Tools::getAdminToken('AdminModulesPositions' . (int) Tab::getIdFromClassName('AdminModulesPositions') . (int) Tools::getValue('id_employee'))) { $live_edit = true; $output .= self::wrapLiveEdit($display, $moduleInstance, $array['id_hook']); } elseif ($array_return) { $output[$moduleInstance->name] = $display; } else { $output .= $display; } } } if ($different_shop) { $context->shop = $old_shop; $context->shop->setContext($old_context, $shop->id); } if ($array_return) { return $output; } else { return ($live_edit ? '<script type="text/javascript">hooks_list.push(\'' . $hook_name . '\');</script> <div id="' . $hook_name . '" class="dndHook" style="min-height:50px">' : '') . $output . ($live_edit ? '</div>' : ''); } // Return html string }
/** * Execute modules for specified hook * * @param string $hook_name Hook Name * @param array $hook_args Parameters for the functions * @param int $id_module Execute hook for this module only * @param bool $array_return If specified, module output will be set by name in an array * @param bool $check_exceptions Check permission exceptions * @param bool $use_push Force change to be refreshed on Dashboard widgets * @param int $id_shop If specified, hook will be execute the shop with this ID * * @throws PrestaShopException * * @return string/array modules output */ public static function exec($hook_name, $hook_args = array(), $id_module = null, $array_return = false, $check_exceptions = true, $use_push = false, $id_shop = null) { if (defined('PS_INSTALLATION_IN_PROGRESS')) { return; } static $disable_non_native_modules = null; if ($disable_non_native_modules === null) { $disable_non_native_modules = (bool) Configuration::get('PS_DISABLE_NON_NATIVE_MODULE'); } // Check arguments validity if ($id_module && !is_numeric($id_module) || !Validate::isHookName($hook_name)) { throw new PrestaShopException('Invalid id_module or hook_name'); } // If no modules associated to hook_name or recompatible hook name, we stop the function if (!($module_list = Hook::getHookModuleExecList($hook_name))) { return ''; } // Check if hook exists if (!($id_hook = Hook::getIdByName($hook_name))) { return false; } if (array_key_exists($hook_name, self::$deprecated_hooks)) { $deprecVersion = isset(self::$deprecated_hooks[$hook_name]['from']) ? self::$deprecated_hooks[$hook_name]['from'] : _PS_VERSION_; Tools::displayAsDeprecated('The hook ' . $hook_name . ' is deprecated in PrestaShop v.' . $deprecVersion); } // Store list of executed hooks on this page Hook::$executed_hooks[$id_hook] = $hook_name; $context = Context::getContext(); if (!isset($hook_args['cookie']) || !$hook_args['cookie']) { $hook_args['cookie'] = $context->cookie; } if (!isset($hook_args['cart']) || !$hook_args['cart']) { $hook_args['cart'] = $context->cart; } $retro_hook_name = Hook::getRetroHookName($hook_name); // Look on modules list $altern = 0; if ($array_return) { $output = array(); } else { $output = ''; } if ($disable_non_native_modules && !isset(Hook::$native_module)) { Hook::$native_module = Module::getNativeModuleList(); } $different_shop = false; if ($id_shop !== null && Validate::isUnsignedId($id_shop) && $id_shop != $context->shop->getContextShopID()) { $old_context = $context->shop->getContext(); $old_shop = clone $context->shop; $shop = new Shop((int) $id_shop); if (Validate::isLoadedObject($shop)) { $context->shop = $shop; $context->shop->setContext(Shop::CONTEXT_SHOP, $shop->id); $different_shop = true; } } foreach ($module_list as $array) { // Check errors if ($id_module && $id_module != $array['id_module']) { continue; } if ((bool) $disable_non_native_modules && Hook::$native_module && count(Hook::$native_module) && !in_array($array['module'], Hook::$native_module)) { continue; } // Check permissions if ($check_exceptions) { $exceptions = Module::getExceptionsStatic($array['id_module'], $array['id_hook']); $controller = Dispatcher::getInstance()->getController(); $controller_obj = Context::getContext()->controller; //check if current controller is a module controller if (isset($controller_obj->module) && Validate::isLoadedObject($controller_obj->module)) { $controller = 'module-' . $controller_obj->module->name . '-' . $controller; } if (in_array($controller, $exceptions)) { continue; } //Backward compatibility of controller names $matching_name = array('authentication' => 'auth'); if (isset($matching_name[$controller]) && in_array($matching_name[$controller], $exceptions)) { continue; } if (Validate::isLoadedObject($context->employee) && !Module::getPermissionStatic($array['id_module'], 'view', $context->employee)) { continue; } } if (!($moduleInstance = Module::getInstanceByName($array['module']))) { continue; } if ($use_push && !$moduleInstance->allow_push) { continue; } // Check which / if method is callable $hook_callable = is_callable(array($moduleInstance, 'hook' . $hook_name)); $hook_retro_callable = is_callable(array($moduleInstance, 'hook' . $retro_hook_name)); if ($hook_callable || $hook_retro_callable) { $hook_args['altern'] = ++$altern; if ($use_push && isset($moduleInstance->push_filename) && file_exists($moduleInstance->push_filename)) { Tools::waitUntilFileIsModified($moduleInstance->push_filename, $moduleInstance->push_time_limit); } // Call hook method if ($hook_callable) { $display = Hook::coreCallHook($moduleInstance, 'hook' . $hook_name, $hook_args); } elseif ($hook_retro_callable) { $display = Hook::coreCallHook($moduleInstance, 'hook' . $retro_hook_name, $hook_args); } if ($array_return) { $output[$moduleInstance->name] = $display; } else { $output .= $display; } } elseif (Hook::isDisplayHookName($hook_name)) { if ($moduleInstance instanceof WidgetInterface) { $display = Hook::coreRenderWidget($moduleInstance, $hook_name, $hook_args); if ($array_return) { $output[$moduleInstance->name] = $display; } else { $output .= $display; } } } } if ($different_shop) { $context->shop = $old_shop; $context->shop->setContext($old_context, $shop->id); } return $output; }