FileloaderBehavior.php 3.63 KB
<?php
    namespace common\modules\fileloader\behaviors;

    use yii\base\Behavior;
    use yii\base\Event;
    use yii\db\ActiveQuery;
    use yii\db\ActiveRecord;
    use yii\validators\Validator;

    /**
     * Class FileloaderBehavior
     * @package common\modules\fileloader\behaviors
     */
    class FileloaderBehavior extends Behavior
    {

        /**
         * @var string $fileclass Classname that hande files
         */
        public $fileclass = 'common\models\File';

        /**
         * @var string $relationtable Table name that keeps relation between model and file
         */
        public $relationclass = 'common\modules\fileloader\models\FileRelation';

        /**
         * @var int[] Files ids to insert
         */
        public $fileloader = [ ];

        /**
         * @inheritdoc
         */
        public function events()
        {
            return [
                ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',
                ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',
                ActiveRecord::EVENT_INIT         => 'attachValidator',
            ];
        }

        public function attachValidator($event)
        {
            $validator = Validator::createValidator('safe', $this->owner, 'fileloader');
            $this->owner->validators->append($validator);
        }

        /**
         * After saving model delete all relative files and insert new file connections from
         * fileloader variable
         *
         * @param Event $event
         */
        public function afterSave($event)
        {
            /**
             * @var ActiveRecord $owner
             * @var string       $relation
             */
            $owner = $this->owner;
            $relation = $this->relationclass;
            call_user_func([
                $relation,
                'deleteAll',
            ], [
                'model'    => $owner->className(),
                'model_id' => $owner->primaryKey,
            ]);
            if(!empty( $owner->fileloader )) {
                foreach($owner->fileloader as $file) {
                    /**
                     * @var ActiveRecord $model
                     */
                    $model = new $relation([
                        'file_id'  => $file,
                        'model'    => $owner->className(),
                        'model_id' => $owner->primaryKey,
                        'user_id'  => \Yii::$app->user->getId(),
                        'status'   => 1,
                    ]);
                    if($model->validate()) {
                        $model->save(false);
                    }
                    unset( $model );
                }
            }
        }

        /**
         * Bind owner class tp specified $fileclass via $relationclass table.
         * @return ActiveQuery
         */
        public function getFileloaderFiles()
        {
            /**
             * @var ActiveRecord $owner
             */
            $owner = $this->owner;
            $relationtable = call_user_func([
                $this->relationclass,
                'tableName',
            ]);
            return $owner->hasMany($this->fileclass, [ 'file_id' => 'file_id' ])
                         ->viaTable($relationtable, [ 'model_id' => $owner->primaryKey()[ 0 ] ], function($query) use ($owner) {
                             /**
                              * @var ActiveQuery $query
                              */
                             $query->andWhere([
                                 'model'  => $owner->className(),
                                 'status' => 1,
                             ]);
                         });
        }
    }