Search code examples
phpmysqlurlseoopencart

opencart seo url rewriting


I've successfully managed to get SEO URLs to work in opencart and have also managed to tweak the standard SEO URL file to incorporate other custom URLs. The one i am having trouble with relates to a blog that I've set up. The table for the blog entries has an SEO keyword column for each respective entry. The current URL comes up as http://www.imbued.co.uk/blog?news_id=5 with 5 being the 5th blog entry. I would rather the URL was cleaner such as http://www.imbued.co.uk/blog/seokeywordfromthetable

Can the SEO URL file below be tweaked for it to come as such?

<?php
class ControllerCommonSeoUrl extends Controller {
        /* SEO Custom URL */
        private $url_list = array (
            'common/home'            => '',
            'checkout/cart'          => 'basket',
            'product/special'        => 'special',
            'product/search'         => 'search',
            'affiliate/account'      => 'affiliate',
            'account/voucher'        => 'gift-voucher',
            'checkout/success'       => 'checkout/success',
            'product/manufacturer'   => 'brand',
            'account/transaction'    => 'transactions',
            'information/contact'    => 'contact-us',
            'product/compare'        => 'compare',
            'information/news'       => 'blog',
            'information/sitemap'    => 'sitemap',
            );
        /* SEO Custom URL */

    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';   
                }
            }
                         /* SEO Custom URL */
                         if ( $_s = $this->setURL($this->request->get['_route_']) ) {
                                 $this->request->get['route'] = $_s;
                         }/* SEO Custom URL */

            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';
            }

            if (isset($this->request->get['route'])) {
                return $this->forward($this->request->get['route']);
            }
        }
    }

    public function rewrite($link) {
        if ($this->config->get('config_seo_url')) {
            $url_data = parse_url(str_replace('&amp;', '&', $link));

            $url = ''; 

            $data = array();

            parse_str($url_data['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]);
                     }// 
                                        /* SEO Custom URL */
                                        if( $_u = $this->getURL($data['route']) ){
                                            $url .= $_u;
                                            unset($data[$key]);
                                        }/* SEO Custom URL */        


                                }
                        }

            if ($url) {
                unset($data['route']);

                $query = '';

                if ($data) {
                    foreach ($data as $key => $value) {
                        $query .= '&' . $key . '=' . $value;
                    }

                    if ($query) {
                        $query = '?' . trim($query, '&');
                    }
                }

                return $url_data['scheme'] . '://' . $url_data['host'] . (isset($url_data['port']) ? ':' . $url_data['port'] : '') . str_replace('/index.php', '', $url_data['path']) . $url . $query;
            } else {
                return $link;
            }
        } else {
            return $link;
        }       
    }
        /* SEO Custom URL */
        public function getURL($route) {
                if( count($this->url_list) > 0) {
                     foreach ($this->url_list as $key => $value) {
                        if($route == $key) {
                            return '/'.$value;
                        }
                     }
                }
                return false;
        }
        public function setURL($_route) {
                if( count($this->url_list) > 0 ){
                     foreach ($this->url_list as $key => $value) {
                        if($_route == $value) {
                            return $key;
                        }
                     }
                }
                return false;
        }/* SEO Custom URL */   
}
?>

Solution

  • To do this, you would really need to add an SEO keyword field in the admin, then add the keywords to the url_alias table as they are edited. You will also need to use blog_id=XXX in place of for example product_id=XXX. Easiest way to do this would be to copy the code from one of the core code types (product, category, manufacturer or information files) and how they do this in their model files. After this, you just need to handle the seo urls in the common/seo_url.php you have above to get the links running (again you just need to replicate one of the four types that are part of the core)

    If this is a commercial mod you've bought, I would actually get in touch with the developer. It's likely they will have a solution for this, and if not it would be in their interest to add it for future customers