PivotSaveBehavior::savePivots()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 10
c 2
b 0
f 1
dl 0
loc 14
rs 8.8333
cc 7
nc 9
nop 0
1
<?php
2
3
4
namespace carono\yii2file\behaviors;
5
6
7
use carono\yii2file\FileUploadTrait;
8
use carono\yii2migrate\traits\PivotTrait;
9
use yii\db\ActiveRecord;
10
11
/**
12
 * Class PivotSaveBehavior
13
 *
14
 * @package app\behaviors
15
 * @property PivotTrait|ActiveRecord $owner
16
 */
17
class PivotSaveBehavior extends \yii\base\Behavior
18
{
19
    protected $_pivots;
20
    public $attribute;
21
    public $pivotClass;
22
    public $modelClass;
23
    public $prepareValues;
24
    public $deletePivotsBeforeSave = true;
25
    public $savePivots;
26
    public $inverseInsertPivot = false;
27
28
    public function canSetProperty($name, $checkVars = true)
29
    {
30
        return $name == $this->attribute;
31
    }
32
33
    public function __set($name, $value)
34
    {
35
        if ($this->canSetProperty($name)) {
36
            $this->setPivots($value);
37
        } else {
38
            parent::__set($name, $value);
39
        }
40
    }
41
42
    public function getStoredPivots($attribute)
43
    {
44
        if ($attribute == $this->attribute) {
45
            return $this->_pivots;
46
        }
47
48
        return null;
49
    }
50
51
    /**
52
     * @return ActiveRecord|FileUploadTrait
53
     */
54
    protected function getModelClass()
55
    {
56
        return $this->modelClass;
57
    }
58
59
    protected function setPivots($values)
60
    {
61
        $class = $this->getModelClass();
62
        $this->_pivots = [];
63
        if ($this->prepareValues instanceof \Closure) {
64
            $values = call_user_func($this->prepareValues, (array)$values);
65
        }
66
        foreach ((array)$values as $value) {
67
            if (is_numeric($value)) {
68
                $this->_pivots[] = $class::findOne($value);
69
            } elseif ($value instanceof $class) {
70
                $this->_pivots[] = $value;
71
            }
72
        }
73
        $eventName = $this->owner->isNewRecord ? ActiveRecord::EVENT_AFTER_INSERT : ActiveRecord::EVENT_AFTER_UPDATE;
74
        if ($this->savePivots instanceof \Closure) {
75
            call_user_func($this->savePivots, $this, $this->pivotClass, $this->_pivots);
76
        } else {
77
            $this->owner->on($eventName, [$this, 'savePivots']);
0 ignored issues
show
Bug introduced by
It seems like on() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
            $this->owner->/** @scrutinizer ignore-call */ 
78
                          on($eventName, [$this, 'savePivots']);
Loading history...
78
        }
79
    }
80
81
    public function savePivots()
82
    {
83
        if (!method_exists($this->owner, 'addPivot')) {
84
            throw new \Exception('Class ' . get_class($this->owner) . ' must use carono\yii2migrate\traits\PivotTrait trait');
85
        }
86
        if ($this->deletePivotsBeforeSave && $this->_pivots !== null) {
87
            $this->owner->deletePivots($this->pivotClass);
88
        }
89
        if ($this->_pivots) {
90
            foreach ($this->_pivots as $pv) {
91
                if ($this->inverseInsertPivot) {
92
                    $pv->addPivot($this->owner, $this->pivotClass);
93
                } else {
94
                    $this->owner->addPivot($pv, $this->pivotClass);
95
                }
96
            }
97
        }
98
    }
99
}