Сохранение новых тегов в блоге

Пробую использовать метод с тэгами, используя модели и события. Что нужно изменить здесь, чтобы можно было добавлять произвольные тэги?

Если использовать такой метод, то теги сохраняются (из базы), но новые нельзя добавить в посте редактирования и сохранить.

Blog.php





  <?php


namespace medeyacom\blog\models;


use common\components\behaviors\StatusBehavior;

use Yii;

use yii\behaviors\TimestampBehavior;

use yii\db\ActiveRecord;

use yii\db\Expression;

use yii\web\UploadedFile;

use yii\helpers\Url;

use yii\helpers\ArrayHelper;

use common\models\ImageManager;

use common\models\User;




/**

 * This is the model class for table "blog".

 *

 * @property integer $id

 * @property string $title

 * @property string $image

 * @property string $text

 * @property string $date_create

 * @property string $date_update

 * @property string $url

 * @property integer $status_id

 * @property integer $sort

 */

class Blog extends ActiveRecord {


  const STATUS_LIST = ['off','on'];

  const IMAGES_SIZE = [

        ['50','50'],

        ['800',null],

    ];

  public $tags_array;

  public $file;

   


    /**

     * @inheritdoc

     */

  public static function tableName()

    {

        return 'blog';

    }




    public function behaviors()

    {

         return [

         'timestampBehavior'=>[

            'class' => TimestampBehavior::className(),

            'createdAtAttribute' => 'date_create',

            'updatedAtAttribute' => 'date_update',

            'value' => new Expression('NOW()'),

            ],

            'statusBehavior'=> [

            'class' => StatusBehavior::className(),

            'statusList'=> self::STATUS_LIST,

              ]

         ];

      }

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['title', 'url'], 'required'],

            [['text'], 'string'],

            [['url'], 'unique'],

            [['status_id', 'sort'], 'integer'],

            [['sort'], 'integer','max'=>99, 'min'=>1],

            [['title', 'url'], 'string', 'max' => 150],

            [['image'], 'string', 'max' => 100],

            [['image'], 'file', 'extensions'=>'jpg, gif, png, svg'],

            [['file'], 'image'],

            [['tags_array','date_create','date_update'],'safe'],


        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'title' => 'Заголовок',

            'text' => 'Текст',

            'url' => 'ЧПУ',

            'status_id' => 'Статус',

            'sort' => 'Сортировка',

            'date_update' => 'Обновлено',

            'date_create' => 'Создано',

            'tags_array' => 'Тэги',

            'tagsAsString' => 'Тэги',

            'image' => 'Картинка',

            'file' => 'Картинка',

            'author.username'=>'Имя Автора',

            'author.email'=>'Почта Автора',


        ];

    }


    public function getAuthor () {

      return $this->hasOne (User::className(),['id'=>'user_id']);

    

    }

     public function getImages()

    {

        return $this->hasMany(ImageManager::className(), ['item_id' => 'id'])->andWhere(['class'=>self::tableName()])->orderBy('sort');

    }


      public function getImagesLinks()

    {

        return ArrayHelper::getColumn($this->images,'imageUrl');

    }


     public function getImagesLinksData()

    {

        return ArrayHelper::toArray($this->images,[

                ImageManager::className() => [

                    'caption'=>'name',

                    'key'=>'id',

                ]]

        );

    }

     public function getBlogTag () {

      return $this->hasMany(BlogTag::className(),['blog_id'=>'id']);

    }


     public function getTags()

    {

      return $this->hasMany(Tag::className(),['id'=>'tag_id'])->via('blogTag');

    }


      public function getTagsAsString() 

    {  

       $arr = \yii\helpers\ArrayHelper::map($this->tags,'id','name');

       return implode (', ',$arr);

    }




 public function getSmallImage() 

    {  

      if($this->image){

        $path = str_replace('admin.','',Url::home(true)).'uploads/images/blog/50x50/'.$this->image;

      }else{


        $path = str_replace('admin.','', Url::home(true)).'uploads/images/ss.jpg';

      } 

      return $path;

     }





       public function afterFind() 

    {  

      parent::afterFind();

      $this->tags_array = $this->tags;

    }




 public function beforeSave ($insert)


