commit a62a234134dd3ef1c1e8ae55db650e7fd3fb9565 Author: Francois Gaillard Date: Thu Mar 20 14:28:17 2014 +0100 Initial commit diff --git a/blocktopmenu.php b/blocktopmenu.php new file mode 100644 index 0000000..1a14292 --- /dev/null +++ b/blocktopmenu.php @@ -0,0 +1,1083 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +require (dirname(__FILE__).'/menutoplinks.class.php'); + +class Blocktopmenu extends Module +{ + private $_menu = ''; + private $_html = ''; + private $user_groups; + + /* + * Pattern for matching config values + */ + private $pattern = '/^([A-Z_]*)[0-9]+/'; + + /* + * Name of the controller + * Used to set item selected or not in top menu + */ + private $page_name = ''; + + /* + * Spaces per depth in BO + */ + private $spacer_size = '5'; + + public function __construct() + { + $this->name = 'blocktopmenu'; + $this->tab = 'front_office_features'; + $this->version = 1.10; + $this->author = 'PrestaShop'; + + $this->bootstrap = true; + parent::__construct(); + + $this->displayName = $this->l('Top horizontal menu'); + $this->description = $this->l('Adds a new horizontal menu to the top of your e-commerce website.'); + } + + public function install() + { + if (!parent::install() || + !$this->registerHook('displayTop') || + !Configuration::updateGlobalValue('MOD_BLOCKTOPMENU_ITEMS', 'CAT3,CAT26') || + !Configuration::updateGlobalValue('MOD_BLOCKTOPMENU_SEARCH', '1') || + !$this->registerHook('actionObjectCategoryUpdateAfter') || + !$this->registerHook('actionObjectCategoryDeleteAfter') || + !$this->registerHook('actionObjectCategoryAddAfter') || + !$this->registerHook('actionObjectCmsUpdateAfter') || + !$this->registerHook('actionObjectCmsDeleteAfter') || + !$this->registerHook('actionObjectCmsAddAfter') || + !$this->registerHook('actionObjectSupplierUpdateAfter') || + !$this->registerHook('actionObjectSupplierDeleteAfter') || + !$this->registerHook('actionObjectSupplierAddAfter') || + !$this->registerHook('actionObjectManufacturerUpdateAfter') || + !$this->registerHook('actionObjectManufacturerDeleteAfter') || + !$this->registerHook('actionObjectManufacturerAddAfter') || + !$this->registerHook('actionObjectProductUpdateAfter') || + !$this->registerHook('actionObjectProductDeleteAfter') || + !$this->registerHook('actionObjectProductAddAfter') || + !$this->registerHook('categoryUpdate') || + !$this->registerHook('actionShopDataDuplication') || + !$this->installDB()) + return false; + return true; + } + + public function installDb() + { + return (Db::getInstance()->execute(' + CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'linksmenutop` ( + `id_linksmenutop` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + `id_shop` INT(11) UNSIGNED NOT NULL, + `new_window` TINYINT( 1 ) NOT NULL, + INDEX (`id_shop`) + ) ENGINE = '._MYSQL_ENGINE_.' CHARACTER SET utf8 COLLATE utf8_general_ci;') && + Db::getInstance()->execute(' + CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'linksmenutop_lang` ( + `id_linksmenutop` INT(11) UNSIGNED NOT NULL, + `id_lang` INT(11) UNSIGNED NOT NULL, + `id_shop` INT(11) UNSIGNED NOT NULL, + `label` VARCHAR( 128 ) NOT NULL , + `link` VARCHAR( 128 ) NOT NULL , + INDEX ( `id_linksmenutop` , `id_lang`, `id_shop`) + ) ENGINE = '._MYSQL_ENGINE_.' CHARACTER SET utf8 COLLATE utf8_general_ci;')); + } + + public function uninstall() + { + if (!parent::uninstall() || + !Configuration::deleteByName('MOD_BLOCKTOPMENU_ITEMS') || + !Configuration::deleteByName('MOD_BLOCKTOPMENU_SEARCH') || + !$this->uninstallDB()) + return false; + return true; + } + + private function uninstallDb() + { + Db::getInstance()->execute('DROP TABLE `'._DB_PREFIX_.'linksmenutop`'); + Db::getInstance()->execute('DROP TABLE `'._DB_PREFIX_.'linksmenutop_lang`'); + return true; + } + + public function getContent() + { + $this->context->controller->addjQueryPlugin('hoverIntent'); + + $id_lang = (int)Context::getContext()->language->id; + $languages = $this->context->controller->getLanguages(); + $default_language = (int)Configuration::get('PS_LANG_DEFAULT'); + + $labels = Tools::getValue('label') ? array_filter(Tools::getValue('label'), 'strlen') : array(); + $links_label = Tools::getValue('link') ? array_filter(Tools::getValue('link'), 'strlen') : array(); + $spacer = str_repeat(' ', $this->spacer_size); + $divLangName = 'link_label'; + + $update_cache = false; + + if (Tools::isSubmit('submitBlocktopmenu')) + { + $items = Tools::getValue('items'); + if (is_array($items) && count($items) && Configuration::updateValue('MOD_BLOCKTOPMENU_ITEMS', (string)implode(',', $items))) + $this->_html .= $this->displayConfirmation($this->l('The settings have been updated.')); + else + $this->_html .= $this->displayError($this->l('Unable to update settings.')); + Configuration::updateValue('MOD_BLOCKTOPMENU_SEARCH', (bool)Tools::getValue('search')); + $update_cache = true; + } + else if (Tools::isSubmit('submitBlocktopmenuLinks')) + { + foreach ($languages as $key => $val) + { + $links_label[$val['id_lang']] = Tools::getValue('link_'.(int)$val['id_lang']); + $labels[$val['id_lang']] = Tools::getValue('label_'.(int)$val['id_lang']); + } + + $count_links_label = count($links_label); + $count_label = count($labels); + if ($count_links_label || $count_label) + { + if (!$count_links_label) + $this->_html .= $this->displayError($this->l('Please complete the "Link" field.')); + elseif (!$count_label) + $this->_html .= $this->displayError($this->l('Please add a label.')); + elseif (!isset($labels[$default_language])) + $this->_html .= $this->displayError($this->l('Please add a label for your default language.')); + else + { + MenuTopLinks::add($links_label, $labels, Tools::getValue('new_window', 0), (int)Shop::getContextShopID()); + $this->_html .= $this->displayConfirmation($this->l('The link has been added.')); + } + } + $update_cache = true; + } + elseif (Tools::isSubmit('deletelinksmenutop')) + { + $id_linksmenutop = Tools::getValue('id_linksmenutop', 0); + MenuTopLinks::remove($id_linksmenutop, (int)Shop::getContextShopID()); + Configuration::updateValue('MOD_BLOCKTOPMENU_ITEMS', str_replace(array('LNK'.$id_linksmenutop.',', 'LNK'.$id_linksmenutop), '', Configuration::get('MOD_BLOCKTOPMENU_ITEMS'))); + $this->_html .= $this->displayConfirmation($this->l('The link has been removed.')); + $update_cache = true; + } + elseif (Tools::isSubmit('updatelinksmenutop')) + { + $id_linksmenutop = (int)Tools::getValue('id_linksmenutop', 0); + $id_shop = (int)Shop::getContextShopID(); + + if (Tools::isSubmit('updatelink')) + { + $link = array(); + $label = array(); + $new_window = (int)Tools::getValue('new_window', 0); + + foreach (Language::getLanguages(false) as $lang) + { + $link[$lang['id_lang']] = Tools::getValue('link_'.(int)$lang['id_lang']); + $label[$lang['id_lang']] = Tools::getValue('label_'.(int)$lang['id_lang']); + } + + MenuTopLinks::update($link, $label, $new_window, (int)$id_shop, (int)$id_linksmenutop, (int)$id_linksmenutop); + $this->_html .= $this->displayConfirmation($this->l('The link has been edited.')); + } + $update_cache = true; + } + + if ($update_cache) + $this->clearMenuCache(); + + $this->_html .= $this->renderForm().$this->renderAddForm(); + + $links = MenuTopLinks::gets((int)$id_lang, null, (int)Shop::getContextShopID()); + + if (!count($links)) + return $this->_html; + + $this->_html .= $this->renderList(); + return $this->_html; + } + + private function getMenuItems() + { + $items = Tools::getValue('items'); + if (is_array($items) && count($items)) + return $items; + else + { + $conf = Configuration::get('MOD_BLOCKTOPMENU_ITEMS'); + if (strlen($conf)) + return explode(',', Configuration::get('MOD_BLOCKTOPMENU_ITEMS')); + else + return array(); + } + } + + private function makeMenuOption() + { + $menu_item = $this->getMenuItems(); + + $id_lang = (int)$this->context->language->id; + $id_shop = (int)Shop::getContextShopID(); + $html = ''; + } + + private function makeMenu() + { + $menu_items = $this->getMenuItems(); + $id_lang = (int)$this->context->language->id; + $id_shop = (int)Shop::getContextShopID(); + + foreach ($menu_items as $item) + { + if (!$item) + continue; + + preg_match($this->pattern, $item, $value); + $id = (int)substr($item, strlen($value[1]), strlen($item)); + + switch (substr($item, 0, strlen($value[1]))) + { + case 'CAT': + $this->_menu .= $this->generateCategoriesMenu(Category::getNestedCategories($id, $id_lang, true, $this->user_groups)); + break; + + case 'PRD': + $selected = ($this->page_name == 'product' && (Tools::getValue('id_product') == $id)) ? ' class="sfHover"' : ''; + $product = new Product((int)$id, true, (int)$id_lang); + if (!is_null($product->id)) + $this->_menu .= ''.$product->name.''.PHP_EOL; + break; + + case 'CMS': + $selected = ($this->page_name == 'cms' && (Tools::getValue('id_cms') == $id)) ? ' class="sfHover"' : ''; + $cms = CMS::getLinks((int)$id_lang, array($id)); + if (count($cms)) + $this->_menu .= ''.Tools::safeOutput($cms[0]['meta_title']).''.PHP_EOL; + break; + + case 'CMS_CAT': + $category = new CMSCategory((int)$id, (int)$id_lang); + if (count($category)) + { + $this->_menu .= '
  • '.$category->name.''; + $this->getCMSMenuItems($category->id); + $this->_menu .= '
  • '.PHP_EOL; + } + break; + + // Case to handle the option to show all Manufacturers + case 'ALLMAN': + $link = new Link; + $this->_menu .= '
  • '.$this->l('All manufacturers').''; + break; + + case 'MAN': + $selected = ($this->page_name == 'manufacturer' && (Tools::getValue('id_manufacturer') == $id)) ? ' class="sfHover"' : ''; + $manufacturer = new Manufacturer((int)$id, (int)$id_lang); + if (!is_null($manufacturer->id)) + { + if (intval(Configuration::get('PS_REWRITING_SETTINGS'))) + $manufacturer->link_rewrite = Tools::link_rewrite($manufacturer->name); + else + $manufacturer->link_rewrite = 0; + $link = new Link; + $this->_menu .= ''.Tools::safeOutput($manufacturer->name).'
  • '.PHP_EOL; + } + break; + + // Case to handle the option to show all Suppliers + case 'ALLSUP': + $link = new Link; + $this->_menu .= '
  • '.$this->l('All suppliers').''; + break; + + case 'SUP': + $selected = ($this->page_name == 'supplier' && (Tools::getValue('id_supplier') == $id)) ? ' class="sfHover"' : ''; + $supplier = new Supplier((int)$id, (int)$id_lang); + if (!is_null($supplier->id)) + { + $link = new Link; + $this->_menu .= ''.$supplier->name.'
  • '.PHP_EOL; + } + break; + + case 'SHOP': + $selected = ($this->page_name == 'index' && ($this->context->shop->id == $id)) ? ' class="sfHover"' : ''; + $shop = new Shop((int)$id); + if (Validate::isLoadedObject($shop)) + { + $link = new Link; + $this->_menu .= ''.$shop->name.''.PHP_EOL; + } + break; + case 'LNK': + $link = MenuTopLinks::get((int)$id, (int)$id_lang, (int)$id_shop); + if (count($link)) + { + if (!isset($link[0]['label']) || ($link[0]['label'] == '')) + { + $default_language = Configuration::get('PS_LANG_DEFAULT'); + $link = MenuTopLinks::get($link[0]['id_linksmenutop'], $default_language, (int)Shop::getContextShopID()); + } + $this->_menu .= '
  • '.Tools::safeOutput($link[0]['label']).'
  • '.PHP_EOL; + } + break; + } + } + } + + private function generateCategoriesOption($categories, $items_to_skip = null) + { + $html = ''; + + foreach ($categories as $key => $category) + { + if (isset($items_to_skip) && !in_array('CAT'.(int)$category['id_category'], $items_to_skip)) + { + $shop = (object) Shop::getShop((int)$category['id_shop']); + $html .= ''; + } + + if (isset($category['children']) && !empty($category['children'])) + $html .= $this->generateCategoriesOption($category['children'], $items_to_skip); + + } + + return $html; + } + + private function generateCategoriesMenu($categories) + { + $html = ''; + + foreach ($categories as $key => $category) + { + if ($category['level_depth'] > 1) + { + $cat = new Category($category['id_category']); + $link = Tools::HtmlEntitiesUTF8($cat->getLink()); + } + else + $link = $this->context->link->getPageLink('index'); + + $html .= 'page_name == 'category' + && (int)Tools::getValue('id_category') == (int)$category['id_category']) ? ' class="sfHoverForce"' : '').'>'; + $html .= ''.$category['name'].''; + + if (isset($category['children']) && !empty($category['children'])) + { + $html .= '
      '; + $html .= $this->generateCategoriesMenu($category['children']); + + if ((int)$category['level_depth'] == 2) + { + $files = scandir(_PS_CAT_IMG_DIR_); + + if (count($files) > 0) + { + $html .= '
    • '; + + foreach ($files as $file) + if (preg_match('/'.$category['id_category'].'-([0-9])?_thumb.jpg/i', $file) === 1) + $html .= '
      '.Tools::SafeOutput($category['name']).'
      '; + + $html .= '
    • '; + } + } + + $html .= '
    '; + } + + $html .= ''; + } + + return $html; + } + + private function getCMSMenuItems($parent, $depth = 1, $id_lang = false) + { + $id_lang = $id_lang ? (int)$id_lang : (int)Context::getContext()->language->id; + + if ($depth > 3) + return; + + $categories = $this->getCMSCategories(false, (int)$parent, (int)$id_lang); + $pages = $this->getCMSPages((int)$parent); + + if (count($categories) || count($pages)) + { + $this->_menu .= '
      '; + + foreach ($categories as $category) + { + $cat = new CMSCategory((int)$category['id_cms_category'], (int)$id_lang); + + $this->_menu .= '
    • '; + $this->_menu .= ''.$category['name'].''; + $this->getCMSMenuItems($category['id_cms_category'], (int)$depth + 1); + $this->_menu .= '
    • '; + } + + foreach ($pages as $page) + { + $cms = new CMS($page['id_cms'], (int)$id_lang); + $links = $cms->getLinks((int)$id_lang, array((int)$cms->id)); + + $selected = ($this->page_name == 'cms' && ((int)Tools::getValue('id_cms') == $page['id_cms'])) ? ' class="sfHoverForce"' : ''; + $this->_menu .= '
    • '; + $this->_menu .= ''.$cms->meta_title.''; + $this->_menu .= '
    • '; + } + + $this->_menu .= '
    '; + } + } + + private function getCMSOptions($parent = 0, $depth = 1, $id_lang = false, $items_to_skip = null) + { + $html = ''; + $id_lang = $id_lang ? (int)$id_lang : (int)Context::getContext()->language->id; + $categories = $this->getCMSCategories(false, (int)$parent, (int)$id_lang); + $pages = $this->getCMSPages((int)$parent, false, (int)$id_lang); + + $spacer = str_repeat(' ', $this->spacer_size * (int)$depth); + + foreach ($categories as $category) + { + if (isset($items_to_skip) && !in_array('CMS_CAT'.$category['id_cms_category'], $items_to_skip)) + $html .= ''; + $html .= $this->getCMSOptions($category['id_cms_category'], (int)$depth + 1, (int)$id_lang, $items_to_skip); + } + + foreach ($pages as $page) + if (isset($items_to_skip) && !in_array('CMS'.$page['id_cms'], $items_to_skip)) + $html .= ''; + + return $html; + } + + protected function getCacheId($name = null) + { + parent::getCacheId($name); + $page_name = in_array($this->page_name, array('category', 'supplier', 'manufacturer', 'cms', 'product')) ? $this->page_name : 'index'; + return 'blocktopmenu|'.(int)Tools::usingSecureMode().'|'.$page_name.'|'.(int)$this->context->shop->id.'|'.implode(', ',$this->user_groups).'|'.(int)$this->context->language->id.'|'.(int)Tools::getValue('id_category').'|'.(int)Tools::getValue('id_manufacturer').'|'.(int)Tools::getValue('id_supplier').'|'.(int)Tools::getValue('id_cms').'|'.(int)Tools::getValue('id_product'); + } + + public function hookDisplayTop($param) + { + $this->user_groups = ($this->context->customer->isLogged() ? $this->context->customer->getGroups() : array(Configuration::get('PS_UNIDENTIFIED_GROUP'))); + $this->page_name = Dispatcher::getInstance()->getController(); + if (!$this->isCached('blocktopmenu.tpl', $this->getCacheId())) + { + $this->makeMenu(); + $this->smarty->assign('MENU_SEARCH', Configuration::get('MOD_BLOCKTOPMENU_SEARCH')); + $this->smarty->assign('MENU', $this->_menu); + $this->smarty->assign('this_path', $this->_path); + } + + $this->context->controller->addJS($this->_path.'js/hoverIntent.js'); + $this->context->controller->addJS($this->_path.'js/superfish-modified.js'); + $this->context->controller->addJS($this->_path.'js/blocktopmenu.js'); + $this->context->controller->addCSS($this->_path.'css/blocktopmenu.css'); + $this->context->controller->addCSS($this->_path.'css/superfish-modified.css'); + + $html = $this->display(__FILE__, 'blocktopmenu.tpl', $this->getCacheId()); + return $html; + } + + public function hookDisplayNav($params) + { + return $this->hookDisplayTop($params); + } + + private function getCMSCategories($recursive = false, $parent = 1, $id_lang = false) + { + $id_lang = $id_lang ? (int)$id_lang : (int)Context::getContext()->language->id; + + if ($recursive === false) + { + $sql = 'SELECT bcp.`id_cms_category`, bcp.`id_parent`, bcp.`level_depth`, bcp.`active`, bcp.`position`, cl.`name`, cl.`link_rewrite` + FROM `'._DB_PREFIX_.'cms_category` bcp + INNER JOIN `'._DB_PREFIX_.'cms_category_lang` cl + ON (bcp.`id_cms_category` = cl.`id_cms_category`) + WHERE cl.`id_lang` = '.(int)$id_lang.' + AND bcp.`id_parent` = '.(int)$parent; + + return Db::getInstance()->executeS($sql); + } + else + { + $sql = 'SELECT bcp.`id_cms_category`, bcp.`id_parent`, bcp.`level_depth`, bcp.`active`, bcp.`position`, cl.`name`, cl.`link_rewrite` + FROM `'._DB_PREFIX_.'cms_category` bcp + INNER JOIN `'._DB_PREFIX_.'cms_category_lang` cl + ON (bcp.`id_cms_category` = cl.`id_cms_category`) + WHERE cl.`id_lang` = '.(int)$id_lang.' + AND bcp.`id_parent` = '.(int)$parent; + + $results = Db::getInstance()->executeS($sql); + foreach ($results as $result) + { + $sub_categories = $this->getCMSCategories(true, $result['id_cms_category'], (int)$id_lang); + if ($sub_categories && count($sub_categories) > 0) + $result['sub_categories'] = $sub_categories; + $categories[] = $result; + } + + return isset($categories) ? $categories : false; + } + + } + + private function getCMSPages($id_cms_category, $id_shop = false, $id_lang = false) + { + $id_shop = ($id_shop !== false) ? (int)$id_shop : (int)Context::getContext()->shop->id; + $id_lang = $id_lang ? (int)$id_lang : (int)Context::getContext()->language->id; + + $sql = 'SELECT c.`id_cms`, cl.`meta_title`, cl.`link_rewrite` + FROM `'._DB_PREFIX_.'cms` c + INNER JOIN `'._DB_PREFIX_.'cms_shop` cs + ON (c.`id_cms` = cs.`id_cms`) + INNER JOIN `'._DB_PREFIX_.'cms_lang` cl + ON (c.`id_cms` = cl.`id_cms`) + WHERE c.`id_cms_category` = '.(int)$id_cms_category.' + AND cs.`id_shop` = '.(int)$id_shop.' + AND cl.`id_lang` = '.(int)$id_lang.' + AND c.`active` = 1 + ORDER BY `position`'; + + return Db::getInstance()->executeS($sql); + } + + public function hookActionObjectCategoryAddAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectCategoryUpdateAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectCategoryDeleteAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectCmsUpdateAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectCmsDeleteAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectCmsAddAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectSupplierUpdateAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectSupplierDeleteAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectSupplierAddAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectManufacturerUpdateAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectManufacturerDeleteAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectManufacturerAddAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectProductUpdateAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectProductDeleteAfter($params) + { + $this->clearMenuCache(); + } + + public function hookActionObjectProductAddAfter($params) + { + $this->clearMenuCache(); + } + + public function hookCategoryUpdate($params) + { + $this->clearMenuCache(); + } + + private function clearMenuCache() + { + $this->_clearCache('blocktopmenu.tpl'); + } + + public function hookActionShopDataDuplication($params) + { + $linksmenutop = Db::getInstance()->executeS(' + SELECT * + FROM '._DB_PREFIX_.'linksmenutop + WHERE id_shop = '.(int)$params['old_id_shop'] + ); + + foreach($linksmenutop as $id => $link) + { + Db::getInstance()->execute(' + INSERT IGNORE INTO '._DB_PREFIX_.'linksmenutop (id_linksmenutop, id_shop, new_window) + VALUES (null, '.(int)$params['new_id_shop'].', '.(int)$link['new_window'].')'); + + $linksmenutop[$id]['new_id_linksmenutop'] = Db::getInstance()->Insert_ID(); + } + + foreach($linksmenutop as $id => $link) + { + $lang = Db::getInstance()->executeS(' + SELECT id_lang, '.(int)$params['new_id_shop'].', label, link + FROM '._DB_PREFIX_.'linksmenutop_lang + WHERE id_linksmenutop = '.(int)$link['id_linksmenutop'].' AND id_shop = '.(int)$params['old_id_shop']); + + foreach($lang as $l) + Db::getInstance()->execute(' + INSERT IGNORE INTO '._DB_PREFIX_.'linksmenutop_lang (id_linksmenutop, id_lang, id_shop, label, link) + VALUES ('.(int)$link['new_id_linksmenutop'].', '.(int)$l['id_lang'].', '.(int)$params['new_id_shop'].', '.(int)$l['label'].', '.(int)$l['link'].' )'); + } + } + + public function renderForm() + { + $fields_form = array( + 'form' => array( + 'legend' => array( + 'title' => $this->l('Menu Top Link'), + 'icon' => 'icon-link' + ), + 'input' => array( + array( + 'type' => 'link_choice', + 'label' => '', + 'name' => 'link', + 'lang' => true, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Search bar'), + 'name' => 'search', + 'is_bool' => true, + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + ) + ), + 'submit' => array( + 'name' => 'submitBlocktopmenu', + 'title' => $this->l('Save') + ) + ), + ); + + if (Shop::isFeatureActive()) + $fields_form['form']['description'] = $this->l('The modifications will be applied to').' '.(Shop::getContext() == Shop::CONTEXT_SHOP ? $this->l('shop').' '.$this->context->shop->name : $this->l('all shops')); + + $helper = new HelperForm(); + $helper->show_toolbar = false; + $helper->table = $this->table; + $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + $helper->default_form_language = $lang->id; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $this->fields_form = array(); + $helper->module = $this; + $helper->identifier = $this->identifier; + $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + $helper->tpl_vars = array( + 'fields_value' => $this->getConfigFieldsValues(), + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + 'choices' => $this->renderChoicesSelect(), + 'selected_links' => $this->makeMenuOption(), + ); + return $helper->generateForm(array($fields_form)); + } + + public function renderAddForm() + { + $fields_form = array( + 'form' => array( + 'legend' => array( + 'title' => (Tools::getIsset('updatelinksmenutop') && !Tools::getValue('updatelinksmenutop')) ? $this->l('Update link') : $this->l('Add a new link'), + 'icon' => 'icon-link' + ), + 'input' => array( + array( + 'type' => 'text', + 'label' => $this->l('Label'), + 'name' => 'label', + 'lang' => true, + ), + array( + 'type' => 'text', + 'label' => $this->l('Link'), + 'name' => 'link', + 'lang' => true, + ), + array( + 'type' => 'switch', + 'label' => $this->l('New window'), + 'name' => 'new_window', + 'is_bool' => true, + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + ) + ), + 'submit' => array( + 'name' => 'submitBlocktopmenuLinks', + 'title' => $this->l('Add') + ) + ), + ); + + $helper = new HelperForm(); + $helper->show_toolbar = false; + $helper->table = $this->table; + $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + $helper->default_form_language = $lang->id; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $this->fields_form = array(); + $helper->identifier = $this->identifier; + $helper->fields_value = $this->getAddLinkFieldsValues(); + + if (Tools::getIsset('updatelinksmenutop') && !Tools::getValue('updatelinksmenutop')) + $fields_form['form']['submit'] = array( + 'name' => 'updatelinksmenutop', + 'title' => $this->l('Update') + ); + + if (Tools::isSubmit('updatelinksmenutop')) + { + $fields_form['form']['input'][] = array('type' => 'hidden', 'name' => 'updatelink'); + $fields_form['form']['input'][] = array('type' => 'hidden', 'name' => 'id_linksmenutop'); + $helper->fields_value['updatelink'] = ''; + } + + $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + $helper->languages =$this->context->controller->getLanguages(); + $helper->default_form_language = (int)$this->context->language->id; + + return $helper->generateForm(array($fields_form)); + } + + public function renderChoicesSelect() + { + $spacer = str_repeat(' ', $this->spacer_size); + $items = $this->getMenuItems(); + + $html = ''; + return $html; + } + + public function getConfigFieldsValues() + { + return array( + 'search' => Tools::getValue('search', Configuration::get('MOD_BLOCKTOPMENU_SEARCH')) + ); + } + + public function getAddLinkFieldsValues() + { + $links_label_edit = ''; + $labels_edit = ''; + $new_window_edit = ''; + + if (Tools::isSubmit('updatelinksmenutop')) + { + $link = MenuTopLinks::getLinkLang(Tools::getValue('id_linksmenutop'), (int)Shop::getContextShopID()); + $links_label_edit = $link['link']; + $labels_edit = $link['label']; + $new_window_edit = $link['new_window']; + } + + $fields_values = array( + 'new_window' => Tools::getValue('new_window', $new_window_edit), + 'id_linksmenutop' => Tools::getValue('id_linksmenutop'), + ); + + if (Tools::getValue('submitAddmodule')) + { + foreach (Language::getLanguages(false) as $lang) + { + $fields_values['label'][$lang['id_lang']] = ''; + $fields_values['link'][$lang['id_lang']] = ''; + } + } + else + foreach (Language::getLanguages(false) as $lang) + { + $fields_values['label'][$lang['id_lang']] = Tools::getValue('label_'.(int)$lang['id_lang'], isset($labels_edit[$lang['id_lang']]) ? $labels_edit[$lang['id_lang']] : ''); + $fields_values['link'][$lang['id_lang']] = Tools::getValue('link_'.(int)$lang['id_lang'], isset($links_label_edit[$lang['id_lang']]) ? $links_label_edit[$lang['id_lang']] : ''); + } + + return $fields_values; + } + + public function renderList() + { + $links = MenuTopLinks::gets((int)$this->context->language->id, null, (int)Shop::getContextShopID()); + $fields_list = array( + 'id_linksmenutop' => array( + 'title' => $this->l('Link ID'), + 'type' => 'text', + ), + 'label' => array( + 'title' => $this->l('Label'), + 'type' => 'text', + ), + 'link' => array( + 'title' => $this->l('Link'), + 'type' => 'link', + ), + 'new_window' => array( + 'title' => $this->l('New window'), + 'type' => 'bool', + 'align' => 'center', + 'active' => 'status', + ) + ); + + $helper = new HelperList(); + $helper->shopLinkType = ''; + $helper->simple_header = true; + $helper->identifier = 'id_linksmenutop'; + $helper->table = 'linksmenutop'; + $helper->actions = array('edit', 'delete'); + $helper->show_toolbar = false; + $helper->module = $this; + $helper->title = $this->l('Link list'); + $helper->token = Tools::getAdminTokenLite('AdminModules'); + $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name; + + return $helper->generateList($links, $fields_list); + } +} diff --git a/blocktopmenu.tpl b/blocktopmenu.tpl new file mode 100644 index 0000000..cf8d86f --- /dev/null +++ b/blocktopmenu.tpl @@ -0,0 +1,24 @@ +{if $MENU != ''} + + +
    +
      + {$MENU} + {if $MENU_SEARCH} + + {/if} +
    +
    +
     
    + + +{/if} \ No newline at end of file diff --git a/config.xml b/config.xml new file mode 100644 index 0000000..76341a5 --- /dev/null +++ b/config.xml @@ -0,0 +1,12 @@ + + + blocktopmenu + + + + + + 1 + 1 + + \ No newline at end of file diff --git a/css/blocktopmenu.css b/css/blocktopmenu.css new file mode 100644 index 0000000..e69de29 diff --git a/css/index.php b/css/index.php new file mode 100644 index 0000000..0df7996 --- /dev/null +++ b/css/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/css/superfish-modified.css b/css/superfish-modified.css new file mode 100644 index 0000000..ff46789 --- /dev/null +++ b/css/superfish-modified.css @@ -0,0 +1,172 @@ +/*** ESSENTIAL STYLES ***/ +.sf-contener { + clear: both; +} +.sf-right { + margin-right: 14px; + float: right; + width: 7px; +} +.sf-menu, .sf-menu * { + margin: 0; + padding: 0; + list-style: none; +} +.sf-menu { + margin: 10px 0; + padding:0; + width:980px;/* 980 */ + background: #383838; +} +.sf-menu ul { + position: absolute; + top: -999em; + width: 10em; /* left offset of submenus need to match (see below) */ +} +.sf-menu ul li { + width: 100%; +} +.sf-menu li:hover { + visibility: inherit; /* fixes IE7 'sticky bug' */ +} +.sf-menu li { + float: left; + position: relative; + border-right: 1px solid #777; +} +.sf-menu a { + display: block; + position: relative; + color:#fff; + text-shadow:0 1px 0 #333; +} +.sf-menu li:hover ul, +.sf-menu li.sfHover ul { + left: 0; + top: 34px; /* match top ul list item height */ + z-index: 99; + width:auto +} +ul.sf-menu li:hover li ul, +ul.sf-menu li.sfHover li ul { + top: -999em; +} +ul.sf-menu li li:hover ul, +ul.sf-menu li li.sfHover ul { + left: 200px; /* match ul width */ + top: 0; +} +ul.sf-menu li li:hover li ul, +ul.sf-menu li li.sfHover li ul { + top: -999em; +} +ul.sf-menu li li li:hover ul, +ul.sf-menu li li li.sfHover ul { + left: 200px; /* match ul width */ + top: 0; +} + +/*** DEMO SKIN ***/ +.sf-menu { + float: left; + margin-bottom: 1em; +} +.sf-menu a { + display:block; + margin-right:2px; + padding: 0 22px 0 20px; + line-height:34px; + border: 0; + text-decoration:none; +} +.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/ + color: #fff; + white-space:nowrap; +} +.sf-menu li li { + background: rgba(113, 113, 113, 0.9); +} +.sf-menu li li li { + background: rgba(113, 113, 113, 0.9); +} +.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active { + background: #4E4E4E; +} +.sf-menu ul li:hover, .sf-menu ul li.sfHover, +.sf-menu ul li a:focus, .sf-menu ul li a:hover, .sf-menu ul li a:active { + background: #4e4e4e; + outline: 0; +} +/*** arrows **/ +.sf-menu a.sf-with-ul { + padding-right: 2.25em; + min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */ +} +.sf-sub-indicator { + position: absolute; + display: block; + right: 10px; + top: 1.05em; /* IE6 only */ + width: 10px; + height: 10px; + text-indent: -999em; + overflow: hidden; + background: url('../img/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ +} +a > .sf-sub-indicator { /* give all except IE6 the correct values */ + top: 11px; + background-position: 0 -100px; /* use translucent arrow for modern browsers*/ +} +/* apply hovers to modern browsers */ +a:focus > .sf-sub-indicator, +a:hover > .sf-sub-indicator, +a:active > .sf-sub-indicator, +li:hover > a > .sf-sub-indicator, +li.sfHover > a > .sf-sub-indicator { + background-position: -10px -100px; /* arrow hovers for modern browsers*/ +} + +/* point right for anchors in subs */ +.sf-menu ul .sf-sub-indicator { background-position: -10px 0; } +.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; } +/* apply hovers to modern browsers */ +.sf-menu ul a:focus > .sf-sub-indicator, +.sf-menu ul a:hover > .sf-sub-indicator, +.sf-menu ul a:active > .sf-sub-indicator, +.sf-menu ul li:hover > a > .sf-sub-indicator, +.sf-menu ul li.sfHover > a > .sf-sub-indicator { + background-position: -10px 0; /* arrow hovers for modern browsers*/ +} + +/*** shadows for all but IE6 ***/ +.sf-shadow ul { + background: url('../img/shadow.png') no-repeat bottom right; + padding: 0 8px 9px 0; + -moz-border-bottom-left-radius: 17px; + -moz-border-top-right-radius: 17px; + -webkit-border-top-right-radius: 17px; + -webkit-border-bottom-left-radius: 17px; +} +.sf-shadow ul.sf-shadow-off { + background: transparent; +} +li.sf-search { + background: inherit; + float: right; + line-height: 25px; +} +li.sf-search input { + -moz-border-radius: 0 5px 5px 0; + padding: 3px 0; + padding-left: 20px; + margin: 6px 6px 0 0; + background: #fff url('../img/search.gif') no-repeat left center; + border:1px solid #777 +} + +/* hack IE7 */ +.sf-menu a, .sf-menu a:visited {height:34px !IE;} +.sf-menu li li { + width:200px; + background:#726f72 !IE; +} diff --git a/img/arrows-ffffff.png b/img/arrows-ffffff.png new file mode 100644 index 0000000..246dd91 Binary files /dev/null and b/img/arrows-ffffff.png differ diff --git a/img/bg_blocktopmenu_li_seleted.png b/img/bg_blocktopmenu_li_seleted.png new file mode 100644 index 0000000..57fe03c Binary files /dev/null and b/img/bg_blocktopmenu_li_seleted.png differ diff --git a/img/blocktopmenu.gif b/img/blocktopmenu.gif new file mode 100644 index 0000000..b4b507d Binary files /dev/null and b/img/blocktopmenu.gif differ diff --git a/img/blocktopmenu_hover.gif b/img/blocktopmenu_hover.gif new file mode 100644 index 0000000..09f9c0a Binary files /dev/null and b/img/blocktopmenu_hover.gif differ diff --git a/img/blocktopmenu_left.gif b/img/blocktopmenu_left.gif new file mode 100644 index 0000000..5898043 Binary files /dev/null and b/img/blocktopmenu_left.gif differ diff --git a/img/blocktopmenu_right.gif b/img/blocktopmenu_right.gif new file mode 100644 index 0000000..d8ab241 Binary files /dev/null and b/img/blocktopmenu_right.gif differ diff --git a/img/index.php b/img/index.php new file mode 100644 index 0000000..0df7996 --- /dev/null +++ b/img/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/img/search.gif b/img/search.gif new file mode 100644 index 0000000..e32a989 Binary files /dev/null and b/img/search.gif differ diff --git a/img/shadow.png b/img/shadow.png new file mode 100644 index 0000000..87c54bd Binary files /dev/null and b/img/shadow.png differ diff --git a/index.php b/index.php new file mode 100644 index 0000000..0df7996 --- /dev/null +++ b/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/js/blocktopmenu.js b/js/blocktopmenu.js new file mode 100644 index 0000000..e69de29 diff --git a/js/hoverIntent.js b/js/hoverIntent.js new file mode 100644 index 0000000..91da57b --- /dev/null +++ b/js/hoverIntent.js @@ -0,0 +1,84 @@ +(function($){ + /* hoverIntent by Brian Cherne */ + $.fn.hoverIntent = function(f,g) { + // default configuration options + var cfg = { + sensitivity: 7, + interval: 100, + timeout: 0 + }; + // override configuration options with user supplied object + cfg = $.extend(cfg, g ? { over: f, out: g } : f ); + + // instantiate variables + // cX, cY = current X and Y position of mouse, updated by mousemove event + // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval + var cX, cY, pX, pY; + + // A private function for getting mouse position + var track = function(ev) { + cX = ev.pageX; + cY = ev.pageY; + }; + + // A private function for comparing current and previous mouse position + var compare = function(ev,ob) { + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); + // compare mouse positions to see if they've crossed the threshold + if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { + $(ob).unbind("mousemove",track); + // set hoverIntent state to true (so mouseOut can be called) + ob.hoverIntent_s = 1; + return cfg.over.apply(ob,[ev]); + } else { + // set previous coordinates for next time + pX = cX; pY = cY; + // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) + ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); + } + }; + + // A private function for delaying the mouseOut function + var delay = function(ev,ob) { + ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); + ob.hoverIntent_s = 0; + return cfg.out.apply(ob,[ev]); + }; + + // A private function for handling mouse 'hovering' + var handleHover = function(e) { + // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut + var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; + while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } } + if ( p == this ) { return false; } + + // copy objects to be passed into t (required for event object to be passed in IE) + var ev = jQuery.extend({},e); + var ob = this; + + // cancel hoverIntent timer if it exists + if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } + + // else e.type == "onmouseover" + if (e.type == "mouseover") { + // set "previous" X and Y position based on initial entry point + pX = ev.pageX; pY = ev.pageY; + // update "current" X and Y position based on mousemove + $(ob).bind("mousemove",track); + // start polling interval (self-calling timeout) to compare mouse coordinates over time + if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} + + // else e.type == "onmouseout" + } else { + // unbind expensive mousemove event + $(ob).unbind("mousemove",track); + // if hoverIntent state is true, then call the mouseOut function after the specified delay + if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} + } + }; + + // bind the function to the two event listeners + return this.mouseover(handleHover).mouseout(handleHover); + }; + +})(jQuery); \ No newline at end of file diff --git a/js/index.php b/js/index.php new file mode 100644 index 0000000..0df7996 --- /dev/null +++ b/js/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/js/superfish-modified.js b/js/superfish-modified.js new file mode 100644 index 0000000..0635741 --- /dev/null +++ b/js/superfish-modified.js @@ -0,0 +1,124 @@ + +/* + * Superfish v1.4.8 - jQuery menu widget + * Copyright (c) 2008 Joel Birch + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt + */ + +(function($){ + $.fn.superfish = function(op){ + + var sf = $.fn.superfish, + c = sf.c, + $arrow = $([' »'].join('')), + over = function(){ + var $$ = $(this), menu = getMenu($$); + clearTimeout(menu.sfTimer); + $$.showSuperfishUl().siblings().hideSuperfishUl(); + }, + out = function(){ + var $$ = $(this), menu = getMenu($$), o = sf.op; + clearTimeout(menu.sfTimer); + menu.sfTimer=setTimeout(function(){ + o.retainPath=($.inArray($$[0],o.$path)>-1); + $$.hideSuperfishUl(); + if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);} + },o.delay); + }, + getMenu = function($menu){ + var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0]; + sf.op = sf.o[menu.serial]; + return menu; + }, + addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); }; + + return this.each(function() { + var s = this.serial = sf.o.length; + var o = $.extend({},sf.defaults,op); + o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){ + $(this).addClass([o.hoverClass,c.bcClass].join(' ')) + .filter('li:has(ul)').removeClass(o.pathClass); + }); + sf.o[s] = sf.op = o; + + $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() { + if (o.autoArrows) addArrow( $('>a:first-child',this) ); + }) + .not('.'+c.bcClass) + .hideSuperfishUl(); + + var $a = $('a',this); + $a.each(function(i){ + var $li = $a.eq(i).parents('li'); + $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);}); + }); + o.onInit.call(this); + + }).each(function() { + menuClasses = [c.menuClass]; + if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass); + $(this).addClass(menuClasses.join(' ')); + }); + }; + + var sf = $.fn.superfish; + sf.o = []; + sf.op = {}; + sf.IE7fix = function(){ + var o = sf.op; + if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined) + this.toggleClass(sf.c.shadowClass+'-off'); + }; + sf.c = { + bcClass : 'sf-breadcrumb', + menuClass : 'sf-js-enabled', + anchorClass : 'sf-with-ul', + arrowClass : 'sf-sub-indicator', + shadowClass : 'sf-shadow' + }; + sf.defaults = { + hoverClass : 'sfHover', + pathClass : 'overideThisToUse', + pathLevels : 1, + delay : 800, + animation : {opacity:'show'}, + speed : 'fast', + autoArrows : true, + dropShadows : true, + disableHI : false, // true disables hoverIntent detection + onInit : function(){}, // callback functions + onBeforeShow: function(){}, + onShow : function(){}, + onHide : function(){} + }; + $.fn.extend({ + hideSuperfishUl : function(){ + var o = sf.op, + not = (o.retainPath===true) ? o.$path : ''; + o.retainPath = false; + var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass) + .find('>ul').hide().css('visibility','hidden'); + o.onHide.call($ul); + return this; + }, + showSuperfishUl : function(){ + var o = sf.op, + sh = sf.c.shadowClass+'-off', + $ul = this.addClass(o.hoverClass) + .find('>ul:hidden').css('visibility','visible'); + sf.IE7fix.call($ul); + o.onBeforeShow.call($ul); + $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); }); + return this; + } + }); + +})(jQuery); +jQuery(function(){ + jQuery('ul.sf-menu').superfish(); +}); \ No newline at end of file diff --git a/logo.gif b/logo.gif new file mode 100644 index 0000000..5e0095b Binary files /dev/null and b/logo.gif differ diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..743bdf9 Binary files /dev/null and b/logo.png differ diff --git a/menutoplinks.class.php b/menutoplinks.class.php new file mode 100644 index 0000000..c50d9b0 --- /dev/null +++ b/menutoplinks.class.php @@ -0,0 +1,134 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +class MenuTopLinks +{ + public static function gets($id_lang, $id_linksmenutop = null, $id_shop) + { + $sql = 'SELECT l.id_linksmenutop, l.new_window, ll.link, ll.label + FROM '._DB_PREFIX_.'linksmenutop l + LEFT JOIN '._DB_PREFIX_.'linksmenutop_lang ll ON (l.id_linksmenutop = ll.id_linksmenutop AND ll.id_lang = '.(int)$id_lang.' AND ll.id_shop='.(int)$id_shop.') + WHERE 1 '.((!is_null($id_linksmenutop)) ? ' AND l.id_linksmenutop = "'.(int)$id_linksmenutop.'"' : '').' + AND l.id_shop IN (0, '.(int)$id_shop.')'; + + return Db::getInstance()->executeS($sql); + } + + public static function get($id_linksmenutop, $id_lang, $id_shop) + { + return self::gets($id_lang, $id_linksmenutop, $id_shop); + } + + public static function getLinkLang($id_linksmenutop, $id_shop) + { + $ret = Db::getInstance()->executeS(' + SELECT l.id_linksmenutop, l.new_window, ll.link, ll.label, ll.id_lang + FROM '._DB_PREFIX_.'linksmenutop l + LEFT JOIN '._DB_PREFIX_.'linksmenutop_lang ll ON (l.id_linksmenutop = ll.id_linksmenutop AND ll.id_shop='.(int)$id_shop.') + WHERE 1 + '.((!is_null($id_linksmenutop)) ? ' AND l.id_linksmenutop = "'.(int)$id_linksmenutop.'"' : '').' + AND l.id_shop IN (0, '.(int)$id_shop.') + '); + + $link = array(); + $label = array(); + $new_window = false; + + foreach ($ret as $line) + { + $link[$line['id_lang']] = Tools::safeOutput($line['link']); + $label[$line['id_lang']] = Tools::safeOutput($line['label']); + $new_window = (bool)$line['new_window']; + } + + return array('link' => $link, 'label' => $label, 'new_window' => $new_window); + } + + public static function add($link, $label, $newWindow = 0, $id_shop) + { + if(!is_array($label)) + return false; + if(!is_array($link)) + return false; + + Db::getInstance()->insert( + 'linksmenutop', + array( + 'new_window'=>(int)$newWindow, + 'id_shop' => (int)$id_shop + ) + ); + $id_linksmenutop = Db::getInstance()->Insert_ID(); + + foreach ($label as $id_lang=>$label) + Db::getInstance()->insert( + 'linksmenutop_lang', + array( + 'id_linksmenutop'=>(int)$id_linksmenutop, + 'id_lang'=>(int)$id_lang, + 'id_shop'=>(int)$id_shop, + 'label'=>pSQL($label), + 'link'=>pSQL($link[$id_lang]) + ) + ); + } + + public static function update($link, $labels, $newWindow = 0, $id_shop, $id_link) + { + if(!is_array($labels)) + return false; + if(!is_array($link)) + return false; + + Db::getInstance()->update( + 'linksmenutop', + array( + 'new_window'=>(int)$newWindow, + 'id_shop' => (int)$id_shop + ), + 'id_linksmenutop = '.(int)$id_link + ); + + foreach ($labels as $id_lang => $label) + Db::getInstance()->update( + 'linksmenutop_lang', + array( + 'id_shop'=>(int)$id_shop, + 'label'=>pSQL($label), + 'link'=>pSQL($link[$id_lang]) + ), + 'id_linksmenutop = '.(int)$id_link.' AND id_lang = '.(int)$id_lang + ); + } + + + public static function remove($id_linksmenutop, $id_shop) + { + Db::getInstance()->delete('linksmenutop', 'id_linksmenutop = '.(int)$id_linksmenutop.' AND id_shop = '.(int)$id_shop); + Db::getInstance()->delete('linksmenutop_lang', 'id_linksmenutop = '.(int)$id_linksmenutop); + } + +} diff --git a/translations/index.php b/translations/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/translations/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/upgrade/install-1.6.php b/upgrade/install-1.6.php new file mode 100644 index 0000000..9018355 --- /dev/null +++ b/upgrade/install-1.6.php @@ -0,0 +1,9 @@ +registerHook('actionObjectCategoryAddAfter')); +} diff --git a/views/index.php b/views/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/admin/_configure/helpers/form/form.tpl b/views/templates/admin/_configure/helpers/form/form.tpl new file mode 100644 index 0000000..76a9242 --- /dev/null +++ b/views/templates/admin/_configure/helpers/form/form.tpl @@ -0,0 +1,125 @@ +{* +* 2007-2014 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + +{extends file="helpers/form/form.tpl"} + +{block name="script"} +$(document).ready(function(){ +$('#menuOrderUp').click(function(e){ + e.preventDefault(); + move(true); +}); +$('#menuOrderDown').click(function(e){ + e.preventDefault(); + move(); +}); +$("#items").closest('form').on('submit', function(e) { + $("#items option").prop('selected', true); +}); +$("#addItem").click(add); +$("#availableItems").dblclick(add); +$("#removeItem").click(remove); +$("#items").dblclick(remove); +function add() +{ + $("#availableItems option:selected").each(function(i){ + var val = $(this).val(); + var text = $(this).text(); + text = text.replace(/(^\s*)|(\s*$)/gi,""); + if (val == "PRODUCT") + { + val = prompt('{l s="Set ID product" mod='blocktopmenu' js=1}'); + if (val == null || val == "" || isNaN(val)) + return; + text = '{l s="Product ID" mod='blocktopmenu' js=1}'+val; + val = "PRD"+val; + } + $("#items").append(''); + }); + serialize(); + return false; +} +function remove() +{ + $("#items option:selected").each(function(i){ + $(this).remove(); + }); + serialize(); + return false; +} +function serialize() +{ + var options = ""; + $("#items option").each(function(i){ + options += $(this).val()+","; + }); + $("#itemsInput").val(options.substr(0, options.length - 1)); +} +function move(up) +{ + var tomove = $('#items option:selected'); + if (tomove.length >1) + { + alert('{l s="Please select just one item" mod='blocktopmenu'}'); + return false; + } + if (up) + tomove.prev().insertAfter(tomove); + else + tomove.next().insertBefore(tomove); + serialize(); + return false; +} +}); +{/block} + +{block name="input"} + {if $input.type == 'link_choice'} +
    +
    +

    {l s='Change position' mod='blocktopmenu'}

    +
    +
    +
    +
    +

    {l s='Selected items' mod='blocktopmenu'}

    + {$selected_links} +
    +
    +

    {l s='Available items' mod='blocktopmenu'}

    + {$choices} +
    + +
    +
    + + {else} + {$smarty.block.parent} + {/if} +{/block} diff --git a/views/templates/admin/_configure/helpers/form/index.php b/views/templates/admin/_configure/helpers/form/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/admin/_configure/helpers/form/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/admin/_configure/helpers/index.php b/views/templates/admin/_configure/helpers/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/admin/_configure/helpers/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/admin/_configure/helpers/list/index.php b/views/templates/admin/_configure/helpers/list/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/admin/_configure/helpers/list/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/admin/_configure/helpers/list/list_content.tpl b/views/templates/admin/_configure/helpers/list/list_content.tpl new file mode 100644 index 0000000..f74b1cb --- /dev/null +++ b/views/templates/admin/_configure/helpers/list/list_content.tpl @@ -0,0 +1,34 @@ +{* +* 2007-2014 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + +{extends file="helpers/list/list_content.tpl"} + +{block name="td_content"} + {if isset($params.type) && $params.type == 'link'} + {$tr.$key|escape:'html':'UTF-8'} + {else} + {$smarty.block.parent} + {/if} +{/block} diff --git a/views/templates/admin/_configure/index.php b/views/templates/admin/_configure/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/admin/_configure/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/admin/index.php b/views/templates/admin/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/admin/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/views/templates/index.php b/views/templates/index.php new file mode 100644 index 0000000..a41987d --- /dev/null +++ b/views/templates/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file