Completed
Push — master ( 6d9f7a...ddd29f )
by Igor
03:01
created

UploadAction::run()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 31
ccs 20
cts 20
cp 1
rs 8.439
cc 6
eloc 17
nc 7
nop 0
crap 6
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\actions;
10
11
use Yii;
12
use yii\base\Action;
13
use yii\base\DynamicModel;
14
use yii\base\InvalidParamException;
15
use yii\web\UploadedFile;
16
use yii\helpers\ArrayHelper;
17
18
class UploadAction extends Action
19
{
20
    /**
21
     * @var string $modelClass Class name of the model
22
     */
23
    public $modelClass;
24
    /**
25
     * @var string $modelObject Model
26
     */
27
    public $modelObject;
28
    /**
29
     * @var string $attribute Attribute name of the model
30
     */
31
    public $attribute;
32
    /**
33
     * @var string $inputName The name of the file input field
34
     */
35
    public $inputName;
36
    /**
37
     * @var string $resultFieldId The name of the field that contains the id of the file in the response
38
     */
39
    public $resultFieldId = 'id';
40
    /**
41
     * @var string $resultFieldPath The name of the field that contains the path of the file in the response
42
     */
43
    public $resultFieldPath = 'path';
44
    /**
45
     * @var ActiveRecord $model
46
     */
47
    private $model;
48
49 28
    public function init()
50
    {
51 28
        if ($this->modelClass === null && $this->modelObject === null) {
52 1
            throw new InvalidParamException(
53 1
                get_class($this) . '::$modelClass or ' .get_class($this) . '::$modelObject must be set'
54 1
            );
55
        }
56
57 27
        $this->model = $this->modelClass ? new $this->modelClass : $this->modelObject;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->modelClass ? new ...() : $this->modelObject can also be of type string. However, the property $model is declared as type object<rkit\filemanager\actions\ActiveRecord>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
58 27
    }
59
60 27
    public function run()
61
    {
62 27
        $file = UploadedFile::getInstanceByName($this->inputName);
63
64 27
        if (!$file) {
65 1
            return $this->response(
66 1
                ['error' => Yii::t('filemanager-yii2', 'An error occured, try again later…')]
67 1
            );
68
        }
69
70 26
        $rules = $this->model->fileRules($this->attribute, true);
71 26
        $type = $this->model->fileOption($this->attribute, 'type', 'image');
72
73 26
        $model = new DynamicModel(compact('file'));
74
75 26
        $maxFiles = ArrayHelper::getValue($rules, 'maxFiles');
76 26
        if ($maxFiles !== null && $maxFiles > 1) {
77 3
            $model->file = [$model->file];
78 3
        }
79
80 26
        $model->addRule('file', $type, $rules)->validate();
81 26
        if ($model->hasErrors()) {
82 1
            return $this->response(['error' => $model->getFirstError('file')]);
83
        }
84
85 25
        if (is_array($model->file)) {
86 3
            $model->file = $model->file[0];
87 3
        }
88
89 25
        return $this->save($model->file);
90
    }
91
92
    /**
93
     * Upload
94
     *
95
     * @param UploadedFile $file
96
     * @return string JSON
97
     * @SuppressWarnings(PHPMD.ElseExpression)
98
     */
99 25
    private function save($file)
100
    {
101 25
        $file = $this->model->createFile($this->attribute, $file->tempName, $file->name);
102 25
        if ($file) {
103 25
            $presetAfterUpload = $this->model->filePresetAfterUpload($this->attribute);
104 25
            if (count($presetAfterUpload)) {
105 25
                $this->applyPreset($presetAfterUpload, $file);
106 25
            }
107 25
            $template = $this->model->fileOption($this->attribute, 'template');
108 25
            if ($template) {
109 1
                return $this->response(
110 1
                    $this->controller->renderFile(Yii::getAlias($template), [
0 ignored issues
show
Bug introduced by
It seems like \Yii::getAlias($template) targeting yii\BaseYii::getAlias() can also be of type boolean; however, yii\base\Controller::renderFile() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
111 1
                        'file' => $file,
112 1
                        'model' => $this->model,
113 1
                        'attribute' => $this->attribute
114 1
                    ])
115 1
                );
116
            }
117 24
            return $this->response([
118 24
                $this->resultFieldId => $file->getPrimaryKey(),
119 24
                $this->resultFieldPath => $this->model->fileUrl($this->attribute, $file),
120 24
            ]);
121
        }
122
        return $this->response(['error' => Yii::t('filemanager-yii2', 'Error saving file')]); // @codeCoverageIgnore
123
    }
124
125
    /**
126
     * Apply preset for file
127
     *
128
     * @param array $presetAfterUpload
129
     * @param ActiveRecord $file The file model
130
     * @return void
131
     */
132 25
    private function applyPreset($presetAfterUpload, $file)
133
    {
134 25
        foreach ($presetAfterUpload as $preset) {
135 25
            $this->model->thumbUrl($this->attribute, $preset, $file);
136 25
        }
137 25
    }
138
139
    /**
140
     * JSON Response
141
     *
142
     * @param mixed $data
143
     * @return string JSON Only for yii\web\Application, for console app returns `mixed`
144
     */
145 27
    private function response($data)
146
    {
147
        // @codeCoverageIgnoreStart
148
        if (!Yii::$app instanceof \yii\console\Application) {
149
            \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
150
        }
151
        // @codeCoverageIgnoreEnd
152 27
        return $data;
153
    }
154
}
155