FileloaderBehavior.php
3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?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,
                             ]);
                         });
        }
    }