Opencart duplicate URL keywords

前端 未结 5 1044
天涯浪人
天涯浪人 2020-12-20 01:36

How would I go about fixing the issue where two categories/products have the same URL in Opencart? Or if their is a module which already does this?

E.g: categories

相关标签:
5条回答
  • 2020-12-20 02:06

    I have resolved this issue i have made a vqmode xml file

    see opencart give the same result for below urls

    • http://mycart/mp3-players/iPod-Classic
    • http://mycart/mp3-players/some-child/iPod-Classic
    • http://mycart/some-parent/mp3-players/iPod-Classic
    • http://mycart/iPod-Classic

    it will difficult to do seo for that product “iPod-Classic”

    so i write a “vqmod” script with this script you can redirect user to a specific and correct page

    even a user type a wrong url

    i.e.

    http://mycart/mp3-players/ffffdfsdgf/sdf/sdf/iPod-Classic
    

    it will automatically redirect it to

    http://mycart/mp3-players/iPod-Classic
    

    you just need to download ‘controller_common_seo_url.xml’ from “box” or

    1. install vqmode in your open cart
    2. create a xml file named “controller_common_seo_url.xml” in vqmod/xml
    3. open controller_common_seo_url.xml and write below code
        <modification>
                <id>public function index() add more functions</id>
                <version>1.0</version>
                <vqmver>2.1.5</vqmver>
                <author>http://www.bhardwajabhi.wordpress.com</author>
                <file name=”catalog/controller/common/seo_url.php”>
                    <operation>
                         <search position=”before”><![CDATA[ public function index() { ]]></search>
                                    <add><![CDATA[
    
                    public function get_seo_title($id, $type)
                    {
                    $query = $this->db->query("SELECT keyword FROM " . DB_PREFIX . "url_alias WHERE query = '". $type ."=" . (int)$id  . "'");    
    
                    if($query->row)
                        return     $query->row['keyword'];
                        else
                        return     $id;
                    }
    
                public function get_path_level($id)
                    {
                    $query = $this->db->query(“select `level` from ” . DB_PREFIX . “category_path where `category_id` = ‘”. $id. “‘ order by level desc LIMIT 1″);    
    
                        return     $query->row['level'];
    
                    }    
    
    
                public function get_product_relative($parts, $product_id)
                    {
    
    
                    if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == ‘on’) || ($this->request->server['HTTPS'] == ’1′))) {
    
                         $this->data['base'] = $this->config->get(‘config_ssl’);
    
                    } else {
    
                        $this->data['base'] = $this->config->get(‘config_url’);
    
                        }    
    
    
    
    
    
                    $path         =      $this->get_seo_title($product_id, ‘product_id’);        
    
                    $query = $this->db->query(“SELECT category_id FROM ” . DB_PREFIX . “product_to_category WHERE product_id = ‘” . (int)$product_id . “‘”);
                    $i =0;
    
                        foreach($query->rows as $pro_cat):
                        $i++;
                        $sub_query = $this->db->query(“select `path_id` from ” . DB_PREFIX . “category_path where `category_id` = ‘”. $pro_cat['category_id']. “‘ order by level desc”);
    
                            foreach($sub_query->rows as $pro_sub_cat):
                            $path = $this->get_seo_title($pro_sub_cat['path_id'], ‘category_id’) . “/” . $path;
                            endforeach;
    
                            $path1 = ‘/’. $path;
    
                            $array1 = explode(‘/’, $path1);
    
                            $array2 = explode(‘/’, $this->request->get['_route_']);
    
                            $result = array_diff($array1, $array2);
    
    
                            $new_path[$i]['path'] = $path;
                            $new_path[$i]['count'] = count($result);
    
    
                            $path = $this->get_seo_title($product_id, ‘product_id’);      
    
    
                        endforeach;
    
                        $min = PHP_INT_MAX;
                        $max = 0;
    
                        foreach ($new_path as $i) {                
                            $min = min($min, $i['count']);
                            }
    
    
                    foreach($new_path as $value):
                        if($value['count']==$min):
                            $final_path =  $value['path'];
                            break;
                        endif;
                    endforeach;
    
    
    
    
                    similar_text($this->request->get['_route_'], $final_path, $percent);
                    if($percent<>100)
                        header (‘location:’ . $this->data['base'] .”. $final_path);    
    
    
    
    
                }
                ]]></add>
    
                    </operation>
                </file>
                <file name=”catalog/controller/common/seo_url.php”>
                            <operation info=”After ABC, add 123″>
                                    <search position=”after”><![CDATA[
                                   $this->request->get['product_id'] = $url[1];
                                    ]]></search>
                                    <add><![CDATA[
                                    /*Start url redirection*/
                                    $this->get_product_relative($parts, $url[1]);
                        /*End Url Redirection*/
                                    ]]></add>
                            </operation>
    
                    </file>
    
            </modification>
    

    that’s it so now when some one hit on any product the cart will show page like

    http://www.yourSiteUrl/parent-category/child-category/product
    

    note: you must give seo title to each and every category ,child category and there product because script search for the seo title and if seo title is not available then it give it id so suppose we have not give seo-title for child category and vew its product then the url will be like

    http://www.yourSiteurl/parent-category/56/product
    

    you can get more detail about it on here

    0 讨论(0)
  • 2020-12-20 02:07

    I know this is a late answer, but this is a deep rooted problem with OpenCarts architecture.

    Personally I am not a fan of vQmod, so here is a (what some would call a hack) solution to the problem without using one.

    I have seen many alterations to catalog/controller/common/seo_url.php that add custom seo urls. This fix is compatible with such modifications.

    I would also like to add that is by no means the most sophisticated solution in the world but it will guarantee that sub categories with duplicate seo url entries will work as they should.

    Find in catalog/controller/common/seo_url.php

    if ($url[0] == 'category_id') {
        if (!isset($this->request->get['path'])) {
            $this->request->get['path'] = $url[1];
        } else {
            $this->request->get['path'] .= '_' . $url[1];
        }
    }
    

    Replace with the following

    if ($url[0] == 'category_id') {
        $categories[$i] = $this->model_catalog_category->getCategory($url[1]);
    
        if (!isset($this->request->get['path'])) {
            $this->request->get['path'] = $categories[$i]['category_id'];
        } else {
            foreach ($query->rows as $row) {
                $url = explode('=', $row['query']);
                $category_id = $url[1];
    
                $category = $this->model_catalog_category->getCategory($category_id);
    
                if ($category['parent_id'] == $categories[$i - 1]['category_id']) {
                    $this->request->get['path'] .= '_' . $category['category_id'];
                }
            }
        }
    }
    

    Add the following line to the top of the method index()

    $this->load->model('catalog/category');
    

    Find the line...

    foreach ($parts as $part) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");
    

    And replace with the following

    $categories = array();
    
    for ($i = 0; $i < count($parts); $i++) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($parts[$i]) . "'");
    
    0 讨论(0)
  • 2020-12-20 02:11

    In addition to @Ian Brindley you also should edit another 2 files so you can enter the keywords in the admin panel:
    Admin/Controller/Catalog/category.php

    Find these lines of code in the method validateForm

    if (utf8_strlen($this->request->post['keyword']) > 0) {
        $this->load->model('catalog/url_alias');
    
        $url_alias_info = $this->model_catalog_url_alias->getUrlAlias($this->request->post['keyword']);
    
        if ($url_alias_info && isset($this->request->get['category_id']) && $url_alias_info['query'] != 'category_id=' . $this->request->get['category_id']) {
            $this->error['keyword'] = sprintf($this->language->get('error_keyword'));
        }
    
        if ($url_alias_info && !isset($this->request->get['category_id'])) {
            $this->error['keyword'] = sprintf($this->language->get('error_keyword'));
        }
    
        if ($this->error && !isset($this->error['warning'])) {
            $this->error['warning'] = $this->language->get('error_warning');
        }
    }
    

    and change them into:

    if (utf8_strlen($this->request->post['keyword']) > 0) {
        $this->load->model('catalog/url_alias');
    
        $url_alias_info = $this->model_catalog_url_alias->getUrlAlias($this->request->post['keyword']);
    
        if ($url_alias_info && !isset($this->request->get['category_id'])) {
            $this->error['keyword'] = sprintf($this->language->get('error_keyword'));
        }
    
        if ($this->error && !isset($this->error['warning'])) {
            $this->error['warning'] = $this->language->get('error_warning');
        }
    }
    

    This will get rid of the check if the seo keyword is a duplicate. This way you can enter the seo keywords within the adminpanel instead of phpmyadmin

    0 讨论(0)
  • 2020-12-20 02:14
    if ($url[0] == 'category_id') {
        $categories[$i] = $this->model_catalog_category->getCategory($url[1]);
    
        if (!isset($this->request->get['path'])) {
            $this->request->get['path'] = $categories[$i]['category_id'];
        } else {
            foreach ($query->rows as $row) {
                $url = explode('=', $row['query']);
                $category_id = $url[1];
    
                $category = $this->model_catalog_category->getCategory($category_id);
    
                if ($category['parent_id'] == $categories[$i - 1]['category_id']) {
                    $this->request->get['path'] .= '_' . $category['category_id'];
                }
            }
        }
    }
    

    this will not work if its a 3 level category. I hope someone will have a better solution.

    0 讨论(0)
  • 2020-12-20 02:20

    I developed this vqmod for that exact scenario

    0 讨论(0)
提交回复
热议问题