diff --git a/modules/leobootstrapmenu/Readme.md b/modules/leobootstrapmenu/Readme.md new file mode 100644 index 00000000..448852dd --- /dev/null +++ b/modules/leobootstrapmenu/Readme.md @@ -0,0 +1,4 @@ +# Onlide guide +http://www.leotheme.com/support/prestashop-16x-guides.html + + diff --git a/modules/leobootstrapmenu/classes/Btmegamenu.php b/modules/leobootstrapmenu/classes/Btmegamenu.php new file mode 100644 index 00000000..18b78485 --- /dev/null +++ b/modules/leobootstrapmenu/classes/Btmegamenu.php @@ -0,0 +1,1202 @@ + + * @copyright 2007-2015 Leotheme + * @license http://leotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class Btmegamenu extends ObjectModel +{ + public $id; + public $id_btmegamenu; + public $id_group; + public $image; + public $icon_class; + public $id_parent = 0; + public $is_group = 0; + public $width; + public $submenu_width; + public $submenu_colum_width; + public $item; + public $item_parameter; + public $colums = 1; + public $type; + public $is_content = 0; + public $show_title = 1; + public $level_depth; + public $active = 1; + public $position; + public $show_sub; + public $url; + public $target; + public $privacy; + public $position_type; + public $menu_class; + public $content; + public $submenu_content; + public $level; + public $left; + public $right; + public $date_add; + public $date_upd; + # Lang + public $title; + public $text; + public $description; + public $content_text; + public $submenu_catids; + public $is_cattree = 1; + private $shop_url; + private $edit_string = ''; + private $mega_config = array(); + private $edit_string_col = ''; + public $is_live_edit = true; + private $leo_module = null; + public $id_shop = ''; + // Default for import datasameple + public $groupBox = 'all'; + public $sub_with; + public $params_widget; + + public function setModule($module) + { + $this->leo_module = $module; + } + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'btmegamenu', + 'primary' => 'id_btmegamenu', + 'multilang' => true, + 'fields' => array( + 'id_group' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), + 'image' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName'), + 'id_parent' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), + 'is_group' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true), + 'width' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 255), + 'submenu_width' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 255), + 'submenu_colum_width' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'item' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 255), + 'item_parameter' => array('type' => self::TYPE_STRING, 'validate' => 'isString'), + 'colums' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'size' => 255), + 'type' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 255), + 'is_content' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'show_title' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'is_cattree' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'level_depth' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'), + 'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true), + 'position' => array('type' => self::TYPE_INT), + 'show_sub' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'url' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isUrl', 'size' => 255), + 'target' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 25), + 'privacy' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'size' => 6), + 'position_type' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 25), + 'menu_class' => array('type' => self::TYPE_STRING, 'validate' => 'isCatalogName', 'size' => 255), + 'icon_class' => array('type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'size' => 125), + 'content' => array('type' => self::TYPE_STRING, 'validate' => 'isString'), + 'submenu_content' => array('type' => self::TYPE_STRING, 'validate' => 'isString'), + 'level' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'), + 'left' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'), + 'right' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'), + 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat'), + 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat'), + 'sub_with' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true, 'size' => 255), + 'groupBox' => array('type' => self::TYPE_STRING, 'size' => 255), + 'params_widget' => array('type' => self::TYPE_HTML, 'validate' => 'isString'), + # Lang fields + 'title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 255), + 'text' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => false, 'size' => 255), + 'description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCleanHtml'), + 'content_text' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'), + 'submenu_catids' => array('type' => self::TYPE_STRING, 'lang' => false, 'validate' => 'isString'), + + ), + ); + + public static function getMenus() + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $id_lang = $context->language->id; + $cacheId = 'leobootstrapmenu_classes_Btmegamenu.php_____getMenus()_' . md5($id_shop.$id_lang); + + if (!Cache::isStored($cacheId)) { + $sql = 'SELECT m.*, ml.* + FROM '._DB_PREFIX_.'btmegamenu m + LEFT JOIN '._DB_PREFIX_.'btmegamenu_lang ml ON m.id_btmegamenu = ml.id_btmegamenu AND ml.id_lang = '.(int)$id_lang + .' JOIN '._DB_PREFIX_.'btmegamenu_shop ms ON m.id_btmegamenu = ms.id_btmegamenu AND ms.id_shop = '.(int)$id_shop + .' WHERE m.`active` = 1 ORDER BY `position` '; + + $result = Db::getInstance()->executes($sql); + Cache::store($cacheId, $result); + } else { + $result = Cache::retrieve($cacheId); + } + return $result; + } + + /** + * $key : field in db + * $value : value in db + * $one : default return one record + */ + public static function cacheMenusByFields($params = array(), $one = false) + { + $result = array(); + + $menus = self::getMenus(); + foreach ($menus as $menu) { + $check_field = true; + foreach ($params as $key => $value) { + if ($menu[$key] != $value) { + $check_field = false; + break; + } + } + + if ($check_field) { + if ($one === false) { + $result = $menu; + break; + } else { + $result[] = $menu; + } + } + } + + return $result; + } + + public function copyFromPost($post = array()) + { + /* Classical fields */ + foreach ($post as $key => $value) { + if (key_exists($key, $this) && $key != 'id_'.$this->table) { + $this->{$key} = $value; + } + } + /* Multilingual fields */ + if (count($this->fieldsValidateLang)) { + $languages = Language::getLanguages(false); + foreach ($languages as $language) { + foreach ($this->fieldsValidateLang as $field => $validation) { + if (Tools::getIsset($field.'_'.(int)$language['id_lang'])) { + $this->{$field}[(int)$language['id_lang']] = Tools::getValue($field.'_'.(int)$language['id_lang']); + } + + # validate module + unset($validation); + } + } + } + $this->groupBox = implode(',', $this->groupBox); + } + + public function add($autodate = true, $null_values = false) + { + if (isset($this->import_datasample) && $this->import_datasample == true) { + // Datasample + $this->groupBox = 'all'; + } + $this->level_depth = $this->calcLevelDepth(); + $id_shop = LeoBtmegamenuHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $sql = 'INSERT INTO `'._DB_PREFIX_.'btmegamenu_shop` (`id_shop`, `id_btmegamenu`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'; + $res &= Db::getInstance()->execute($sql); + return $res; + } + + public function update($null_values = false) + { + $this->level_depth = $this->calcLevelDepth(); + return parent::update($null_values); + } + + protected function recursiveDelete(&$to_delete, $id_btmegamenu) + { + if (!is_array($to_delete) || !$id_btmegamenu) { + die(Tools::displayError()); + } + + $result = Db::getInstance()->executeS(' + SELECT `id_btmegamenu` + FROM `'._DB_PREFIX_.'btmegamenu` + WHERE `id_parent` = '.(int)$id_btmegamenu); + foreach ($result as $row) { + $to_delete[] = (int)$row['id_btmegamenu']; + $this->recursiveDelete($to_delete, (int)$row['id_btmegamenu']); + } + } + + public function delete() + { + $this->clearCache(); + + // Get children categories + $to_delete = array((int)$this->id); + $this->recursiveDelete($to_delete, (int)$this->id); + $to_delete = array_unique($to_delete); + + // Delete CMS Category and its child from database + $list = count($to_delete) > 1 ? implode(',', array_map('intval', $to_delete)) : (int)$this->id; + Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'btmegamenu` WHERE `id_btmegamenu` IN ('.pSQL($list).')'); + Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'btmegamenu_shop` WHERE `id_btmegamenu` IN ('.pSQL($list).')'); + Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'btmegamenu_lang` WHERE `id_btmegamenu` IN ('.pSQL($list).')'); + Btmegamenu::cleanPositions($this->id_parent); + return true; + } + + public function deleteSelection($menus) + { + $return = 1; + foreach ($menus as $id_btmegamenu) { + $obj_menu = new Btmegamenu($id_btmegamenu); + $return &= $obj_menu->delete(); + } + return $return; + } + + public function calcLevelDepth() + { + $parent_btmegamenu = new Btmegamenu($this->id_parent); + if (!$parent_btmegamenu) { + die('parent Menu does not exist'); + } + return $parent_btmegamenu->level_depth + 1; + } + + public function updatePosition($way, $position) + { + $sql = ' + SELECT cp.`id_btmegamenu`, cp.`position`, cp.`id_parent` + FROM `'._DB_PREFIX_.'btmegamenu` cp + WHERE cp.`id_parent` = '.(int)$this->id_parent.' + ORDER BY cp.`position` ASC'; + if (!$res = Db::getInstance()->executeS($sql)) { + return false; + } + foreach ($res as $menu) { + if ((int)$menu['id_btmegamenu'] == (int)$this->id) { + $moved_menu = $menu; + } + } + if (!isset($moved_menu) || !isset($position)) { + return false; + } + // < and > statements rather than BETWEEN operator + // since BETWEEN is treated differently according to databases + return (Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'btmegamenu` + SET `position`= `position` '.pSQL($way ? '- 1' : '+ 1').' + WHERE `position` + '.($way ? '> '.(int)$moved_menu['position'].' AND `position` <= '.(int)$position : '< '.(int)$moved_menu['position'].' AND `position` >= '.(int)$position).' + AND `id_parent`='.(int)$moved_menu['id_parent']) && Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'btmegamenu` + SET `position` = '.(int)$position.' + WHERE `id_parent` = '.(int)$moved_menu['id_parent'].' + AND `id_btmegamenu`='.(int)$moved_menu['id_btmegamenu'])); + } + + public static function cleanPositions($id_parent) + { + $result = Db::getInstance()->executeS(' + SELECT `id_btmegamenu` + FROM `'._DB_PREFIX_.'btmegamenu` + WHERE `id_parent` = '.(int)$id_parent.' + ORDER BY `position`'); + $sizeof = count($result); + for ($i = 0; $i < $sizeof; ++$i) { + $sql = ' + UPDATE `'._DB_PREFIX_.'btmegamenu` + SET `position` = '.(int)$i.' + WHERE `id_parent` = '.(int)$id_parent.' + AND `id_btmegamenu` = '.(int)$result[$i]['id_btmegamenu']; + Db::getInstance()->execute($sql); + } + return true; + } + + public static function getLastPosition($id_parent) + { + return (Db::getInstance()->getValue('SELECT MAX(position)+1 FROM `'._DB_PREFIX_.'btmegamenu` WHERE `id_parent` = '.(int)$id_parent)); + } + + public function getInfo($id_btmegamenu, $id_lang = null, $id_shop = null) + { + if (!$id_lang) { + $id_lang = Context::getContext()->language->id; + } + if (!$id_shop) { + $id_shop = Context::getContext()->shop->id; + } + $sql = 'SELECT m.*, md.title, md.description, md.content_text , md.url + FROM '._DB_PREFIX_.'megamenu m + LEFT JOIN '._DB_PREFIX_.'btmegamenu_lang md ON m.id_btmegamenu = md.id_btmegamenu AND md.id_lang = '.(int)$id_lang + .' JOIN '._DB_PREFIX_.'btmegamenu_shop bs ON m.id_btmegamenu = bs.id_btmegamenu AND bs.id_shop = '.(int)$id_shop; + $sql .= ' WHERE m.id_btmegamenu='.(int)$id_btmegamenu; + + return Db::getInstance()->executeS($sql); + } + + public function getChild($id_btmegamenu = null, $id_group = null, $id_lang = null, $id_shop = null, $active = false) + { + if (!$id_lang) { + $id_lang = Context::getContext()->language->id; + } + if (!$id_shop) { + $id_shop = Context::getContext()->shop->id; + } + + $sql = ' SELECT m.*, md.title, md.text, md.url, md.description, md.content_text + FROM '._DB_PREFIX_.'btmegamenu m + LEFT JOIN '._DB_PREFIX_.'btmegamenu_lang md ON m.id_btmegamenu = md.id_btmegamenu AND md.id_lang = '.(int)$id_lang + .' JOIN '._DB_PREFIX_.'btmegamenu_shop bs ON m.id_btmegamenu = bs.id_btmegamenu AND bs.id_shop = '.(int)$id_shop; + if ($id_group != null) { + $sql .= ' WHERE id_group='.(int)$id_group; + } + + if ($active) { + $sql .= ' AND m.`active`=1 '; + } + + if ($id_btmegamenu != null) { + # validate module + $sql .= ' AND id_parent='.(int)$id_btmegamenu; + } + + $sql .= ' ORDER BY `position` '; + return Db::getInstance()->executeS($sql); + } + + public function hasChild($id) + { + return isset($this->children[$id]); + } + + public function getNodes($id) + { + return $this->children[$id]; + } + + public function getTree($id = null, $id_group = null) + { + $childs = $this->getChild($id, $id_group); + + foreach ($childs as $child) { + # validate module + $this->children[$child['id_parent']][] = $child; + } + $parent = 0; + $output = $this->genTree($parent, 1); + return $output; + } + + public function getDropdown($id = null, $selected = 0, $id_group = null) + { + $this->children = array(); + $childs = $this->getChild($id, $id_group); + foreach ($childs as $child) { + # validate module871 + $this->children[$child['id_parent']][] = $child; + } + $output = array(array('id' => '0', 'title' => 'Root', 'selected' => '')); + $output = $this->genOption(0, 1, $selected, $output); + + return $output; + } + + public function genOption($parent, $level = 0, $selected = null, $output = array()) + { + if ($this->hasChild($parent)) { + $data = $this->getNodes($parent); + foreach ($data as $menu) { + $selected == $menu['id_btmegamenu'] ? 'selected="selected"' : ''; + $output[] = array('id' => $menu['id_btmegamenu'], 'title' => str_repeat('-', $level).' '.$menu['title'].' (ID:'.$menu['id_btmegamenu'].')', 'selected' => $selected); + if ($menu['id_btmegamenu'] != $parent) { + $output = $this->genOption($menu['id_btmegamenu'], $level + 1, $selected, $output); + } + } + } + return $output; + } + + public function genTree($parent, $level) + { + if ($this->hasChild($parent)) { + $data = $this->getNodes($parent); + $t = $level == 1 ? ' sortable' : ''; + Context::getContext()->smarty->assign(array( + 'parent' => $parent, + 'level' => $level, + 't' => $t, + 'data' => $data, + 'param_id_btmegamenu' => Tools::getValue('id_btmegamenu'), + 'model_cat' => $this, + )); + return Context::getContext()->smarty->fetch($this->getTemplatePath().'genTree.tpl'); + } + return ''; + } + + public function getTemplatePath() + { + return _PS_MODULE_DIR_ . 'leobootstrapmenu/views/templates/admin/'; + } + + public function getHookTemplatePath() + { + return _PS_MODULE_DIR_ . 'leobootstrapmenu/views/templates/hook/'; + } + + public function renderAttrs($menu) + { + $t = sprintf($this->edit_string, $menu['id_btmegamenu'], $menu['is_group'], $menu['colums']); + if ($this->is_live_edit) { + if (isset($menu['megaconfig']->subwidth) && $menu['megaconfig']->subwidth) { + # validate module + $t .= ' data-subwidth="'.$menu['megaconfig']->subwidth.'" '; + } + if (isset($menu['megaconfig']->align) && $menu['megaconfig']->align) { + # validate module + $t .= ' data-align="'.$menu['megaconfig']->align.'" '; + } + if ($menu['sub_with'] != 'widget') { + $hasChild = $this->hasChild($menu['id_btmegamenu']); + } else { + $hasChild = ''; + } + $t .= ' data-submenu="'.(isset($menu['megaconfig']->submenu) ? $menu['megaconfig']->submenu : $hasChild).'"'; + $t .= ' data-subwith="'.$menu['sub_with'].'"'; + } + return $t; + } + + public function parserMegaConfig($params) + { + if (!empty($params)) { + foreach ($params as $key => $param) { + if ($param) { + # validate module + if ($param->subwith != 'widget' || ($param->subwith == 'widget' && count($param->rows) >0)) { + $this->mega_config[$key] = $param; + } + } + } + } + } + + public function hasMegaMenuConfig($menu) + { + $id = $menu['id_btmegamenu']; + return isset($this->mega_config[$id]) ? $this->mega_config[$id] : array(); + } + + public function getFrontTree($parent = 0, $edit = false, $params = array(), $id_group = null, $hook = null) + { + $this->parserMegaConfig($params); + + if ($edit) { + # validate module + $this->edit_string = ' data-id="%s" data-group="%s" data-cols="%s" '; + } else { + $this->is_live_edit = false; + $this->model_menu_widget = new LeoWidget(); + $this->model_menu_widget->setTheme(Context::getContext()->shop->theme->getName()); + $this->model_menu_widget->langID = Context::getContext()->language->id; + $this->model_menu_widget->loadWidgets(Context::getContext()->shop->id); + $this->model_menu_widget->loadEngines(); + } + $this->edit_string_col = ' data-colwidth="%s" data-class="%s" '; + + $childs = Btmegamenu::cacheMenusByFields(array('id_group' => (int)$id_group), true); + + if ($edit == false) { + // PERMISSION + foreach ($childs as $key => $menu) { + $id_customer_group = ContextCore::getContext()->customer->id_default_group; + + if (!array_key_exists('groupBox', $menu)) { + // PERMISSION FOR OLD VERSION + $menu['groupBox'] = 'all'; + } + $id_menu_groups = $this->getGroups($menu['groupBox']); + if (!in_array($id_customer_group, $id_menu_groups) && !in_array('all', $id_menu_groups)) { + // PERMISSION : Not allow show menu level 1 + unset($childs[$key]); + } + } + } + foreach ($childs as $child) { + $child['megaconfig'] = $this->hasMegaMenuConfig($child); + $child['megamenu_id'] = $child['id_btmegamenu']; + if (isset($child['megaconfig']->group) && $child['level'] != 0) { + # validate module + $child['is_group'] = $child['megaconfig']->group; + } + + if (isset($child['megaconfig']->submenu) && $child['megaconfig']->submenu == 0) { + # validate module + $child['menu_class'] = $child['menu_class']; + } + + $this->children[$child['id_parent']][] = $child; + } + + $parent = 0; + $theme_name = Context::getContext()->shop->theme->getName(); + $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 'https://' : 'http://'; + $this->image_base_url = Tools::htmlentitiesutf8($protocol.$_SERVER['HTTP_HOST'].__PS_BASE_URI__).'themes/'.$theme_name.'/'.$this->leo_module->getThemeMediaDir('img').'img/icons/'; + $this->shop_url = $this->image_base_url; + $output = ''; + $typesub = ''; + $group_type = ''; + + # GET PARAM FROM DATABASE +// $group = new BtmegamenuGroup($id_group); +// $group_params = Tools::jsonDecode(LeoBtmegamenuHelper::base64Decode($group->params), true); + + # GET PARAM FROM CACHE + $group = BtmegamenuGroup::cacheGroupsByFields(array('id_btmegamenu_group' => $id_group)); + $group_params = Tools::jsonDecode(LeoBtmegamenuHelper::base64Decode($group['params']), true); + + $group_type = $group_params['group_type']; + if ($group_type == 'vertical') { + $typesub = $group_params['type_sub']; + + if ($typesub == 'auto') { + $theme = Context::getContext()->shop->theme_name; + $cookie = LeoBtmegamenuHelper::getCookie(); + if ($hook && $hook == 'rightcolumn') { + if (isset($cookie[$theme.'_layout_dir']) && $cookie[$theme.'_layout_dir']) { + $layout = $cookie[$theme.'_layout_dir']; + if ($layout == 'right-left-main' || $layout == 'right-main-left' || $layout == 'left-right-main') { + $typesub = 'right'; + } elseif ($layout == 'main-left-right') { + $typesub = 'left'; + } + } + } elseif ($hook && $hook == 'leftcolumn') { + if (isset($cookie[$theme.'_layout_dir']) && $cookie[$theme.'_layout_dir']) { + $layout = $cookie[$theme.'_layout_dir']; + if ($layout == 'right-main-left' || $layout == 'main-left-right') { + $typesub = 'left'; + } elseif ($layout == 'left-right-main' || $layout == 'right-left-main') { + $typesub = 'right'; + } + } + } elseif (Context::getContext()->language->is_rtl) { + $typesub = 'left'; + } else { + $typesub = 'right'; + } + } + } + if ($this->hasChild($parent)) { + $data = $this->getNodes($parent); + if ($group_type == 'vertical') { + $output = '