From bd4ece095b002ba3cced051a92a3aed5145cb1a4 Mon Sep 17 00:00:00 2001 From: Damien Metzger Date: Fri, 19 Jul 2013 10:58:51 +0200 Subject: [PATCH 1/3] [*] FO : lots of performance improvements (removed or merged useless SQL queries) --- classes/Group.php | 7 +++++ classes/Hook.php | 25 ++++++++++------ classes/ObjectModel.php | 27 ++++++++++------- classes/module/Module.php | 63 +++++++++++++++++++++------------------ 4 files changed, 74 insertions(+), 48 deletions(-) diff --git a/classes/Group.php b/classes/Group.php index aa7f6cccd..eb8b95e3d 100644 --- a/classes/Group.php +++ b/classes/Group.php @@ -70,6 +70,13 @@ class GroupCore extends ObjectModel protected $webserviceParameters = array(); + public function __construct($id = null, $id_lang = null, $id_shop = null) + { + parent::__construct($id, $id_lang, $id_shop); + if ($this->id && !isset(Group::$group_price_display_method[$this->id])) + self::$group_price_display_method[$this->id] = $this->price_display_method; + } + public static function getGroups($id_lang, $id_shop = false) { $shop_criteria = ''; diff --git a/classes/Hook.php b/classes/Hook.php index 420d5b798..407a8a83c 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -113,19 +113,26 @@ class HookCore extends ObjectModel if (!Validate::isHookName($hook_name)) return false; - $cache_id = 'hook_idbyname_'.$hook_name; + $cache_id = 'hook_idsbyname'; if (!Cache::isStored($cache_id)) { - $retro_hook_name = Hook::getRetroHookName($hook_name); - Cache::store($cache_id, Db::getInstance()->getValue(' - SELECT `id_hook` - FROM `'._DB_PREFIX_.'hook` - WHERE `name` = \''.pSQL($hook_name).'\' - OR `name` = \''.pSQL($retro_hook_name).'\' - ')); + // Get all hook ID by name and alias + $hook_ids = array(); + $result = Db::getInstance()->ExecuteS(' + SELECT `id_hook`, `name` + FROM `'._DB_PREFIX_.'hook` + UNION + SELECT `id_hook`, ha.`alias` as name + FROM `ps_hook_alias` ha + INNER JOIN `ps_hook` h ON ha.name = h.name'); + foreach ($result as $row) + $hook_ids[$row['name']] = $row['id_hook']; + Cache::store($cache_id, $hook_ids); } + else + $hook_ids = Cache::retrieve($cache_id); - return Cache::retrieve($cache_id); + return (isset($hook_ids[$hook_name]) ? $hook_ids[$hook_name] : false); } /** diff --git a/classes/ObjectModel.php b/classes/ObjectModel.php index a9aadd82d..d1cd8f5ad 100644 --- a/classes/ObjectModel.php +++ b/classes/ObjectModel.php @@ -242,16 +242,6 @@ abstract class ObjectModelCore $this->{$key} = $value; } } - - if (!is_array(self::$fieldsRequiredDatabase)) - { - $fields = $this->getfieldsRequiredDatabase(true); - if ($fields) - foreach ($fields as $row) - self::$fieldsRequiredDatabase[$row['object_name']][(int)$row['id_required_field']] = pSQL($row['field_name']); - else - self::$fieldsRequiredDatabase = array(); - } } /** @@ -901,6 +891,7 @@ abstract class ObjectModelCore */ public function validateField($field, $value, $id_lang = null) { + $this->cacheFieldsRequiredDatabase(); $data = $this->def['fields'][$field]; // Check if field is required @@ -983,6 +974,7 @@ abstract class ObjectModelCore public function validateController($htmlentities = true) { + $this->cacheFieldsRequiredDatabase(); $errors = array(); $required_fields_database = (isset(self::$fieldsRequiredDatabase[get_class($this)])) ? self::$fieldsRequiredDatabase[get_class($this)] : array(); foreach ($this->def['fields'] as $field => $data) @@ -1029,6 +1021,7 @@ abstract class ObjectModelCore public function getWebserviceParameters($ws_params_attribute_name = null) { + $this->cacheFieldsRequiredDatabase(); $default_resource_parameters = array( 'objectSqlId' => $this->def['primary'], 'retrieveData' => array( @@ -1139,6 +1132,7 @@ abstract class ObjectModelCore public function validateFieldsRequiredDatabase($htmlentities = true) { + $this->cacheFieldsRequiredDatabase(); $errors = array(); $required_fields = (isset(self::$fieldsRequiredDatabase[get_class($this)])) ? self::$fieldsRequiredDatabase[get_class($this)] : array(); @@ -1166,6 +1160,19 @@ abstract class ObjectModelCore FROM '._DB_PREFIX_.'required_field '.(!$all ? 'WHERE object_name = \''.pSQL(get_class($this)).'\'' : '')); } + + public function cacheFieldsRequiredDatabase() + { + if (!is_array(self::$fieldsRequiredDatabase)) + { + $fields = $this->getfieldsRequiredDatabase(true); + if ($fields) + foreach ($fields as $row) + self::$fieldsRequiredDatabase[$row['object_name']][(int)$row['id_required_field']] = pSQL($row['field_name']); + else + self::$fieldsRequiredDatabase = array(); + } + } public function addFieldsRequiredDatabase($fields) { diff --git a/classes/module/Module.php b/classes/module/Module.php index 6067612b6..b521e0fe4 100644 --- a/classes/module/Module.php +++ b/classes/module/Module.php @@ -153,18 +153,22 @@ abstract class ModuleCore // If cache is not generated, we generate it if (self::$modules_cache == null && !is_array(self::$modules_cache)) { - // Join clause is done to check if the module is activated in current shop context - $sql_limit_shop = 'SELECT COUNT(*) FROM `'._DB_PREFIX_.'module_shop` ms WHERE m.`id_module` = ms.`id_module` AND ms.`id_shop` = '.((is_object(Context::getContext()->shop) && $id = (int)Context::getContext()->shop->id) ? $id : 1); - - $sql = 'SELECT m.`id_module`, m.`name`, ('.$sql_limit_shop.') as total FROM `'._DB_PREFIX_.'module` m'; - - // Result is cached + $id_shop = (Validate::isLoadedObject($this->context->shop) ? $this->context->shop->id : 1); self::$modules_cache = array(); - $result = Db::getInstance()->executeS($sql); + // Join clause is done to check if the module is activated in current shop context + $result = Db::getInstance()->executeS(' + SELECT m.`id_module`, m.`name`, ( + SELECT id_module + FROM `'._DB_PREFIX_.'module_shop` ms + WHERE m.`id_module` = ms.`id_module` + AND ms.`id_shop` = '.(int)$id_shop.' + LIMIT 1 + ) as mshop + FROM `'._DB_PREFIX_.'module` m'); foreach ($result as $row) { self::$modules_cache[$row['name']] = $row; - self::$modules_cache[$row['name']]['active'] = ($row['total'] > 0) ? 1 : 0; + self::$modules_cache[$row['name']]['active'] = ($row['mshop'] > 0) ? 1 : 0; } } @@ -1511,12 +1515,12 @@ abstract class ModuleCore * @param int $id_hook Hook ID * @return array Exceptions */ - protected static $exceptionsCache = null; - public function getExceptions($hookID, $dispatch = false) + public function getExceptions($id_hook, $dispatch = false) { - if (self::$exceptionsCache === null) + $cache_id = 'exceptionsCache'; + if (!Cache::isStored($cache_id)) { - self::$exceptionsCache = array(); + $exceptionsCache = array(); $sql = 'SELECT * FROM `'._DB_PREFIX_.'hook_module_exceptions` WHERE `id_shop` IN ('.implode(', ', Shop::getContextListShopID()).')'; $result = Db::getInstance()->executeS($sql); @@ -1525,33 +1529,34 @@ abstract class ModuleCore if (!$row['file_name']) continue; $key = $row['id_hook'].'-'.$row['id_module']; - if (!isset(self::$exceptionsCache[$key])) - self::$exceptionsCache[$key] = array(); - if (!isset(self::$exceptionsCache[$key][$row['id_shop']])) - self::$exceptionsCache[$key][$row['id_shop']] = array(); - self::$exceptionsCache[$key][$row['id_shop']][] = $row['file_name']; + if (!isset($exceptionsCache[$key])) + $exceptionsCache[$key] = array(); + if (!isset($exceptionsCache[$key][$row['id_shop']])) + $exceptionsCache[$key][$row['id_shop']] = array(); + $exceptionsCache[$key][$row['id_shop']][] = $row['file_name']; } + Cache::store($cache_id, $exceptionsCache); } + else + $exceptionsCache = !Cache::retrieve($cache_id); - $key = $hookID.'-'.$this->id; - if (!$dispatch) + $key = $id_hook.'-'.$this->id; + $array_return = array(); + if ($dispatch) { - $files = array(); foreach (Shop::getContextListShopID() as $shop_id) - if (isset(self::$exceptionsCache[$key], self::$exceptionsCache[$key][$shop_id])) - foreach (self::$exceptionsCache[$key][$shop_id] as $file) - if (!in_array($file, $files)) - $files[] = $file; - return $files; + if (isset($exceptionsCache[$key], $exceptionsCache[$key][$shop_id])) + $array_return[$shop_id] = $exceptionsCache[$key][$shop_id]; } else { - $list = array(); foreach (Shop::getContextListShopID() as $shop_id) - if (isset(self::$exceptionsCache[$key], self::$exceptionsCache[$key][$shop_id])) - $list[$shop_id] = self::$exceptionsCache[$key][$shop_id]; - return $list; + if (isset($exceptionsCache[$key], $exceptionsCache[$key][$shop_id])) + foreach ($exceptionsCache[$key][$shop_id] as $file) + if (!in_array($file, $array_return)) + $array_return[] = $file; } + return $array_return; } public static function isInstalled($module_name) From 989dafce21688d6997df621ebffe11ec25bea76c Mon Sep 17 00:00:00 2001 From: Damien Metzger Date: Fri, 19 Jul 2013 11:29:18 +0200 Subject: [PATCH 2/3] [*] FO : a few more SQL improvements --- classes/Connection.php | 4 ++++ classes/Hook.php | 2 +- classes/shop/ShopUrl.php | 35 ++++++++++++++++------------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/classes/Connection.php b/classes/Connection.php index b250e4ea5..4b171b1f0 100644 --- a/classes/Connection.php +++ b/classes/Connection.php @@ -82,8 +82,12 @@ class ConnectionCore extends ObjectModel // The connection is created if it does not exist yet and we get the current page id if (!isset($cookie->id_connections) || !strstr(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', Tools::getHttpHost(false, false))) $id_page = Connection::setNewConnection($cookie); + // If we do not track the pages, no need to get the page id + if (!Configuration::get('PS_STATSDATA_PAGESVIEWS') && !Configuration::get('PS_STATSDATA_CUSTOMER_PAGESVIEWS')) + return array(); if (!isset($id_page) || !$id_page) $id_page = Page::getCurrentId(); + // If we do not track the page views by customer, the id_page is the only information needed if (!Configuration::get('PS_STATSDATA_CUSTOMER_PAGESVIEWS')) return array('id_page' => $id_page); diff --git a/classes/Hook.php b/classes/Hook.php index 407a8a83c..d9ba5f57e 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -83,7 +83,7 @@ class HookCore extends ObjectModel public function add($autodate = true, $null_values = false) { - Cache::clean('hook_idbyname_'.$this->name); + Cache::clean('hook_idsbyname'); return parent::add($autodate, $null_values); } diff --git a/classes/shop/ShopUrl.php b/classes/shop/ShopUrl.php index c8e4b6074..e1594c86b 100644 --- a/classes/shop/ShopUrl.php +++ b/classes/shop/ShopUrl.php @@ -143,22 +143,21 @@ class ShopUrlCore extends ObjectModel return Db::getInstance()->getValue($sql); } - public static function getMainShopDomain($id_shop = null) - { - if (!self::$main_domain || $id_shop !== null) - self::$main_domain = Db::getInstance()->getValue('SELECT domain - FROM '._DB_PREFIX_.'shop_url - WHERE main=1 AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id)); - return self::$main_domain; - } - public static function cacheMainDomainForShop($id_shop) { if (!Validate::isUnsignedId($id_shop)) return false; - ShopUrl::getMainShopDomain($id_shop); - ShopUrl::getMainShopDomainSSL($id_shop); + if (!self::$main_domain_ssl || !self::$main_domain || $id_shop !== null) + { + $row = Db::getInstance()->getRow(' + SELECT domain, domain_ssl + FROM '._DB_PREFIX_.'shop_url + WHERE main = 1 + AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id)); + self::$main_domain = $row['domain']; + self::$main_domain_ssl = $row['domain_ssl']; + } } public static function resetMainDomainCache() @@ -167,17 +166,15 @@ class ShopUrlCore extends ObjectModel self::$main_domain_ssl = null; } + public static function getMainShopDomain($id_shop = null) + { + ShopUrl::cacheMainDomainForShop($id_shop); + return self::$main_domain; + } public static function getMainShopDomainSSL($id_shop = null) { - if (!self::$main_domain_ssl || $id_shop !== null) - { - $sql = 'SELECT domain_ssl - FROM '._DB_PREFIX_.'shop_url - WHERE main = 1 - AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id); - self::$main_domain_ssl = Db::getInstance()->getValue($sql); - } + ShopUrl::cacheMainDomainForShop($id_shop); return self::$main_domain_ssl; } } \ No newline at end of file From 8c47ca3edf9ccbf23569eb61bcc6aba5d0ef19e3 Mon Sep 17 00:00:00 2001 From: Damien Metzger Date: Fri, 19 Jul 2013 11:40:52 +0200 Subject: [PATCH 3/3] [-] BO : fixed sort by currency exchange rate #PSCFV-9840 --- controllers/admin/AdminCurrenciesController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/admin/AdminCurrenciesController.php b/controllers/admin/AdminCurrenciesController.php index c5d719483..bf8690b64 100644 --- a/controllers/admin/AdminCurrenciesController.php +++ b/controllers/admin/AdminCurrenciesController.php @@ -38,7 +38,7 @@ class AdminCurrenciesControllerCore extends AdminController 'iso_code' => array('title' => $this->l('ISO code'), 'align' => 'center', 'width' => 80), 'iso_code_num' => array('title' => $this->l('ISO code number'), 'align' => 'center', 'width' => 120), 'sign' => array('title' => $this->l('Symbol'), 'width' => 20, 'align' => 'center', 'orderby' => false, 'search' => false), - 'conversion_rate' => array('title' => $this->l('Exchange rate'), 'type' => 'float', 'align' => 'center', 'width' => 130, 'search' => false), + 'conversion_rate' => array('title' => $this->l('Exchange rate'), 'type' => 'float', 'align' => 'center', 'width' => 130, 'search' => false, 'filter_key' => 'currency_shop!conversion_rate'), 'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false), );