{  

  if ($file = UploadedFile::getInstance($this,'file')) {

      $dir = Yii::getAlias('@images').'/blog/';

  if (!is_dir($dir . $this->image)) {

  if (file_exists($dir.$this->image)){

     unlink($dir.$this->image);

  }

  if (file_exists($dir.'50x50/'.$this->image)) {

     unlink($dir.'50x50/'.$this->image);

  }

  if (file_exists($dir. '800x/'.$this->image)) {

     unlink($dir.'800x/'.$this->image);

  }

}

    $this->image = strtotime ('now').'_'.Yii::$app->getSecurity()->generateRandomString(6) .'.'. $file->extension;

    $file ->saveAs($dir.$this->image);

    $imag = Yii::$app->image->load($dir.$this->image);

    $imag ->background ('#fff',0);

    $imag ->resize ('50','50', Yii\image\drivers\Image::INVERSE);

    $imag ->crop ('50','50');

    $imag ->save($dir.'50x50/'.$this->image, 90);

    $imag = Yii::$app->image->load($dir.$this->image);

    $imag->background('#fff',0);

    $imag->resize('800',null, Yii\image\drivers\Image::INVERSE);

    $imag->save($dir.'800x/'.$this->image, 90);


    }

      return parent::beforeSave($insert);

  }




   public function afterSave ($insert, $changedAttributes) 

    {

      parent::afterSave($insert, $changedAttributes);


      $arr = \yii\helpers\ArrayHelper::map($this->tags,'id','id');

      foreach ($this->tags_array as $one) {

       if(!in_array($one,$arr)){

          $model = new BlogTag();

          $model->blog_id = $this->id;

          $model->tag_id = $one;

          $model->save();

      }

      if(isset($arr[$one])) {

         unset ($arr[$one]);

      }

      }

       BlogTag::deleteAll(['tag_id'=>$arr]);

  }




 public function beforeDelete()

        {

            if (parent::beforeDelete()) {

                $dir = Yii::getAlias('@images').'/blog/';

                if(file_exists($dir.$this->image)){

                    unlink($dir.$this->image);

                }

                foreach (self::IMAGES_SIZE as $size){

                    $size_dir = $size[0].'x';

                    if($size[1] !== null)

                        $size_dir .= $size[1];

                    if(file_exists($dir.$this->image)){

                        unlink($dir.$size_dir.'/'.$this->image);

                    }

                }

                

                 BlogTag::deleteAll(['blog_id'=>$this->id]);

                

               return true;

            } else {

                return false;

            }

        }

}

 

 

 

Но когда пробую реализовать сохранение тегов другим методом, то ничего не сохраняется. 2 вариант кода ниже.

Попробую объяснить как бы хотелось реализовать, хотя сам не оч.понимаю логику))


 public function afterFind()

    {

     $this->newtags = \yii\helpers\ArrayHelper::map($this->tags,'tag','tag');

}

