Passed
Pull Request — master (#28)
by
unknown
10:31
created

ExtendedCollection::performOperation()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 4
eloc 10
c 1
b 1
f 1
nc 5
nop 3
dl 0
loc 18
rs 9.9332
1
<?php
2
/**
3
 * ActiveRecord for API
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\hiart;
12
13
use Closure;
14
15
/**
16
 * {@inheritdoc}
17
 */
18
class ExtendedCollection extends Collection
19
{
20
    /**
21
     * {@inheritdoc}
22
     */
23
    public $checkConsistency = false;
24
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function insert($runValidation = true, $attributes = null, array $queryOptions = [])
29
    {
30
        if (!$attributes) {
31
            $attributes = $this->attributes ?: $this->first->activeAttributes();
32
        }
33
        if ($runValidation && !$this->validate($attributes)) {
34
            return false;
35
        }
36
        if (!$this->beforeSave(true)) {
37
            return false;
38
        }
39
40
        $data    = $this->collectData($attributes);
41
        $results = $this->performOperation('create', $data, $queryOptions);
42
        $pk      = $this->first->primaryKey()[0];
43
        foreach ($this->models as $key => $model) {
44
            $values = &$data[$key];
45
            $result = &$results[$key];
46
            if (!$result) {
47
                $result = $this->findAssociatedModelData($results, $model, $pk);
48
            }
49
50
            $model->{$pk} = $result['id'];
51
            if ($pk !== 'id') {
52
                $values[$pk] = $result['id'];
53
            }
54
            $changedAttributes = array_fill_keys(array_keys($values), null);
55
            $model->setOldAttributes($values);
56
            $model->afterSave(true, $changedAttributes);
57
        }
58
59
        $this->afterSave();
60
61
        return true;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function update($runValidation = true, $attributes = null, array $queryOptions = [])
68
    {
69
        if (!$attributes) {
70
            $attributes = $this->attributes ?: $this->first->activeAttributes();
71
        }
72
        if ($runValidation && !$this->validate($attributes)) {
73
            return false;
74
        }
75
        if (!$this->beforeSave()) {
76
            return false;
77
        }
78
79
        $data    = $this->collectData($attributes);
80
        $results = $this->performOperation('update', $data, $queryOptions);
0 ignored issues
show
Unused Code introduced by
The assignment to $results is dead and can be removed.
Loading history...
81
82
        foreach ($this->models as $key => $model) {
83
            $changedAttributes = [];
84
            $values            = array_key_exists($key, $data) ? $data[$key] : $data[$model->id]; /// XXX not good
85
            foreach ($values as $name => $value) {
86
                $changedAttributes[$name] = $model->getOldAttribute($name);
87
                $model->setOldAttribute($name, $value);
88
            }
89
            $model->afterSave(false, $changedAttributes);
90
        }
91
92
        $this->afterSave();
93
94
        return true;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function delete()
101
    {
102
        if (!$this->beforeDelete()) {
103
            return false;
104
        }
105
106
        $data    = $this->collectData();
107
        $results = $this->performOperation('delete', $data);
108
109
        $this->afterDelete();
110
111
        return $results;
112
    }
113
114
    /**
115
     * Collects data from the stored models.
116
     * @param string|array $attributes list of attributes names
117
     * @return array
118
     */
119
    public function collectData($attributes = null)
120
    {
121
        $data = [];
122
        foreach ($this->models as $model) {
123
            if ($this->dataCollector instanceof Closure) {
124
                list($key, $row) = call_user_func($this->dataCollector, $model, $this);
125
            } else {
126
                $key = $model->getPrimaryKey();
127
                $row = $model->getAttributes($this->isConsistent() ? $attributes : $model->attributes);
0 ignored issues
show
Bug introduced by
It seems like $this->isConsistent() ? ...es : $model->attributes can also be of type string; however, parameter $names of yii\base\Model::getAttributes() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

127
                $row = $model->getAttributes(/** @scrutinizer ignore-type */ $this->isConsistent() ? $attributes : $model->attributes);
Loading history...
128
                $row['recordModel'] = $model;
129
            }
130
131
            if ($key) {
132
                $data[$key] = $row;
133
            } else {
134
                $data[] = $row;
135
            }
136
        }
137
138
        return $data;
139
    }
140
141
    /**
142
     * Perform operation with collection models
143
     * @param string $command (create||update||delete)
144
     * @param array $data
145
     * @param array $queryOptions
146
     * @return array
147
     */
148
    protected function performOperation(string $command, array $data, array $queryOptions = []) : array
149
    {
150
        if ($this->isConsistent()) {
151
            return $this->first->batchQuery($command, $data, $queryOptions);
152
        }
153
154
        foreach ($data as $key => $record) {
155
            $records[$record['recordModel']->className()][$key] = $record;
156
        }
157
158
        $results = [];
159
        foreach ($records as $className => $d) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $records seems to be defined by a foreach iteration on line 154. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
160
            $row = reset($d);
0 ignored issues
show
Unused Code introduced by
The assignment to $row is dead and can be removed.
Loading history...
161
            $model = $d['recordModel'];
162
            $results = array_merge($results, $model->batchQuery($command, $d, $queryOptions));
163
        }
164
165
        return $results;
166
    }
167
}
168