Столкнулся с очередной проблемой в компоненте 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;
}
}
