79 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| 
 | |
| namespace common\behaviors;
 | |
| 
 | |
| 
 | |
| use dosamigos\transliterator\TransliteratorHelper;
 | |
| use yii;
 | |
| use yii\base\Behavior;
 | |
| use yii\db\ActiveRecord;
 | |
| use yii\helpers\Inflector;
 | |
| 
 | |
| class Slug extends Behavior
 | |
| {
 | |
|     public $in_attribute = 'name';
 | |
|     public $out_attribute = 'slug';
 | |
|     public $translit = true;
 | |
| 
 | |
|     public function events()
 | |
|     {
 | |
|         return [
 | |
|             ActiveRecord::EVENT_BEFORE_VALIDATE => 'getSlug'
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     public function getSlug($event)
 | |
|     {
 | |
|         if (empty($this->owner->{$this->out_attribute})) {
 | |
|             $this->owner->{$this->out_attribute} = $this->generateSlug($this->owner->{$this->in_attribute});
 | |
|         } else {
 | |
|             $this->owner->{$this->out_attribute} = $this->generateSlug($this->owner->{$this->out_attribute});
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private function generateSlug($slug)
 | |
|     {
 | |
|         $slug = $this->slugify($slug);
 | |
|         if ($this->checkUniqueSlug($slug)) {
 | |
|             return $slug;
 | |
|         } else {
 | |
|             for ($suffix = 2; !$this->checkUniqueSlug($new_slug = $slug . '-' . $suffix); $suffix++) {
 | |
|             }
 | |
|             return $new_slug;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private function slugify($slug)
 | |
|     {
 | |
|         if ($this->translit) {
 | |
|             return Inflector::slug(TransliteratorHelper::process($slug), '-', true);
 | |
|         } else {
 | |
|             return $this->slug($slug, '-', true);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private function slug($string, $replacement = '-', $lowercase = true)
 | |
|     {
 | |
|         $string = preg_replace('/[^\p{L}\p{Nd}]+/u', $replacement, $string);
 | |
|         $string = trim($string, $replacement);
 | |
|         return $lowercase ? strtolower($string) : $string;
 | |
|     }
 | |
| 
 | |
|     private function checkUniqueSlug($slug)
 | |
|     {
 | |
|         $pk = $this->owner->primaryKey();
 | |
|         $pk = $pk[0];
 | |
| 
 | |
|         $condition = $this->out_attribute . ' = :out_attribute';
 | |
|         $params = [':out_attribute' => $slug];
 | |
|         if (!$this->owner->isNewRecord) {
 | |
|             $condition .= ' and ' . $pk . ' != :pk';
 | |
|             $params[':pk'] = $this->owner->{$pk};
 | |
|         }
 | |
| 
 | |
|         return !$this->owner->find()
 | |
|             ->where($condition, $params)
 | |
|             ->one();
 | |
|     }
 | |
| } | 
