This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @link https://github.com/rkit/filemanager-yii2 |
||
5 | * @copyright Copyright (c) 2015 Igor Romanov |
||
6 | * @license [MIT](http://opensource.org/licenses/MIT) |
||
7 | */ |
||
8 | |||
9 | namespace rkit\filemanager\behaviors; |
||
10 | |||
11 | use Yii; |
||
12 | use yii\helpers\ArrayHelper; |
||
13 | use yii\db\Query; |
||
14 | |||
15 | class FileBind |
||
16 | { |
||
17 | 21 | public function bind($model, $attribute, $files) |
|
18 | { |
||
19 | 21 | $newFiles = $this->newFiles($model, $attribute, $files); |
|
20 | 21 | if (!count($newFiles)) { |
|
21 | 2 | return false; |
|
22 | } |
||
23 | |||
24 | 20 | $currentFiles = $this->files($model, $attribute); |
|
25 | 20 | $currentRelations = $this->relations($model, $attribute); |
|
26 | 20 | $insertData = $this->prepareInsertRelations($model, $attribute, $newFiles); |
|
27 | 20 | $updateData = $this->prepareUpdateRelations($model, $attribute, $newFiles, $currentRelations); |
|
28 | |||
29 | 20 | $resultFiles = $insertData['files'] + $updateData['files']; |
|
30 | 20 | if (!count($resultFiles)) { |
|
31 | return false; |
||
32 | } |
||
33 | |||
34 | 20 | $this->delete($model, $attribute, array_diff_key($currentFiles, $resultFiles)); |
|
35 | 20 | $this->save($model, $attribute, $insertData, $updateData, $resultFiles); |
|
36 | |||
37 | 20 | return $resultFiles; |
|
38 | } |
||
39 | |||
40 | 20 | private function save($model, $attribute, $insertData, $updateData, $resultFiles) |
|
41 | { |
||
42 | 20 | if (count($insertData['rows'])) { |
|
43 | 20 | $this->insertRelations($model, $attribute, $insertData['rows'], $insertData['columns']); |
|
44 | 20 | } |
|
45 | 20 | if (count($updateData['rows'])) { |
|
46 | 2 | $this->updateRelations($model, $attribute, $updateData['rows']); |
|
47 | 2 | } |
|
48 | 20 | if (count($resultFiles)) { |
|
49 | 20 | $this->updateFiles($model, $attribute, $resultFiles); |
|
50 | 20 | } |
|
51 | 20 | } |
|
52 | |||
53 | 21 | private function newFiles($model, $attribute, $fileIds) |
|
54 | { |
||
55 | 21 | $relation = $model->fileRelation($attribute); |
|
56 | 21 | $fileModel = $relation->modelClass; |
|
57 | |||
58 | 21 | return $fileModel::find() |
|
59 | 21 | ->where([key($relation->link) => $fileIds]) |
|
60 | 21 | ->indexBy(key($relation->link)) |
|
61 | 21 | ->all(); |
|
62 | } |
||
63 | |||
64 | 20 | private function prepareInsertRelations($model, $attribute, $newFiles) |
|
65 | { |
||
66 | 20 | $ownerId = $model->getPrimaryKey(); |
|
67 | 20 | $relation = $model->fileRelation($attribute); |
|
68 | 20 | $uploadedFiles = $model->fileState($attribute); |
|
69 | 20 | $handlerExtraFields = $model->fileOption($attribute, 'extraFields'); |
|
70 | |||
71 | 20 | $files = []; |
|
72 | 20 | $rows = []; |
|
73 | 20 | $extraFields = []; |
|
74 | 20 | foreach ($uploadedFiles as $fileId) { |
|
75 | 20 | if (isset($newFiles[$fileId])) { |
|
76 | 20 | $file = $newFiles[$fileId]; |
|
77 | 20 | $row = [$ownerId, $fileId]; |
|
78 | 20 | if ($handlerExtraFields) { |
|
79 | $fields = [ |
||
80 | 20 | key($relation->via->link) => $ownerId, |
|
81 | 20 | current($relation->link) => $fileId, |
|
82 | 20 | ]; |
|
83 | 20 | $extraFields = $handlerExtraFields($file, $fields); |
|
84 | 20 | $row = array_merge($row, array_values($extraFields)); |
|
85 | 20 | } |
|
86 | 20 | $rows[] = $row; |
|
87 | 20 | $files[$file->getPrimaryKey()] = $file; |
|
88 | 20 | } |
|
89 | 20 | } |
|
90 | |||
91 | 20 | $columns = [key($relation->via->link), current($relation->link)]; |
|
92 | 20 | $columns = array_merge($columns, array_keys($extraFields)); |
|
93 | |||
94 | 20 | return ['rows' => $rows, 'files' => $files, 'columns' => $columns]; |
|
95 | } |
||
96 | |||
97 | 20 | private function prepareUpdateRelations($model, $attribute, $newFiles, $currentRelations) |
|
98 | { |
||
99 | 20 | $relation = $model->fileRelation($attribute); |
|
100 | 20 | $handlerExtraFields = $model->fileOption($attribute, 'extraFields'); |
|
101 | |||
102 | 20 | $files = []; |
|
103 | 20 | $rows = []; |
|
104 | 20 | foreach ($currentRelations as $fields) { |
|
105 | 4 | if (isset($newFiles[$fields[current($relation->link)]])) { |
|
106 | 3 | $file = $newFiles[$fields[current($relation->link)]]; |
|
107 | 3 | if ($handlerExtraFields) { |
|
108 | 3 | $extraFields = $handlerExtraFields($file, $fields); |
|
109 | 3 | $fieldChanged = (bool)count(array_diff_assoc($extraFields, $fields)); |
|
110 | 3 | if ($fieldChanged) { |
|
111 | 2 | $rows[$file->getPrimaryKey()] = $extraFields; |
|
112 | 2 | } |
|
113 | 3 | } |
|
114 | 3 | $files[$file->getPrimaryKey()] = $file; |
|
115 | 3 | } |
|
116 | 20 | } |
|
117 | 20 | return ['rows' => $rows, 'files' => $files]; |
|
118 | } |
||
119 | |||
120 | 20 | private function insertRelations($model, $attribute, $rows, $columns) |
|
121 | { |
||
122 | 20 | $relation = $model->fileRelation($attribute); |
|
123 | 20 | Yii::$app->getDb()->createCommand() |
|
124 | 20 | ->batchInsert($relation->via->from[0], $columns, $rows) |
|
125 | 20 | ->execute(); |
|
126 | 20 | } |
|
127 | |||
128 | 2 | private function updateRelations($model, $attribute, $rows) |
|
129 | { |
||
130 | 2 | $relation = $model->fileRelation($attribute); |
|
131 | 2 | $ownerId = $model->getPrimaryKey(); |
|
132 | 2 | $db = Yii::$app->getDb()->createCommand(); |
|
133 | |||
134 | 2 | foreach ($rows as $fileId => $row) { |
|
135 | 2 | $db->update($relation->via->from[0], $row, [ |
|
136 | 2 | key($relation->via->link) => $ownerId, |
|
137 | 2 | current($relation->link) => $fileId |
|
138 | 2 | ])->execute(); |
|
139 | 2 | } |
|
140 | 2 | } |
|
141 | |||
142 | 20 | private function updateFiles($model, $attribute, $files) |
|
143 | { |
||
144 | 20 | $handlerUpdateFile = $model->fileOption($attribute, 'updateFile'); |
|
145 | 20 | $relation = $model->fileOption($attribute, 'relation'); |
|
146 | 20 | $isMultiple = $model->fileOption($attribute, 'multiple'); |
|
147 | |||
148 | 20 | $relationValue = []; |
|
149 | 20 | foreach ($files as $file) { |
|
150 | 20 | $relationValue[] = $file; |
|
151 | 20 | if ($handlerUpdateFile) { |
|
152 | 20 | $fileUpd = $handlerUpdateFile($file); |
|
153 | 20 | $dirtyAttributes = $fileUpd->getDirtyAttributes(); |
|
154 | 20 | if (count($dirtyAttributes)) { |
|
155 | 1 | $fileUpd->updateAttributes($dirtyAttributes); |
|
156 | 1 | } |
|
157 | 20 | } |
|
158 | 20 | } |
|
159 | |||
160 | 20 | if (!$isMultiple) { |
|
161 | 14 | $relationValue = array_shift($relationValue); |
|
162 | 14 | } |
|
163 | 20 | $model->populateRelation($relation, $relationValue); |
|
164 | 20 | } |
|
165 | |||
166 | 21 | public function delete($model, $attribute, $files) |
|
167 | { |
||
168 | 21 | $relation = $model->fileRelation($attribute); |
|
169 | 21 | $storage = $model->fileStorage($attribute); |
|
170 | 21 | $presets = array_keys($model->fileOption($attribute, 'preset', [])); |
|
171 | 21 | $handlerTemplatePath = $model->fileOption($attribute, 'templatePath'); |
|
172 | |||
173 | 21 | $db = Yii::$app->getDb()->createCommand(); |
|
174 | 21 | foreach ($files as $file) { |
|
175 | 5 | foreach ($presets as $preset) { |
|
176 | 4 | $thumbPath = $model->thumbPath($attribute, $preset, $file); |
|
177 | 4 | $filePath = str_replace($storage->path, '', $thumbPath); |
|
178 | 4 | if ($storage->has($filePath)) { |
|
179 | 4 | $storage->delete($filePath); |
|
180 | 4 | } |
|
181 | 4 | } |
|
182 | |||
183 | 4 | if ($file->delete()) { |
|
184 | 4 | $db->delete($relation->via->from[0], [ |
|
185 | 4 | current($relation->link) => $file->getPrimaryKey() |
|
186 | 4 | ])->execute(); |
|
187 | 4 | $filePath = $handlerTemplatePath($file); |
|
188 | 4 | if ($storage->has($filePath)) { |
|
189 | 4 | $storage->delete($filePath); |
|
190 | 4 | } |
|
191 | 4 | } |
|
192 | 21 | } |
|
193 | 21 | } |
|
194 | |||
195 | 20 | public function relations($model, $attribute) |
|
196 | { |
||
197 | 20 | $relation = $model->fileRelation($attribute); |
|
198 | |||
199 | 20 | return (new Query()) |
|
200 | 20 | ->from($relation->via->from[0]) |
|
201 | 20 | ->andWhere([key($relation->via->link) => $model->getPrimaryKey()]) |
|
202 | 20 | ->indexBy(current($relation->link)) |
|
0 ignored issues
–
show
|
|||
203 | 20 | ->all(); |
|
204 | } |
||
205 | |||
206 | 22 | public function files($model, $attribute) |
|
207 | { |
||
208 | 22 | $relation = $model->fileRelation($attribute); |
|
209 | 22 | $relationName = $model->fileOption($attribute, 'relation'); |
|
210 | |||
211 | 22 | $query = call_user_func([$model, 'get' . $relationName]); |
|
212 | 22 | return $query->indexBy(key($relation->link))->all(); |
|
213 | } |
||
214 | |||
215 | 12 | public function file($model, $attribute) |
|
216 | { |
||
217 | 12 | $relation = $model->fileOption($attribute, 'relation'); |
|
218 | 12 | return $model->$relation; |
|
219 | } |
||
220 | } |
||
221 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: