s); $ret = $this->db->executeS($query); break; case 'prepareQuery': $query = new DbQuery(); $query->select('i.id_product AS id, c, a, f, g')->from('af_index', 'i'); switch ($params['order']['by']) { case 'n': if ($this->settings['indexation']['n']) { $query->select('n_'.(int)$params['id_lang'].' AS n'); } else { $on = 'pl.id_product = i.id_product AND pl.id_shop = i.id_shop AND pl.id_lang = '.(int)$params['id_lang']; $query->select('pl.name AS n')->leftJoin('product_lang', 'pl', $on); } break; case 'd': case 'r': $query->select($params['order']['by']); // ordering in PHP is faster on large catalogues if($params['order']['way'] == 'asc' && $params['order']['by'] == 'r'){ if(isset($_REQUEST['s']) && !empty($_REQUEST['s']) && $_REQUEST['s2'] != 3){ $search_term = $_REQUEST['s']; $query->leftJoin('product_lang','pl','i.`id_product` = pl.`id_product`'); $query->where('(i.`r` LIKE "%'.$search_term.'%" OR pl.name LIKE "%'.$search_term.'%" )'); $query->orderBy('(CASE WHEN i.`r` LIKE "'.$search_term.'%" THEN 1 ELSE 2 END),(CASE WHEN pl.name LIKE "'.$search_term.'%" THEN 1 ELSE 2 END)'); }else{ $query->leftJoin('acdc_special_lookup','asl','i.`r` = asl.`reference`'); $query->leftJoin('product_sale','ps','i.`id_product` = ps.`id_product`'); $query->orderBy('(CASE WHEN asl.`reference` IS NOT NULL THEN 1 ELSE 2 END)'); $query->orderBy('ps.`quantity` DESC'); } } } foreach (array('s', 'q', 'm') as $c_name) { if (isset($params['available_options'][$c_name]) || ($c_name == 'm' && $params['order']['by'] == 'manufacturer_name')) { $query->select($c_name); } } if (isset($params['available_options']['t']) && $this->settings['indexation']['t']) { $query->select('t_'.(int)$params['id_lang'].' AS t'); } if (isset($params['available_options']['w']) || isset($params['sliders']['w'])) { $query->select('w'); } if (!empty($params['p_identifier'])) { $query->select($params['p_identifier'].' AS p'); } foreach ($this->indexationData('queryRestrictions', $params) as $restriction) { $query->where($restriction); } $ret = $query; break; case 'queryRestrictions': $ret = array( 'id_shop' => 'i.id_shop = '.(int)$params['id_shop'], 'visibility' => 'v <> '.($params['current_controller'] == 'search' ? 1 : 2), // visibility 'none' is excluded during indexation ); if ($params['current_controller'] == 'category') { $ret['controller'] = 'FIND_IN_SET('.(int)$params['id_parent_cat'].', i.c) > 0'; } elseif ($params['current_controller'] == 'manufacturer') { $ret['controller'] = 'i.m = '.(int)$params['id_manufacturer']; } elseif ($params['current_controller'] == 'supplier') { $ret['controller'] = 'FIND_IN_SET('.(int)$params['id_supplier'].', i.s) > 0'; } elseif ($params['current_controller'] != 'index' && $params['current_controller'] != 'seopage') { // newproducts, pricesdrop, bestsales, search $imploded_cpids = $this->formatIDs($params['controller_product_ids'], true) ?: 0; $ret['controller'] = 'i.id_product IN ('.pSQL($imploded_cpids).')'; } break; case 'erase': $sql = 'DELETE FROM '.pSQL($this->i['table']).' WHERE 1'; foreach (array('id_product', 'id_shop') as $c_name) { if (isset($params[$c_name]) && $imploded_ids = $this->formatIDs($params[$c_name], true)) { $sql .= ' AND '.$c_name.' IN ('.($imploded_ids).')'; } } $ret &= $this->db->execute($sql); break; case 'get_ids': $ret = array_column($this->db->executeS(' SELECT id_product AS id FROM '.pSQL($this->i['table']).' WHERE id_shop = '.(int)$params['id_shop'].' '), 'id', 'id'); break; } return $ret; } public function indexationInfo($type, $shop_ids = array(), $remove_unused = false) { $ret = array(); $shop_ids = $shop_ids ?: $this->shop_ids; switch ($type) { case 'ids': foreach ($shop_ids as $id_shop) { $indexed = $this->indexationData('get_ids', array('id_shop' => $id_shop)); $required = $this->getProductIDsForIndexation($id_shop); $ret[$id_shop]['indexed'] = array_intersect($required, $indexed); $ret[$id_shop]['missing'] = array_diff($required, $indexed); if ($remove_unused && $unused_ids = array_diff($indexed, $required)) { $this->unindexProducts($unused_ids, array($id_shop)); } } break; case 'count': $ret = $this->indexationInfo('ids', $shop_ids, $remove_unused); foreach ($ret as $id_shop => $data) { foreach ($data as $key => $ids) { $ret[$id_shop][$key] = count($ids); } } break; } return $ret; } public function hookDisplayBackOfficeHeader() { if (Tools::getValue('controller') == 'AdminProducts') { // reindexProduct after mass combinations generation if ($this->is_17) { $this->addJqueryBO(); $js_path = $this->_path.'views/js/attribute-indexer.js?v='.$this->version; $this->context->controller->js_files[] = $js_path; $ajax_path = 'index.php?controller=AdminModules&configure='.$this->name. '&token='.Tools::getAdminTokenLite('AdminModules').'&ajax=1'; return $this->bo()->assignJsVars(array('af_ajax_action_path' => $ajax_path)); } elseif (!empty($this->context->cookie->af_index_product)) { $this->indexProduct($this->context->cookie->af_index_product); $this->context->cookie->__unset('af_index_product'); } return; } elseif (Tools::getValue('configure') != $this->name) { return; } $this->addJqueryBO(); $this->context->controller->addJqueryUI('ui.sortable'); $this->context->controller->css_files[$this->_path.'views/css/back.css?v='.$this->version] = 'all'; if ($this->is_17) { $this->context->controller->css_files[$this->_path.'views/css/back-17.css?'.$this->version] = 'all'; } $this->context->controller->js_files[] = $this->_path.'views/js/back.js?v='.$this->version; if (!empty($this->sp)) { $sp_path = _MODULE_DIR_.$this->sp->name.'/'; $this->context->controller->js_files[] = $sp_path.'views/js/back.js?v='.$this->sp->version; $this->context->controller->css_files[$sp_path.'views/css/back.css?v='.$this->sp->version] = 'all'; } // mce $this->context->controller->addJS(__PS_BASE_URI__.'js/tiny_mce/tiny_mce.js'); $this->context->controller->addJS(__PS_BASE_URI__.'js/admin/tinymce.inc.js'); $js_vars = array( 'savedTxt' => $this->saved_txt, 'errorTxt' => $this->error_txt, 'deletedTxt' => $this->l('Deleted'), 'areYouSureTxt' => $this->l('Are you sure?'), ); return $this->bo()->assignJsVars($js_vars); } public function addJqueryBO() { $this->defineSettings(); if (empty($this->context->jqueryAdded)) { version_compare(_PS_VERSION_, '1.7.6.0', '>=') ? $this->context->controller->setMedia() : $this->context->controller->addJquery(); $this->context->jqueryAdded = 1; } } public function ajaxAction($action) { $ret = array(); switch ($action) { case 'CallTemplateForm': $id_template = Tools::getValue('id_template'); $ret = $this->callTemplateForm($id_template); break; case 'RunProductIndexer': $this->ajaxRunProductIndexer(Tools::getValue('all_identifier')); break; case 'SaveMultipleSettings': $ret['saved'] = true; foreach (Tools::getValue('submitted_forms') as $type => $data) { $submitted_settings = $this->parseStr($data); $ret['saved'] &= $this->saveSettings($type, $submitted_settings, null, true); } break; case 'SaveTemplate': case 'DuplicateTemplate': case 'DeleteTemplate': case 'EraseIndex': case 'UpdateHook': $method = 'ajax'.$action; $this->$method(); break; case 'ToggleActiveStatus': $id_template = Tools::getValue('id_template'); $active = Tools::getValue('active'); $ret = array('success' => $this->toggleActiveStatus($id_template, $active)); break; case 'ShowAvailableFilters': $available_filters = $this->getAvailableFiltersSorted(); $this->context->smarty->assign(array('available_filters' => $available_filters)); $html = $this->display(__FILE__, 'views/templates/admin/available-filters.tpl'); $ret['content'] = utf8_encode($html); $ret['title'] = utf8_encode($this->l('Available filtering criteria')); break; case 'RenderFilterElements': $keys = explode(',', Tools::getValue('keys')); $html = ''; $this->assignLanguageVariables(); foreach ($keys as $key) { $this->context->smarty->assign(array('filter' => $this->getFilterData($key))); $html .= $this->display(__FILE__, 'views/templates/admin/filter-form.tpl'); } $ret['html'] = utf8_encode($html); break; case 'SaveAvailableCustomerFilters': $filters = Tools::getValue('customer_filters'); $filters = $filters ? Tools::jsonEncode($filters) : ''; $ret = array('success' => Configuration::updateValue('AF_SAVED_CUSTOMER_FILTERS', $filters)); break; case 'UpdateModulePosition': case 'DisableModule': case 'UnhookModule': case 'UninstallModule': case 'EnableModule': $id_module = Tools::getValue('id_module'); $hook_name = Tools::getValue('hook_name'); $id_hook = Hook::getIdByName($hook_name); $module = Module::getInstanceById($id_module); if (Validate::isLoadedObject($module)) { if ($action == 'UpdateModulePosition') { $new_position = Tools::getValue('new_position'); $way = Tools::getValue('way'); $ret['saved'] = $module->updatePosition($id_hook, $way, $new_position); } elseif ($action == 'DisableModule') { $module->disable(); $ret['saved'] = !$module->isEnabledForShopContext(); } elseif ($action == 'UnhookModule') { $ret['saved'] = $module->unregisterHook($id_hook, $this->shop_ids); } elseif ($action == 'UninstallModule') { if ($id_module != $this->id) { $ret['saved'] = $module->uninstall(); } } elseif ($action == 'EnableModule') { $ret['saved'] = $module->enable(); } } break; case 'IndexProduct': $ret['indexed'] = $this->indexProduct(Tools::getValue('id_product')); break; case 'addOverride': case 'removeOverride': $override = Tools::getValue('override'); $ret['processed'] = $this->processOverride($action, $override); break; case 'clearCache': $this->cache('clear', ''); $ret['notice'] = utf8_encode($this->l('Cleared')); break; case 'getCachingInfo': $ret['info'] = array(); foreach (array_keys($this->getSettingsFields('caching', false)) as $name) { $ret['info'][$name] = utf8_encode($this->cache('info', $name)); } break; } exit(Tools::jsonEncode($ret)); } public function getAvailableFiltersSorted() { $filters = $this->getAvailableFilters(); $sorted = array(); foreach ($filters as $key => $f) { if ($key == 'c') { $f['name'] = $this->l('Subcategories of current page'); } $sorted[$f['prefix']][$key] = $f; } return $sorted; } public function processOverride($action, $override, $throw_error = true) { $processed = false; switch ($action) { case 'addOverride': case 'removeOverride': $file_path = $this->custom_overrides_dir.$override; $tmp_path = $this->local_path.'override/'.$override; if (file_exists($file_path)) { if (is_writable(dirname($tmp_path))) { try { // temporarily copy file to /override/ folder for processing it natively Tools::copy($file_path, $tmp_path); $class_name = basename($override, '.php'); $processed = $this->$action($class_name); unlink($tmp_path); } catch (Exception $e) { unlink($tmp_path); if ($throw_error) { $this->throwError($e->getMessage()); } } } elseif ($throw_error) { $dir_name = str_replace(_PS_ROOT_DIR_, '', dirname($tmp_path)).'/'; $txt = $this->l('Make sure the following directory is writable: %s'); $this->throwError(sprintf($txt, $dir_name)); } } break; } return $processed; } public function getImplodedContextShopIds() { return implode(', ', $this->shop_ids); } public function getContent() { if (Tools::isSubmit('ajax') && $action = Tools::getValue('action')) { $this->defineSettings(); if (!empty($this->sp) && Tools::getValue('sp')) { $this->sp->ajaxAction($action); } elseif (Tools::getValue('mergedValues')) { $this->mergedValues()->ajaxAction($action); } else { $this->ajaxAction($action); } } $this->bo()->setWarningsIfRequired(); $this->indexationColumns('adjust', 0, 86400); // just to be sure $available_customer_filters = $this->getAvailableFilters(false); $to_unset = array_merge(array('p', 'w'), array_keys($this->getSpecialFilters())); foreach ($to_unset as $k) { unset($available_customer_filters[$k]); } $settings = array(); foreach ($this->getSettingsKeys() as $type) { $settings[$type] = $this->getSettingsFields($type); } $indexation_required = false; $indexation_info = $this->indexationInfo('count', $this->shop_ids, true); foreach ($indexation_info as $id_shop => $data) { $indexation_info[$id_shop]['shop_name'] = $this->db->getValue(' SELECT name FROM '._DB_PREFIX_.'shop WHERE id_shop = '.(int)$id_shop.' '); if ($data['missing']) { $indexation_required = true; } } $smarty_variables = array( 'indexation_data' => $indexation_info, 'indexation_required' => $indexation_required, 'grouped_templates' => $this->getGroupedTemplates(), 'available_hooks' => $this->getAvailableHooks(), 'settings' => $settings, 'available_customer_filters' => $available_customer_filters, 'saved_customer_filters' => $this->getAdjustableCustomerFilters(), 'overrides_data' => $this->getOverridesData(), 'this' => $this, 'changelog_link' => $this->_path.'Readme.md?v='.$this->version, 'documentation_link' => $this->_path.'readme_en.pdf?v='.$this->version, 'contact_us_link' => 'https://addons.prestashop.com/en/write-to-developper?id_product=18575', 'other_modules_link' => 'https://addons.prestashop.com/en/2_community-developer?contributor=64815', 'files_update_warnings' => $this->bo()->getFilesUpdadeWarnings(), ); if (!empty($this->sp)) { $smarty_variables['sp'] = $this->sp->getConfigSmartyVariables(); } $this->context->smarty->assign($smarty_variables); $this->mergedValues()->assignConfigVariables(); $html = $this->display(__FILE__, 'views/templates/admin/configure.tpl'); return $html; } public function getGroupedTemplates($available_controllers = array()) { $grouped_templates = array(); $templates_multishop = $this->db->executeS(' SELECT * FROM '._DB_PREFIX_.'af_templates WHERE id_shop IN ('.pSQL($this->getImplodedContextShopIds()).') GROUP BY id_template ORDER BY id_template DESC, id_shop = '.(int)$this->id_shop.' DESC '); $available_controllers = $available_controllers?: $this->getAvailableControllers(true); $multiple_id_controllers = $this->getControllersWithMultipleIDs(false); foreach ($available_controllers as $c => $title) { if (!isset($multiple_id_controllers[$c])) { $c = 'other'; $title = $this->l('other pages'); } $grouped_templates[$c] = array( 'title' => sprintf($this->l('Templates for %s'), Tools::strtolower($title)), 'first' => !count($grouped_templates), 'additional_actions' => $c != 'other', 'templates' => array(), ); } foreach ($templates_multishop as $t) { $c = $t['template_controller']; if (isset($available_controllers[$c])) { $group = isset($multiple_id_controllers[$c]) ? $c : 'other'; if (isset($grouped_templates[$group])) { $grouped_templates[$group]['templates'][$t['id_template']] = $t; } } } foreach ($grouped_templates as $g => $t) { if ($t['templates']) { $min_id = min(array_keys($t['templates'])); $grouped_templates[$g]['templates'][$min_id]['first_in_group'] = 1; } } return $grouped_templates; } public function getGroupOptions($type, $id_lang) { $group_options = array(); switch ($type) { case 'attribute': foreach (AttributeGroup::getAttributesGroups($id_lang) as $g) { $name = $g['public_name'].($g['name'] != $g['public_name'] ? ' ('.$g['name'].')' : ''); $group_options[$g['id_attribute_group']] = $name; } break; case 'feature': foreach (Feature::getFeatures($id_lang) as $f) { $group_options[$f['id_feature']] = $f['name']; } break; } return $group_options; } public function getOverridesData() { $data_fetching_txt = $this->l('Required to avoid double data fetching on %s'); $notes = array( 'Product' => sprintf($data_fetching_txt, $this->l('prices drop and new products pages')), 'ProductSale' => sprintf($data_fetching_txt, $this->l('bestsellers page')), 'Search' => sprintf($data_fetching_txt, $this->l('search results page')), 'Manufacturer' => sprintf($data_fetching_txt, $this->l('manufacturer pages')), 'Supplier' => sprintf($data_fetching_txt, $this->l('supplier pages')), 'AdminProductsController' => $this->l('Required for proper indexation on saving the product'), 'FrontController' => $this->l('Required for applying custom sorting and number of products per page'), ); if ($this->is_17) { $notes['Product'] = $this->l('Required for improved performance on Search results page'); } $autoload = PrestaShopAutoload::getInstance(); $overrides = array(); foreach (Tools::scandir($this->custom_overrides_dir, 'php', '', true) as $file) { $class_name = basename($file, '.php'); if ($class_name != 'index' && (!$this->is_17 || $class_name == 'Product')) { $path = $autoload->getClassPath($class_name.'Core'); $overrides[$class_name] = array( 'note' => isset($notes[$class_name]) ? $notes[$class_name] : '', 'path' => $path, 'installed' => $this->isOverrideInstalled($path), ); } } return $overrides; } public function isOverrideInstalled($path) { $shop_override_path = _PS_OVERRIDE_DIR_.$path; $module_override_path = $this->custom_overrides_dir.$path; $methods_to_override = $already_overriden = array(); if (file_exists($module_override_path)) { $lines = file($module_override_path); foreach ($lines as $line) { // note: this check is available only for public functions if (Tools::substr(trim($line), 0, 6) == 'public') { $key = trim(current(explode('(', $line))); $methods_to_override[$key] = 0; } } } $name_length = Tools::strlen($this->name); if (file_exists($shop_override_path)) { $lines = file($shop_override_path); foreach ($lines as $i => $line) { if (Tools::substr(trim($line), 0, 6) == 'public') { $key = trim(current(explode('(', $line))); if (isset($methods_to_override[$key])) { unset($methods_to_override[$key]); // if there is no comment about installed override if (!isset($lines[$i - 4]) || Tools::substr(trim($lines[$i - 4]), - $name_length) !== $this->name) { $key = explode('function ', $key); if (isset($key[1])) { $already_overriden[] = $key[1].'()'; } } } } } } $installed = (bool)!$methods_to_override; if ($already_overriden) { $installed = implode(', ', $already_overriden); } return $installed; } public function getSettingsFields($type, $fill_values = true, $id_shop = false) { $fields = array(); switch ($type) { case 'general': $fields = $this->getGeneralSettingsFields(); break; case 'caching': $fields = $this->getCachingSettingsFields(); break; case 'indexation': $fields = $this->getIndexationSettingsFields(); if ($fill_values) { $this->markBlockedIndexationFields($fields); } break; case 'seopage': if (!empty($this->sp)) { $fields = $this->sp->getSettingsFields(); } break; default: $fields = $this->getSelectorSettingsFields($type); break; } if ($fill_values) { if (!$id_shop && isset($this->settings[$type])) { $saved_settings = $this->settings[$type]; } else { $saved_settings = $this->db->getValue(' SELECT value FROM '._DB_PREFIX_.'af_settings WHERE type = \''.pSQL($type).'\' AND id_shop = '.(int)$id_shop.' '); $saved_settings = $saved_settings ? Tools::jsonDecode($saved_settings, true) : array(); } foreach ($fields as $name => &$f) { if (isset($saved_settings[$name]) && empty($f['blocked'])) { $f['value'] = $saved_settings[$name]; } } } return $fields; } public function markBlockedIndexationFields(&$fields) { $suffixes_count = $this->indexationColumns('getAvailableSuffixesCount', 0, 3600); $check_values = array('p_c' => 'currency', 'p_g' => 'group', 'n' => 'lang', 't' => 'lang'); foreach ($check_values as $key => $type) { if (isset($suffixes_count[$type]) && $suffixes_count[$type] > $this->i['max_column_suffixes']) { $fields[$key]['blocked'] = 1; $fields[$key]['value'] = 0; } } } public function getGeneralSettingsFields() { $get_settings = $this->db->getValue('SELECT value FROM ' . _DB_PREFIX_ . 'af_settings where type= "general"'); $get_settings = $get_settings ? Tools::jsonDecode($get_settings, true) : array(); $fields = array( 'layout' => array( 'display_name' => $this->l('Display type'), 'type' => 'select', 'value' => 'vertical', 'options' => $this->getOptions('layout'), ), 'count_data' => array( 'display_name' => $this->l('Show numbers of matches'), 'value' => 1, 'type' => 'switcher', ), 'hide_zero_matches' => array( 'display_name' => $this->l('Hide options with zero matches'), 'value' => 1, 'type' => 'switcher', ), 'dim_zero_matches' => array( 'display_name' => $this->l('Dim options with zero matches'), 'value' => 1, 'type' => 'switcher', ), 'sf_position' => array( 'display_name' => $this->l('Display selected filters'), 'value' => 0, 'type' => 'select', 'options' => array( 0 => $this->l('Above filter block'), 1 => $this->l('Above product list'), ), ), 'include_group' => array( 'display_name' => $this->l('Show group name in selected filters'), 'value' => 0, 'type' => 'switcher', ), 'compact' => array( 'display_name' => $this->l('Screen width for compact layout'), 'tooltip' => $this->l('Use compact layout if browser width is equal to this value or less'), 'type' => 'text', 'input_suffix' => 'px', 'value' => 767, 'validate' => 'isInt', 'related_options' => '.compact-option', 'subtitle' => $this->l('Responsive compact view'), ), 'compact_offset' => array( 'display_name' => $this->l('Compact panel offset direction'), 'type' => 'select', 'value' => 2, 'options' => array(1 => $this->l('Left'), 2 => $this->l('Right')), 'validate' => 'isInt', 'class' => 'compact-option hidden-on-0', ), 'compact_btn' => array( 'display_name' => $this->l('Compact button'), 'type' => 'select', 'value' => 1, 'options' => array( 1 => $this->l('Text + Filter icon'), 2 => $this->l('Only text'), 3 => $this->l('Only filter icon'), ), 'validate' => 'isInt', 'class' => 'compact-option hidden-on-0', ), 'npp' => array( 'display_name' => $this->l('Number of products per page'), 'value' => Configuration::get('PS_PRODUCTS_PER_PAGE'), 'type' => 'text', 'validate' => 'isInt', 'subtitle' => $this->l('Product list'), ), 'default_order_by' => array( 'display_name' => $this->l('Default order by'), 'value' => Tools::getProductsOrder('by'), 'type' => 'select', 'options' => $this->getOptions('orderby'), 'related_options' => '.order-by-option', ), 'default_order_way' => array( 'display_name' => $this->l('Default order way'), 'value' => Tools::getProductsOrder('way'), 'type' => 'select', 'options' => $this->getOptions('orderway'), 'class' => 'order-by-option hidden-on-random', ), 'random_upd' => array( 'display_name' => $this->l('Update random order'), 'value' => 1, 'type' => 'select', 'options' => array( 0 => $this->l('On every page load'), 1 => $this->l('Every hour'), 2 => $this->l('Every day'), 3 => $this->l('Every week'), ), 'class' => 'order-by-option visible-on-random', ), 'reload_action' => array( 'display_name' => $this->l('Update product list'), 'value' => 1, 'type' => 'select', 'options' => array( 1 => $this->l('Instantly'), 2 => $this->l('On button click'), ), ), 'p_type' => array( 'display_name' => $this->l('Pagination type'), 'value' => 1, 'type' => 'select', 'options' => array( 1 => $this->l('Regular'), 2 => $this->l('Load more button'), 3 => $this->l('Infinite scroll'), ), ), 'autoscroll' => array( 'display_name' => $this->l('Autoscroll to top after filtration'), 'tooltip' => $this->l('After applying filters, switching pages, changing sorting, etc...'), 'value' => $get_settings['autoscroll']!= 0?$get_settings['autoscroll']:0, LIGHTNING & SURGE PROTECTION DEVICES & CONDUCTORS (4)

lightning & surge...

LIGHTNING & SURGE PROTECTION DEVICES & CONDUCTORS

Product added to your list
Product added to compare.

We use cookies to improve user experience, and analyze website traffic. For these reasons, we may share your site usage data with our analytics partners. By clicking “Accept Cookies,” you consent to store on your device all the technologies described in our Terms & Conditions & Privacy Policy