I currently have User SEO URL\'s
set to Yes in OpenCart Admin.
System -> Settings -> Store -> Server -> User SEO URL\'s
So, I'm using 1.5.5.1 and no one answer on this question solved my problem. However, combining the answers from @Jay Gilford, @TheBlackBenzKid and @rkaartikeyen I came up with a fully working solution.
Remember to enable seo urls as shown by @TheBlackBenzKid.
An explanation can be found below the code.
[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_']); foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'"); if ($query->num_rows) { $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]; } } 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 { $this->request->get['route'] = 'error/not_found'; } } if (isset($this->request->get['product_id'])) { $this->request->get['route'] = 'product/product'; } elseif (isset($this->request->get['path'])) { $this->request->get['route'] = 'product/category'; } elseif (isset($this->request->get['manufacturer_id'])) { $this->request->get['route'] = 'product/manufacturer/info'; } elseif (isset($this->request->get['information_id'])) { $this->request->get['route'] = 'information/information'; }else { $this->request->get['route'] = $this->request->get['_route_']; } if (isset($this->request->get['route'])) { return $this->forward($this->request->get['route']); } } } public function rewrite($link) { $url_info = parse_url(str_replace('&', '&', $link)); $url = ''; $data = array(); parse_str($url_info['query'], $data); foreach ($data as $key => $value) { if (isset($data['route'])) { if (($data['route'] == 'product/product' && $key == 'product_id') || (($data['route'] == 'product/manufacturer/info' || $data['route'] == 'product/product') && $key == 'manufacturer_id') || ($data['route'] == 'information/information' && $key == 'information_id')) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($key . '=' . (int)$value) . "'"); if ($query->num_rows) { $url .= '/' . $query->row['keyword']; unset($data[$key]); } } elseif ($key == 'path') { $categories = explode('_', $value); foreach ($categories as $category) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = 'category_id=" . (int)$category . "'"); if ($query->num_rows) { $url .= '/' . $query->row['keyword']; } } unset($data[$key]); } } } if ($url) { unset($data['route']); $query = ''; if ($data) { foreach ($data as $key => $value) { $query .= '&' . $key . '=' . $value; } if ($query) { $query = '?' . trim($query, '&'); } } return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query; } else { $link = str_replace('index.php?route=', '', $link); return $link; } } }
Apparently, @Jay Gilford and @TheBlackBenzKid solve the issue of the urls being properly written on the page.
Line 113 $link = str_replace('index.php?route=', '', $link);
But it seems to break the urls since the Controller can't find the pages and therefore reverts to the error page.
Line 38 - 40 } else { $this->request->get['route'] = 'error/not_found'; }
@rkaartikeyen's solution solves this problem by setting the current route to the requested route
Line 51 - 53 else { $this->request->get['route'] = $this->request->get['_route_']; }
First of all in root folder of your website rename htaccess.txt into .htaccess.
Then go to System > Settings > Your store. Edit. Open tab Server and set Use SEO URLs to Yes.
Now open catalog/controller/startup/seo_url.php
Find } elseif ($key == 'path') {
Add before
} elseif ($key == 'route') {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "seo_url WHERE `query` = '" . $this->db->escape($value) . "' AND store_id = '" . (int)$this->config->get('config_store_id') . "' AND language_id = '" . (int)$this->config->get('config_language_id') . "'");
if ($query->num_rows && $query->row['keyword']) {
$url .= '/' . $query->row['keyword'];
unset($data[$key]);
} else if ($data['route'] == "common/home") {
$url .= '/';
}
Now /index.php?route=common/home
becames /
And now you can although set SEO URLs in Design > SEO URL using constructions like account/login or information/contact.
To simply remove that, you can do a basic replace in /catalog/controller/common/seo_url.php
Find:
return $link;
Before it on a new line put:
$link = str_replace('index.php?route=common/home', '', $link);
Edit by TheBlackBenzKid: If you want full SEO just use this line instead of the above:
$link = str_replace('index.php?route=', '', $link);
Also make sure SEO URLs is turned on in the Admin panel of the store.