Столкнулся с очередной проблемой в компоненте aceshop — модуль категорий, выводящий список категорий в виде меню некорректно работает при многоуровневости меню при включенном ЧПУ. Проще говоря, когда у нас есть категории а у них подкатегории, то при переходе в подкатегорию меню сворачивается и прячет список подкатегорий. Плюс к этому по умолчанию в опенкарте можно вывести только 2 уровня меню — категории и подкатегории. А ведь бывают случаи, когда есть и третий подуровень))Итак для начала стоит заменить стандартный модуль вывода категорий, если конечно вам необходим третий уровень. Прикладываю архив cat_module.zip — в нем файлы для замены оригинальных файлов модуля. Проверялся на aceshop 1.4.3 и opencart 1.5.1.3.
Проблема же со сворачиванием меню происходит только при включенном ЧПУ в joomla и возникает из-за неправильной обработки роутера компонента aceshop. Файл роутера я немного модифицировал:
<?php /* * @package AceShop * @copyright 2009-2012 JoomAce LLC, www.joomace.net * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html */ // No Permission defined('_JEXEC') or die ('Restricted access'); require_once(JPATH_ROOT.'/components/com_aceshop/aceshop/aceshop.php'); class AceShopRouter { static $cats = array(); public function buildRoute(&$query){ $Itemid = null; $segments = array(); $menu = $this->getMenu(); if (!empty($query['Itemid'])) { $Itemid = $query['Itemid']; } else { $Itemid = $this->getItemid(); } if (empty($Itemid)) { $segments[] = 'shop'; $a_menu = $menu->getActive(); } else { $a_menu = $menu->getItem($Itemid); } if (isset($query['view'])) { if ($query['view'] == 'admin') { unset($query['view']); return $segments; } $segments[] = $query['view']; unset($query['view']); } if (isset($query['route'])) { switch($query['route']) { case 'product/product': if (is_object($a_menu) && $a_menu->query['view'] == 'product' && $a_menu->query['product_id'] == @$query['product_id']){ unset($query['path']); unset($query['product_id']); unset($query['manufacturer_id']); break; } $segments[] = 'product'; if (isset($query['product_id'])) { $id = $query['product_id']; $name = AceShop::get('db')->getRecordAlias($id); if (!empty($name)) { $segments[] = $id.':'.$name; } else { $segments[] = $id; } unset($query['path']); unset($query['product_id']); unset($query['manufacturer_id']); unset($query['sort']); unset($query['order']); unset($query['filter_name']); unset($query['filter_tag']); unset($query['limit']); unset($query['page']); } break; case 'product/category': if (is_object($a_menu) && $a_menu->query['view'] == 'category' && $a_menu->query['path'] == @$query['path']){ unset($query['path']); break; } $segments[] = 'category'; if (isset($query['path'])) { $id = $query['path']; if (strpos($id, '_')) { $old_id = $id; $id = end(explode('_', $id)); self::$cats[$id] = $old_id; } else { self::$cats[$id] = $id; } $name = AceShop::get('db')->getRecordAlias($id, 'category'); if (!empty($name)) { $segments[] = $id.':'.$name; } else { $segments[] = $id; } /** fonclub change route*/ $session =& JFactory::getSession(); $session->set('cats-'.$id, self::$cats[$id]); /** fonclub change route*/ unset($query['path']); } break; case 'product/manufacturer/product': if (is_object($a_menu) && $a_menu->query['view'] == 'manufacturer' && $a_menu->query['manufacturer_id'] == @$query['manufacturer_id']){ unset($query['manufacturer_id']); break; } $segments[] = 'manufacturer'; if (isset($query['manufacturer_id'])) { $id = $query['manufacturer_id']; $name = AceShop::get('db')->getRecordAlias($id, 'manufacturer'); if (!empty($name)) { $segments[] = $id.':'.$name; } else { $segments[] = $id; } unset($query['manufacturer_id']); } break; case 'information/information': if (is_object($a_menu) && $a_menu->query['view'] == 'information' && $a_menu->query['information_id'] == @$query['information_id']){ unset($query['information_id']); break; } $segments[] = 'information'; if (isset($query['information_id'])) { $id = $query['information_id']; $name = AceShop::get('db')->getRecordAlias($id, 'information'); if (!empty($name)) { $segments[] = $id.':'.$name; } else { $segments[] = $id; } unset($query['information_id']); } break; case 'common/home': break; default: $_view = $this->getView($query['route']); $_itemid_r = $this->getItemid($_view); $_itemid_h = $this->getItemid('home'); if (($_itemid_r == $_itemid_h) || ($query['route'] == 'checkout/cart')) { $segments[] = $query['route']; } break; } unset($query['route']); } return $segments; } public function parseRoute($segments) { $vars = array(); if (empty($segments)) { return $vars; } $c = count($segments); if ($c == 1) { $vars['view'] = $segments[0]; if ($vars['view'] == 'cart') { $vars['route'] = 'checkout/cart'; } return $vars; } $route = ''; foreach ($segments as $segment) { if ($segment == 'product' && strpos($segments[1], ':')) { $route = 'product/product'; list($id, $alias) = explode(':', $segments[1], 2); $vars['product_id'] = $id; break; } if ($segment == 'category' && strpos($segments[1], ':')) { $route = 'product/category'; list($id, $alias) = explode(':', $segments[1], 2); $id = isset(self::$cats[$id]) ? self::$cats[$id] : $id; /** fonclub change route*/ $session =& JFactory::getSession(); $cats = $session->get('cats-'.$id); $id = isset($cats) ? $cats : $id; /** fonclub change route*/ $vars['path'] = $id; break; } if ($segment == 'manufacturer' && strpos($segments[1], ':')) { $route = 'product/manufacturer/product'; list($id, $alias) = explode(':', $segments[1], 2); $vars['manufacturer_id'] = $id; break; } if ($segment == 'information' && strpos($segments[1], ':')) { $route = 'information/information'; list($id, $alias) = explode(':', $segments[1], 2); $vars['information_id'] = $id; break; } if ($segment == 'admin') { $vars['view'] = 'admin'; } $route .= '/'.$segment; } if (!empty($route)) { $route = ltrim($route, '/'); $vars['route'] = $route; } return $vars; } public function rewrite($url) { if (!strpos($url, 'page')) { $url = $this->route($url); } return $url; } public function route($url) { $uri = JFactory::getURI(); $app = JFactory::getApplication(); $url = str_replace('&', '&', $url); $url = str_replace('//index.php', '/index.php', $url); $url = str_replace('index.php?token=', 'index.php?option=com_aceshop&token=', $url); $url = str_replace('index.php?route=', 'index.php?option=com_aceshop&route=', $url); if ($app->isSite()) { $full_url = AceShop::get('base')->getFullUrl(); $sub_domain = AceShop::get('base')->getSubdomain(); $domain = str_replace(rtrim($sub_domain, '/'), '', rtrim($full_url, '/')); if (substr($domain, -1) != '/') { $domain .= '/'; } $url = str_replace($full_url, '', $url); $url = str_replace(str_replace('http', 'https', $full_url), '', $url); if (substr($url, 0, 10) == 'index.php?') { if (!strpos($url, 'Itemid=')) { $id = 0; parse_str($url, $vars); if (!isset($vars['view']) && !isset($vars['route'])) { $view = 'home'; } if (isset($vars['route'])) { if ($vars['route'] == 'product/category') { $id = $vars['path']; } elseif ($vars['route'] == 'product/product') { $id = $vars['product_id']; } elseif ($vars['route'] == 'product/manufacturer/product') { $id = $vars['manufacturer_id']; } elseif ($vars['route'] == 'information/information ') { $id = $vars['information_id']; } $view = $this->getView($vars['route']); unset($vars); } if (AceShop::get()->isAdmin()) { $view = 'admin'; } $Itemid = $this->getItemid($view, $id, true); $url = str_replace('index.php?option=com_aceshop', 'index.php?option=com_aceshop'.$Itemid, $url); } if (strpos($url, 'captcha')) { $url .= '&tmpl=component&format=raw'; } if ($this->_addLangCode($url)) { $_lang_id = (int) AceShop::getClass('opencart')->get('config')->get('config_language_id'); $_lang = AceShop::getClass('db')->getLanguage($_lang_id); if (!empty($_lang['code'])) { $url .= '&lang='.$_lang['code']; } } if (AceShop::get()->isAdmin() && !strpos($url, 'view=admin')) { $url .= '&view=admin'; } } $url = JRoute::_($url); $url = str_replace('component/aceshop/shop', 'component/aceshop', $url); $url = $domain.ltrim($url, '/'); } else { if (AceShop::get()->isExternal()) { $url .= '&view='.JRequest::getCmd('view'); } } return $url; } public function getItemid($view = 'home', $record_id = 0, $with_name = false) { static $ids = array(); if (!isset($ids[$view][$record_id])) { $component = JComponentHelper::getComponent('com_aceshop'); if (AceShop::get('base')->is15()) { $items = $this->getMenu()->getItems('componentid', $component->id); } else { $items = $this->getMenu()->getItems('component_id', $component->id); } if (is_array($items)) { if ($view == 'product') { $cat_id = AceShop::get('db')->getProductCategoryId($record_id); $needles = array( 'product' => (int) $record_id, 'category' => (int) $cat_id ); } else if ($view == 'category') { $needles = array( 'category' => (int) $record_id ); } else if ($view == 'manufacturer') { $needles = array( 'manufacturer' => (int) $record_id ); } else if ($view == 'information') { $needles = array( 'information' => (int) $record_id ); } else { $needles = array( $view => $record_id ); } $menu_id = $this->_findItemId($needles, $items); $ids[$view][$record_id] = $menu_id; } else { //$Itemid = 1; } } $Itemid = ''; if (empty($ids[$view][$record_id])) { return $Itemid; } $Itemid = $ids[$view][$record_id]; if ($with_name == true) { $Itemid = '&Itemid='.$Itemid; } return $Itemid; } protected function _findItemId($needles, $items, $recursive_cats = true) { $menu_id = $home_id = null; foreach ($needles as $needle => $id) { foreach ($items as $item) { if ($needle == 'product') { if ((@$item->query['view'] == $needle) && (@$item->query['product_id'] == $id)) { $menu_id = $item->id; break; } } else if ($needle == 'category') { if ((@$item->query['view'] == $needle)) { if (@$item->query['path'] == $id) { $menu_id = $item->id; break; } else if ($recursive_cats == true) { $parent_id = AceShop::get('db')->getParentCategoryId($id); if ($parent_id != 0) { $needles = array( 'category' => (int) $parent_id ); $menu_id = $this->_findItemId($needles, $items); } } } } else if ($needle == 'manufacturer') { if ((@$item->query['view'] == $needle) && (@$item->query['manufacturer_id'] == $id)) { $menu_id = $item; break; } } else if ($needle == 'information') { if ((@$item->query['view'] == $needle) && (@$item->query['information_id'] == $id)) { $menu_id = $item->id; break; } } else { if (@$item->query['view'] == $needle) { $menu_id = $item->id; break; } } if (empty($home_id) && @$item->query['view'] == 'home') { $home_id = $item->id; } } if (!empty($menu_id)) { break; } } if (empty($menu_id) && !empty($home_id)) { $menu_id = $home_id; } return $menu_id; } public function &getMenu() { jimport('joomla.application.menu'); $options = array(); $menu = JMenu::getInstance('site', $options); if (JError::isError($menu)) { $null = null; return $null; } return $menu; } public function generateAlias($title) { $alias = JFilterOutput::stringURLSafe(html_entity_decode($title, ENT_QUOTES, 'UTF-8')); if (trim(str_replace('-', '', $alias)) == '') { $mainframe = JFactory::getApplication(); $date = JFactory::getDate(); $date->setOffset($mainframe->getCfg('offset')); $alias = $date->toFormat("%Y-%m-%d-%H-%M-%S"); } return $alias; } public function getView($route, $use_default = true) { $view = ''; switch ($route) { case 'common/home': $view = 'home'; break; case 'account/account': $view = 'account'; break; case 'checkout/cart': $view = 'cart'; break; case 'checkout/checkout': $view = 'checkout'; break; case 'account/wishlist': $view = 'wishlist'; break; case 'information/contact': $view = 'contact'; break; case 'product/product': $view = 'product'; break; case 'product/category': $view = 'category'; break; case 'product/compare': $view = 'compare'; break; case 'product/manufacturer/product': $view = 'manufacturer'; break; case 'product/manufacturer': $view = 'manufacturers'; break; case 'account/login': $view = 'login'; break; case 'account/register': $view = 'registration'; break; case 'account/order': $view = 'orders'; break; case 'account/download': $view = 'downloads'; break; case 'product/search': $view = 'search'; break; case 'account/newsletter': $view = 'newsletter'; break; case 'checkout/voucher': $view = 'voucher'; break; case 'information/sitemap': $view = 'sitemap'; break; case 'account/return/insert': $view = 'returns'; break; case 'affiliate/account': $view = 'affiliates'; break; case 'product/special': $view = 'specials'; break; case 'information/information': $view = 'information'; break; case 'admin': $view = 'admin'; break; default: if ($use_default == true) { $view = 'home'; } break; } return $view; } public function getRoute($view, $use_default = true) { $route = ''; switch ($view) { case 'home': $route = 'common/home'; break; case 'account': $route = 'account/account'; break; case 'cart': $route = 'checkout/cart'; break; case 'checkout': $route = 'checkout/checkout'; break; case 'wishlist': $route = 'account/wishlist'; break; case 'contact': $route = 'information/contact'; break; case 'product': $route = 'product/product'; break; case 'category': $route = 'product/category'; break; case 'compare': $route = 'product/compare'; break; case 'manufacturer': $route = 'product/manufacturer/product'; break; case 'manufacturers': $route = 'product/manufacturer'; break; case 'login': $route = 'account/login'; break; case 'registration': $route = 'account/register'; break; case 'orders': $route = 'account/order'; break; case 'downloads': $route = 'account/download'; break; case 'search': $route = 'product/search'; break; case 'newsletter': $route = 'account/newsletter'; break; case 'voucher': $route = 'checkout/voucher'; break; case 'sitemap': $route = 'information/sitemap'; break; case 'returns': $route = 'account/return/insert'; break; case 'affiliates': $route = 'affiliate/account'; break; case 'specials': $route = 'product/special'; break; case 'information': $route = 'information/information'; break; case 'admin': $route = 'admin'; break; default: if ($use_default == true) { $route = 'common/home'; } break; } return $route; } public function _cleanTitle($text) { $replace = array("""); foreach ($replace as $value) { $text = str_replace($value, "", $text); } return $text; } public function _addLangCode($url) { if (strpos($url, '&lang=')) { return false; } if (AceShop::get('base')->isAdmin('aceshop')) { return false; } if (AceShop::get('base')->is15()) { return false; } else { if (AceShop::get('base')->isAcesefInstalled() && (AcesefFactory::getConfig()->multilang == 1)) { return true; } if (AceShop::get('base')->isSh404sefInstalled() && (Sh404sefFactory::getConfig()->enableMultiLingualSupport == 1)) { return true; } if (AceShop::get('base')->isJoomsefInstalled() && (SEFConfig::getConfig()->langEnable)) { return true; } if (AceShop::get('base')->plgEnabled('system', 'languagefilter')) { return true; } } return false; } }