I need child categories of different parent categories to be able to have the same URL. Example:
Code: Select all
Adult -> Tacos
Child -> Tacos
- /adult/tacos/
- /child/tacos/
- /adult/adult_tacos/
- /child/child_tacos/
The following code will fix the URL lookups for OpenCart 1.5.13 (and maybe other versions, I have no interest in testing on other versions). This modification will allow children categories of different parent categories have the same SEO URL. Replace the top part of your /catalog/controller/common/seo_url.php with:
Code: Select all
<?php
class ControllerCommonSeoUrl extends Controller {
public function index() {
// Add rewrite to url class
if ($this->config->get('config_seo_url')) {
$this->url->addRewrite($this);
}
// Decode URL
if (isset($this->request->get['_route_'])) {
$parts = explode('/', $this->request->get['_route_']);
$this_route = $parts;
$this_route_multistore = $parts;
array_shift($this_route_multistore);
$tree = array(); // this is going to store the last parent category id
foreach ($parts as $part) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");
if ($query->num_rows) {
/* CUSTOM CODE this if/else */
if($query->num_rows > 1) {
// loop these cats until we find the one that is the sub cat
foreach($query->rows as $category) {
$url = explode('=', $category['query']);
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category WHERE category_id = '" . $this->db->escape($url[1]) . "' AND parent_id = '" . $this->db->escape(array_pop(array_values($tree))) . "'");
if ($query->num_rows) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE query = 'category_id=" . $this->db->escape($query->row['category_id']) . "'");
// echo '<pre>';print_r($query);echo '</pre>';exit;
break;
}
}
}
/* end CUSTOM CODE */
$url = explode('=', $query->row['query']);
if ($url[0] == 'product_id') {
$this->request->get['product_id'] = $url[1];
}
if ($url[0] == 'category_id') {
if (!isset($this->request->get['path'])) {
$this->request->get['path'] = $url[1];
} else {
$this->request->get['path'] .= '_' . $url[1];
}
/* CUSTOM CODE */
$tree[] = $url[1];
/* end CUSTOM CODE */
}
if ($url[0] == 'manufacturer_id') {
$this->request->get['manufacturer_id'] = $url[1];
}
if ($url[0] == 'information_id') {
$this->request->get['information_id'] = $url[1];
}
} else {
if (is_file(DIR_APPLICATION . 'controller/' . implode("/", $this_route) . '.php') || is_file(DIR_APPLICATION . 'controller/' . implode("/", $this_route_multistore) . '.php')) {
$this->request->get['route'] = $this->request->get['_route_'];
break;
} else {
$this->request->get['route'] = 'error/not_found';
array_pop($this_route);
}
}
}
NOTICE - This code should be thoroughly testing in a development environment before implementing it. My implementation is limited to a single store, with categories that are only two levels deep, with only English in use.