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: