Opencart, автогенерация ЧПУ

Тема в разделе "OpenCart", создана пользователем rem kwadriga, 22 мар 2013.

  1. rem kwadriga

    rem kwadriga

    Регистрация:
    14 дек 2012
    Сообщения:
    43
    Симпатии:
    3
    Значит, долго я бился над этой темой, ставил кучу модулей, но ничего кроме проблем от этих модулей не получал.
    Есть один нормальный: seo pro. Он устанавливается, и после того, как включить ЧПУ в админке, он нормально работает. НО! Он Не генерирует этих самых ЧПУ сам - их нужно писать вручную. Что, разумеется, никуда не годный отстой. В наше время с таким вопросом, как ЧПУ, уже довно должно быть покончено. По умолчанию везде они должны быть...
    Короче, я заморочился и доработал фунционал опенкарта, и теперь он у меня умеет сам генерировать (по стандартам гугла: латинская транслитерация+тире вместо пробелов) из названий товаров, категорий и статей нормальные урлы.

    Вот как я это сделал:
    Создал в директории /admin/model/catalog файл autoseourls.php, внёс в него следующий код:
    PHP:
    <?php
     
        
    class ModelCatalogAutoseourls extends Model{
     
            private 
    $transliterate=array ("А"=>"A","Б"=>"B","В"=>"V","Г"=>"G","Д"=>"D","Е"=>"E","Ж"=>"J","З"=>"Z","И"=>"I","Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
                
    "О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T","У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH","Ш"=>"SH","Щ"=>"SCH","Ъ"=>"","Ы"=>"YI",
                
    "Ь"=>"","Э"=>"E","Ю"=>"YU","Я"=>"YA","а"=>"a","б"=>"b","в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"j","з"=>"z","и"=>"i","й"=>"y","к"=>"k",
                
    "л"=>"l","м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r","с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h","ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch",
                
    "ъ"=>"y","ы"=>"yi","ь"=>"'","э"=>"e""ё"=>"e""Ё"=>"e""ю"=>"yu","я"=>"ya","."=>"-"," "=>"-","?"=>"-","/"=>"-","\\"=>"-","*"=>"-",":"=>"-",
                
    "*"=>"-",">"=>"-","|"=>"-","'"=>"");
     
            public function 
    __construct(){
     
            }
     
            public function 
    generateSeoUrl($data){
     
                if(isset(
    $data['category_description'])){
                    
    $description='category_description';
                    
    $name='name';
                }elseif(isset(
    $data['information_description'])){
                    
    $description='information_description';
                    
    $name='title';
                }elseif(isset(
    $data['product_description'])){
                    
    $description='product_description';
                    
    $name='name';
                }else{
                    return 
    false;
                }
     
                
    $tr=$this->transliterate;
                
    $letters=array();
                foreach(
    $tr as $letter){
                    
    $letters[]=$letter;
                }
                
    $my_title='';
                
    $size=sizeof($letters)-1;
     
                foreach(
    $data[$description] as $value){
                    if(isset(
    $value[$name])){
                        
    $my_title=$value[$name];
                    }else{
                        
    $lenth=8;
                        for(
    $i=0$i<$lenth$i++){
                            
    $my_title.=$letters[rand(0$size)];
                        }
                        break;
                    }
                }
     
                foreach(
    $tr as $ru=>$lat){
                    
    $my_title=str_replace($ru$lat$my_title);
                }
     
                return 
    $my_title;
            }
        }
    Это класс, который генерирует ссылку. В его метод generateSeoUrl() надо передать данные о созадаваемом товаре/категории/статьи. И дальше просто вставить сгенерированное слово в базу данных. для этого. Находим в директории /admin/model/catalog файлы : product.php, category.php и information.php. Это классы для создания (последовательно) товаров, категорий и информационных статей.
    В каждом из них есть по два метода: создатьНечто() и изменитьНечто():
    Для товаров: public function addProduct($data) и public function editProduct($data);
    Для категорий: public function addCategory($data) и public function editCategory($data);
    Для товаров: public function addInformation($data) и public function editInformation($data);

    Дальше всё очень просто. Находим в каждом из этих шести методов строки:
    PHP:
    if ($data['keyword']) {
                
    //здесь был запрос в БД
            
    }
    И заменяем его:
    Для продуктов:
    PHP:
    if ($data['keyword']) {
                
    $my_title=$data['keyword'];
            }else{
                
    $this->load->model('catalog/autoseourls');
                
    $seo=new ModelCatalogAutoseourls;
                
    $my_title=$seo->generateSeoUrl($data);
            }
            
    $this->db->query("INSERT INTO ".DB_PREFIX."url_alias SET query='product_id=".(int)$product_id."', keyword='".$this->db->escape($my_title)."'");
    Для категорий:
    PHP:
    if ($data['keyword']) {
                
    $my_title=$data['keyword'];
            }else{
                
    $this->load->model('catalog/autoseourls');
                
    $seo=new ModelCatalogAutoseourls;
                
    $my_title=$seo->generateSeoUrl($data);
            }
            
    $this->db->query("INSERT INTO ".DB_PREFIX."url_alias SET query='category_id=".(int)$category_id."', keyword='".$this->db->escape($my_title)."'");
    Для статей:
    PHP:
    if ($data['keyword']) {
                
    $my_title=$data['keyword'];
            }else{
                
    $this->load->model('catalog/autoseourls');
                
    $seo=new ModelCatalogAutoseourls;
                
    $my_title=$seo->generateSeoUrl($data);
            }
            
    $this->db->query("INSERT INTO ".DB_PREFIX."url_alias SET query='information_id=".(int)$information_id."', keyword='".$this->db->escape($my_title)."'");
    И всё. Теперь при создании статей, продуктов и категорий ЧПУ генерируются автоматически. При изменении старых статей, категорий и товаров (созданных без внесения ЧПУ вручную) - тоже.
    Работает стабильно, можете ничего не боясь, пользоваться.
    Только помните: это работает Только при включённом seo pro!
    Всем спасибо за внимание.
     
    Bnopen нравится это.
  2. ixion

    ixion

    Регистрация:
    16 янв 2013
    Сообщения:
    121
    Симпатии:
    75
    спасибо конечно, но зачем эти мучения если есть модуль Deadcow Seo, минус вашего метода что нельзя сгенерировать ЧПУ для уже добавленных товаров. Ия так понял что при изменении названия товара будет меняться и ЧПУ что не есть хорошо для ПС.
     
    987654321 нравится это.
  3. Bnopen

    Bnopen Команда форума

    Регистрация:
    3 мар 2013
    Сообщения:
    1.156
    Симпатии:
    514
    Deadcow Seo тоже не всегда удобно использовать, а для нового магазина это хороший вариант. и названия товара разве так часто изменяются.
    rem kwadriga, недавно только создавал тему и заморачивался с этим вопросом здесь -
    http://wmasteru.ru/threads/seo-pro-и-20.4510/
    Я так думаю, что и с сео про с кешированием должно без проблем работать? Вот этим -
    http://opencartforum.ru/topic/10270-дубли-страниц-seopro/
    Скажите, а можно ли как-то изменить ваш код, чтобы для товара формировался url не из названия товара - а из модели?
    Если да, то прекрасно - буду тестить и использовать вместе с сео про с кешем.
     
  4. Florenco

    Florenco

    Регистрация:
    3 мар 2013
    Сообщения:
    220
    Симпатии:
    101
    Так попробуйте:

    поменять:
    Код:
    }elseif(isset($data['product_description'])){
    $description='product_description';
    на это:
    Код:
    }elseif(isset($data['model'])){
      $description='model';
     
  5. Grek

    Grek

    Регистрация:
    18 янв 2013
    Сообщения:
    172
    Симпатии:
    18
    Вопрос здесь:
    И заменяем его...

    А если у меня уже стоит DeadCow ,код сейчас такой: ( /admin/model/catalog/product.php) :
    Код:
    if ($data['keyword']) {
    			$this->db->query("INSERT INTO " . DB_PREFIX . "url_alias SET query = 'product_id=" . (int)$product_id . "', keyword = '" . $this->db->escape($data['keyword']) . "'");
    		} else {
    			$this->load->model('catalog/manufacturer');
    			$manufacturer = $this->model_catalog_manufacturer->getManufacturer((int)$data['manufacturer_id']);
    			$manufacturerName = '';
    			if ($manufacturer) {
    				$manufacturerName = $manufacturer['name'];
    			}
    			$this->load->model('module/deadcow_seo');
    			if ($productName) {
    				$this->model_module_deadcow_seo->generateProduct($product_id, $productName, $data['model'], $manufacturerName, $this->config->get('deadcow_seo_products_template'), $this->config->get('config_language'));
    			}
    		}
    Так что мне из этого кода удалить? И что будет с deadcow_seo после этих правок? Идея очень классная, только как можно совместить и ваш способ, и deadcow_seo?
     
  6. rem kwadriga

    rem kwadriga

    Регистрация:
    14 дек 2012
    Сообщения:
    43
    Симпатии:
    3
    Всё совсем не так.
    Изменяемый товар (метод productUpdate()) тоже обзаводится новеньким урлом, если ранее его не имел. При переименовании товара (если у него был сгенерирован ранее или создан вручную ЧПУ) - урл остаётся старый.
    Минус метода в том, что он не предусматривает случая совпадения имён и присутствует дублирование кода. Но класс можно модифицировать (на что у меня просто нет времени). Это, считайте: демо-версия.
    --- добавлено: Mar 25, 2013 8:22 AM ---
    Если судить по этой строчке ($this->model_module_deadcow_seo->generateProduct($product_id, $productName, $data['model'], $manufacturerName, $this->config->get('deadcow_seo_products_template'), $this->config->get('config_language')):wink: - то ничего менять вовсе не нужно, потому что здесь в генерации сео-урла присутсвует не только название товара, но и имя производителя (если есть), и айди продукта, и его модель). То есть вероятность совпадения имён сведена к нулю, в отличии от моего метода. Рекомендую ничего не менять в выше приведённом коде, если нет каких-либо принципиальных претензий к его работе.
    --- добавлено: Mar 25, 2013 8:29 AM ---
    Впрочем, спасибо за рекомендацию метода. Видел код, вроде разумно. Я о нём раньше не знал, а нужно было быстрое и простое решение. Впрочем, если в мой метод добавить модель товара (это тоже обязательный параметр при создании), то вероятность совпадения имён сведётся практически к нулю. Хотя для полной уверенности лучше использовать айдишники - они точно уникальны. Зачем в вышеприведённом коде юзается сразу всё (вплоть до имени производителя) - я не пониаю.
     
  7. ixion

    ixion

    Регистрация:
    16 янв 2013
    Сообщения:
    121
    Симпатии:
    75
    там самостоятельно задаешь маску для генерации, я например генерирую по методу бренд-модель, названия товаров слишком длинные
     
  8. Deemonikus

    Deemonikus

    Регистрация:
    8 янв 2013
    Сообщения:
    1
    Симпатии:
    0
    А можно ли задать эту маску не только при ручной генерации урлов, а при создании или обновлении товара? При создании товара Deadcow Seo генерирует только по имени товара, а мне бы по маске [product_name]-[model_name]
     
  9. iga

    iga

    Регистрация:
    6 фев 2014
    Сообщения:
    145
    Симпатии:
    20
    Если кому вдруг лень символы менять...
    Я немного модифицировал транслитерацию.
    Заголовок "Товар Номер Один" получит урл "tovar_nomer_odin"

    Меняем большие буковки на маленькие
    Код:
    private $transliterate=array ("А"=>"a","Б"=>"b","В"=>"v","Г"=>"g","Д"=>"d","Е"=>"e","Ж"=>"j","З"=>"z","И"=>"i","Й"=>"y","К"=>"k","Л"=>"l","М"=>"m","Н"=>"n",
                "О"=>"o","П"=>"p","Р"=>"r","С"=>"s","Т"=>"t","У"=>"u","Ф"=>"f","Х"=>"h","Ц"=>"ts","Ч"=>"ch","Ш"=>"sh","Щ"=>"sch","Ъ"=>"","Ы"=>"yi",
                "Ь"=>"","Э"=>"e","Ю"=>"yu","Я"=>"ya","а"=>"a","б"=>"b","в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"j","з"=>"z","и"=>"i","й"=>"y","к"=>"k",
                "л"=>"l","м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r","с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h","ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch",
                "ъ"=>"y","ы"=>"yi","ь"=>"'","э"=>"e", "ё"=>"e", "Ё"=>"e", "ю"=>"yu","я"=>"ya","."=>"_"," "=>"_","?"=>"_","/"=>"_","\\"=>"_","*"=>"_",":"=>"_",
                "*"=>"-",">"=>"-","|"=>"-","'"=>"");
    Мне кажется так эстетичнее :Smile:
     
    Последнее редактирование: 8 фев 2014
  10. keksik

    keksik

    Регистрация:
    1 мар 2014
    Сообщения:
    3
    Симпатии:
    0
    Подскажите, для статей внести изменения в каком файле? где он располагается? спасибо
    --- Добавлено, 1 мар 2014 ---
    пытаюсь создать новую статью, все нормально создается - но постоянно вылетает ошибка Notice: Undefined variable: category_id in /сайт/public_html/admin/model/catalog/information.php on line 74Warning: Cannot modify header information - headers already sent by (output started at /сайт/public_html/admin/index.php:86) in /сайт/public_html/vqmod/vqcache/vq2-system_engine_controller.php on line 28Warning: Cannot modify header information - headers already sent by (output started at /сайт/public_html/admin/index.php:86) in /сайт/public_html/vqmod/vqcache/vq2-system_engine_controller.php on line 29
     
    Последнее редактирование: 1 мар 2014
  11. Гена Тер

    Гена Тер

    Регистрация:
    6 мар 2014
    Сообщения:
    1
    Симпатии:
    0
    Есть ли возможность добавления префикса в дочернюю ссылку в зависимости от ее родителя? К примеру, my-site.ru/wheels/whe-bmw или my-site.ru/bampers/bam-bmw