Yii Framework. Генерим алиасы.

Yii Framework. Генерим алиасы.
Yii framework. Создаем уникальный алиас для генерации ЧПУ используя заголовки для статей блога.

Для создания красивых ЧПУ, бывает полезно генерировать уникальные заголовки для материалов на транслите. Вот я и решил поделится небольшим опытом по созданию подобных алиасов для статей в своем блоге на yii framework.

Для начала нам понадобится функция которая генерирует транслитерационные названия для русскоязычных имен. В интернете или на официальном сайте php подобных функций можно найти немало. Я в совем блоге использовал такую:

public function getAlias($input)
{
  $gost = array(
   "Є"=>"YE","І"=>"I","Ѓ"=>"G","і"=>"i","№"=>"-","є"=>"ye","ѓ"=>"g",
    "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G","Д"=>"D","Е"=>"E","Ё"=>"YO",
    "Ж"=>"ZH","З"=>"Z","И"=>"I","Й"=>"J","К"=>"K","Л"=>"L","М"=>"M",
    "Н"=>"N","О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T","У"=>"U",
    "Ф"=>"F","Х"=>"X","Ц"=>"C","Ч"=>"CH","Ш"=>"SH","Щ"=>"SHH","Ъ"=>"'",
    "Ы"=>"Y","Ь"=>"","Э"=>"E","Ю"=>"YU","Я"=>"YA","а"=>"a","б"=>"b",
    "в"=>"v","г"=>"g","д"=>"d","е"=>"e","ё"=>"yo","ж"=>"zh","з"=>"z",
    "и"=>"i","й"=>"j","к"=>"k","л"=>"l","м"=>"m","н"=>"n","о"=>"o",
    "п"=>"p","р"=>"r","с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"x",
    "ц"=>"c","ч"=>"ch","ш"=>"sh","щ"=>"shh","ъ"=>"","ы"=>"y","ь"=>"",
    "э"=>"e","ю"=>"yu","я"=>"ya"," "=>"_","—"=>"_",","=>"_","!"=>"_",
    "@"=>"_","#"=>"-","$"=>"","%"=>"","^"=>"","&"=>"","*"=>"","("=>"",
    ")"=>"","+"=>"","="=>"",";"=>"",":"=>"","'"=>"",'"'=>"","~"=>"",
    "`"=>"","?"=>"","/"=>"","\\"=>"","["=>"","]"=>"","{"=>"","}"=>"",
    "|"=>"","."=>""); 
   return strtr($input, $gost);
}

Можете добавить ее в модель или контроллер, я например сделал эту функцию методом класса созданного мной вспомогательного компонента приложения, в связи с тем что она мне понадобилась не только для статей но и категорий тоже. Затем создадим поле alias в таблице и изменим модель следующим образом: 

class Post extends CActiveRecord
{
...
private $_oldTitle;
...
protected function afterFind()
{
    parent::afterFind();    
    $this->_oldTitle = $this->title;		
}

protected function beforeSave()
{
   if(parent::beforeSave())
   {	
        if($this->isNewRecord)
        {
          //генерим алиас
          $this->saveAlias();
        } 
        else
        {	 	
           //при апдейте если меняли заголовок поста
           //то пересоздаем алиас
           if ($this->_oldTitle != $this->title)
               $this->saveAlias();			
        }
        return true;
    }
    else
      return false;
}

public function saveAlias() 
{		
   $alias = strtolower(getAlias($this->title));
   $model = Post::model()->findByAttributes(array(
     'title'=>$this->title,
     'alias'=>$alias
   ));		
   if ($model != null)
   {
	$model->alias = $model->id. '_'. $alias;	
	$model->save();					
   }		
   if (!Post::model()->findByAttributes(array('alias'=>$alias)))
        $this->alias = $alias;
   else 
        return false;
}
... 	

Сначала мы добавляем свойство _oldTitle и сохраняем в нем старое значение поля title в методе afterFind(вызывается автоматически при заполнении модели данными из БД). Это нам понадобится для того чтобы проверить изменился ли заголовок при апдейте статьи в методе beforeSave. Этот метод вызывает метод saveAlias в котором и происходит создание алиаса. 

Метод saveAlias ищет в базе статьи с тем же заголовком и алиасом как и у текущей статьи и если такая статья существует то добавляет к ее алиасу идентификатор этой статьи и нижнее подчеркивание. Таким образом обеспечивается уникальность сохраняемого алиаса. Обратите внимание в 36 строчке вызывается наша функция getAlias, которая должна быть описана заранее либо как метод модели либо каким либо другим способом.   

Комментарии

Нет комментариев

Добавить комментарий