function ‘afterFind’ происходит когда загрузились данные из базы в модель, заполнили данные модели т.е. когда в посте редактирования нажали ‘update’, то туда должны подтягиваться теги, которые связаны (а они, по идее, хранятся в ‘newtags’ , а изначально он = ‘null’ и соответственно, в afterFind мы их наполняем. При этом дёргая связь "Get tags ’ После этого, должны получить из неё массив $this ->tags (т.к. это ‘HasMany’ и дальше надо сделать из этого массив, чтобы скормить его vidget Select 2

Для этого берем данные $this ->tags с помощью ArrayHelper:: map- передаем данные и говорим, что нужно, чтобы был атрибут ‘tag’ из модели Таг.php ($property tag ) - он же был и ключем и значением.- это так надо для Select 2 т.е. он заполняется и во views нужно передать.

У меня есть таблица “blog_tag’ и связь 'getBlogTag”- она как-бы промежуточная между ‘blog’ и ‘tag’ и в ней есть ‘blog_id’ и 'tag_id"

Blog.php




<?php


namespace medeyacom\blog\models;


use common\components\behaviors\StatusBehavior;

use Yii;

use yii\behaviors\TimestampBehavior;

use yii\db\ActiveRecord;

use yii\db\Expression;

use yii\helpers\ArrayHelper;

use yii\helpers\Url;

use yii\web\UploadedFile;

use common\models\User;

use common\models\ImageManager;


/**

 * This is the model class for table "blog".

 *

 * @property integer $id

 * @property string $title

 * @property string $text

 * @property string $image

 * @property string $url

 * @property string $date_create

 * @property string $date_update

 * @property integer $status_id

 * @property integer $sort

 */

class Blog extends ActiveRecord

{

    const STATUS_LIST = ['off','on'];

    const IMAGES_SIZE = [

        ['50','50'],

        ['800',null],

    ];

    public $tags_array;

    public $file;

    public $newtags;




    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'blog';

    }


    public function behaviors()

    {

        return [

            'timestampBehavior'=>[

                'class' => TimestampBehavior::className(),

                'createdAtAttribute' => 'date_create',

                'updatedAtAttribute' => 'date_update',

                'value' => new Expression('NOW()'),

            ],

            'statusBehavior'=>[

                'class' => StatusBehavior::className(),

                'statusList' => self::STATUS_LIST,

            ]

        ];

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['title', 'url'], 'required'],

            [['text'], 'string'],

            [['url'], 'unique'],

            [['status_id', 'sort'], 'integer'],

            [['sort'], 'integer', 'max'=>99, 'min'=>1],

            [['title', 'url'], 'string', 'max' => 150],

            [['image'], 'string', 'max' => 100],

            [['file'], 'image'],

            [['newtags'], 'safe'],

           [['tags_array','date_create','date_update'], 'safe'],

           ];

        

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'title' => 'Заголовок',

            'text' => 'Текст',

            'url' => 'ЧПУ',

            'status_id' => 'Статус',

            'sort' => 'Сортировка',

            'tags_array' => 'Теги',

            'image' => 'Картинка',

            'file' => 'Картинка',

            'tagsAsString' => 'Теги',

            'author.username' => 'Имя Автора',

            'author.email' => 'Почта Автора',

            'date_update' => 'Обновлено',

            'date_create' => 'Создано',

            'smallImage'=> 'Картинка',

            'newtags' => 'теги',

        ];

    }




    public function getAuthor(){

        return $this->hasOne(User::className(),['id'=>'user_id']);

    }

    public function getImages()

    {

        return $this->hasMany(ImageManager::className(), ['item_id' => 'id'])->andWhere(['class'=>self::tableName()])->orderBy('sort');

    }

    public function getImagesLinks()

    {

        return ArrayHelper::getColumn($this->images,'imageUrl');

    }

    public function getImagesLinksData()

    {

        return ArrayHelper::toArray($this->images,[

                ImageManager::className() => [

                    'caption'=>'name',

                    'key'=>'id',

                ]]

        );

    }

    public function getBlogTag(){

        return $this->hasMany(BlogTag::className(),['blog_id'=>'id']);

    }


    public function getTags()

    {

        return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->via('blogTag');

    }


    public function getTagsAsString()

    {

        $arr = \yii\helpers\ArrayHelper::map($this->tags,'id','name');

        return implode(', ',$arr);

    }


    public function getSmallImage()

    {

        if($this->image){

            $path = str_replace('admin.','',Url::home(true)).'uploads/images/blog/50x50/'.$this->image;

        }else{

            $path = str_replace('admin.','',Url::home(true)).'uploads/images/ss.jpg';

        }

        return $path;

    }




  public function beforeDelete()

      

        {   

        	if (parent::beforeDelete()) {

                $dir = Yii::getAlias('@images').'/blog/';

            /* if($this->image != '')*/

          /* if(!empty($this->image))*/

           if(file_exists($dir.$this->image)){

                    unlink($dir.$this->image);

                }

           /* if($this->image && file_exists($dir.$this->image))

        if (isset($this->image) && file_exists($idr.$this->image)){

              unlink($dir.$this->image);}*/

                

        /* if(file_exists($dir.$this->image)){

                    unlink($dir.$this->image);*/

                  foreach (self::IMAGES_SIZE as $size){

                    $size_dir = $size[0].'x';

            if($size[1] !== null)

                        $size_dir .= $size[1];

            if(file_exists($dir.$this->image)){

                        unlink($dir.$size_dir.'/'.$this->image);

                    }

                } 

        

           BlogTag::deleteAll(['blog_id'=>$this->id]);

           return true;

                 } else {

            return false;

              }

        }

    


    public function afterFind()

    {

     /*  parent::afterFind();

        $this->tags_array = $this->tags;*/

       

   $this->newtags = \yii\helpers\ArrayHelper::map($this->tags,'tag','tag');

}


  public function afterSave($insert, $changedAttributes)

    {

       /* parent::afterSave($insert, $changedAttributes);

       $arr = \yii\helpers\ArrayHelper::map($this->tags,'id','id');

        foreach ($this->tags_array as $one){

            if(!in_array($one,$arr)){

                $model = new BlogTag();

                $model->blog_id = $this->id;

                $model->tag_id = $one;

                $model->save();

            }

            if(isset($arr[$one])){

                unset($arr[$one]);

            }*/


            if (is_array($this->newtags)) {

                $old_tags = ArrayHelper::map($this->tags,'tag','id');

                foreach ($this ->newtags as $one_new_tag) {

                    if (isset($old_tags[$one_new_tag])) {

                        unset($old_tags[$one_new_tag]);

                    

                    } else{

                       if($tg = $this->createNewTag($one_new_tag)){

                        Yii::$app->session->addFlash('success','добавлен тег' . $one_new_tag);

                    }else{

                        Yii::$app->session->addFlash('error','тег' . $one_new_tag . 'тег не добавился');

                       }

                    }

                }

                

        BlogTag::deleteAll(['and',['blog_id'=>$this->id],['tag_id'=>$old_tags]]);

    }else{

        /*BlogTag::deleteAll(['blog_id'=>$this->id]);*/

       BlogTag::deleteAll(['tag_id'=>$arr]);

    }

}




    private function createNewTag ($new_tag) {

    	

        if(!$tag = Tag::find()->andWhere(['tag'=>$new_tag])->one()){

            $tag = new Tag();

            $tag ->tag = $new_tag;

            if(!$tag->save()) {

                $tag =null;

            }

        }

        if ($tag instanceof Tag) {

            $blog_tag = new BlogTag();

            $blog_tag->blog_id = $this->id;

            $blog_tag->tag_id = $tag->id;

            if($blog_tag->save())

                return $blog_tag->id;

        }

        return false;

    }







    public function beforeSave($insert)

    {

        if($file = UploadedFile::getInstance($this, 'file')){

            $dir = Yii::getAlias('@images').'/blog/';

            if(file_exists($dir.$this->image)){

                unlink($dir.$this->image);

            }

            if(file_exists($dir.'50x50/'.$this->image)){

                unlink($dir.'50x50/'.$this->image);

            }

            if(file_exists($dir.'800x/'.$this->image)){

                unlink($dir.'800x/'.$this->image);

            }

            $this->image = strtotime('now').'_'.Yii::$app->getSecurity()->generateRandomString(6)  . '.' . $file->extension;

            $file->saveAs($dir.$this->image);

            $imag = Yii::$app->image->load($dir.$this->image);

            $imag->background('#fff',0);

            $imag->resize('50','50', Yii\image\drivers\Image::INVERSE);

            $imag->crop('50','50');

            $imag->save($dir.'50x50/'.$this->image, 90);

            $imag = Yii::$app->image->load($dir.$this->image);

            $imag->background('#fff',0);

            $imag->resize('800',null, Yii\image\drivers\Image::INVERSE);

            $imag->save($dir.'800x/'.$this->image, 90);

        }

        return parent::beforeSave($insert);

    }




 }