Opencart duplicate URL keywords

佐手、 提交于 2019-12-12 00:21:30

问题


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

Ladies -> Trousers (URL: ladies/trousers)
Mens -> Trousers (URL: mens/trousers)

This breaks Opencart because we have two sub-categories with the URL = trousers?


回答1:


I developed this vqmod for that exact scenario




回答2:


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]) . "'");



回答3:


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/dddfsdgf/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




回答4:


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.




回答5:


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



来源:https://stackoverflow.com/questions/33238223/opencart-seo-url-rewriting-duplicate-names

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!