UploadFileAction   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 81.39%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 10
dl 0
loc 123
ccs 35
cts 43
cp 0.8139
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 22 5
B run() 0 44 11
1
<?php
2
/**
3
 * This file is part of yii2-imperavi-widget.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @see https://github.com/vova07/yii2-imperavi-widget
9
 */
10
11
namespace vova07\imperavi\actions;
12
13
use vova07\imperavi\Widget;
14
use Yii;
15
use yii\base\Action;
16
use yii\base\DynamicModel;
17
use yii\base\InvalidCallException;
18
use yii\base\InvalidConfigException;
19
use yii\helpers\FileHelper;
20
use yii\helpers\Inflector;
21
use yii\web\BadRequestHttpException;
22
use yii\web\Response;
23
use yii\web\UploadedFile;
24
25
/**
26
 * UploadFileAction for images and files.
27
 *
28
 * Usage:
29
 *
30
 * ```php
31
 * public function actions()
32
 * {
33
 *     return [
34
 *         'upload-image' => [
35
 *             'class' => 'vova07\imperavi\actions\UploadFileAction',
36
 *             'url' => 'http://my-site.com/statics/',
37
 *             'path' => '/var/www/my-site.com/web/statics',
38
 *             'unique' => true,
39
 *             'validatorOptions' => [
40
 *                 'maxWidth' => 1000,
41
 *                 'maxHeight' => 1000
42
 *             ]
43
 *         ],
44
 *         'file-upload' => [
45
 *             'class' => 'vova07\imperavi\actions\UploadFileAction',
46
 *             'url' => 'http://my-site.com/statics/',
47
 *             'path' => '/var/www/my-site.com/web/statics',
48
 *             'uploadOnlyImage' => false,
49
 *             'translit' => true,
50
 *             'validatorOptions' => [
51
 *                 'maxSize' => 40000
52
 *             ]
53
 *         ]
54
 *     ];
55
 * }
56
 * ```
57
 *
58
 * @author Vasile Crudu <[email protected]>
59
 *
60
 * @link https://github.com/vova07/yii2-imperavi-widget
61
 */
62
class UploadFileAction extends Action
63
{
64
    /**
65
     * @var string Path to directory where files will be uploaded.
66
     */
67
    public $path;
68
69
    /**
70
     * @var string URL path to directory where files will be uploaded.
71
     */
72
    public $url;
73
74
    /**
75
     * @var string Validator name
76
     */
77
    public $uploadOnlyImage = true;
78
79
    /**
80
     * @var string Variable's name that Imperavi Redactor sent upon image/file upload.
81
     */
82
    public $uploadParam = 'file';
83
84
    /**
85
     * @var bool Whether to replace the file with new one in case they have same name or not.
86
     */
87
    public $replace = false;
88
89
    /**
90
     * @var boolean If `true` unique filename will be generated automatically.
91
     */
92
    public $unique = true;
93
94
    /**
95
     * In case of `true` this option will be ignored if `$unique` will be also enabled.
96
     *
97
     * @var bool Whether to translit the uploaded file name or not.
98
     */
99
    public $translit = false;
100
101
    /**
102
     * @var array Model validator options.
103
     */
104
    public $validatorOptions = [];
105
106
    /**
107
     * @var string Model validator name.
108
     */
109
    private $_validator = 'image';
110
111
    /**
112
     * @inheritdoc
113
     */
114 18
    public function init()
115
    {
116 18
        if ($this->url === null) {
117 3
            throw new InvalidConfigException('The "url" attribute must be set.');
118
        } else {
119 15
            $this->url = rtrim($this->url, '/') . '/';
120
        }
121 15
        if ($this->path === null) {
122 3
            throw new InvalidConfigException('The "path" attribute must be set.');
123
        } else {
124 12
            $this->path = rtrim(Yii::getAlias($this->path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
125
126 12
            if (!FileHelper::createDirectory($this->path)) {
127
                throw new InvalidCallException("Directory specified in 'path' attribute doesn't exist or cannot be created.");
128
            }
129
        }
130 12
        if ($this->uploadOnlyImage !== true) {
131 3
            $this->_validator = 'file';
132 1
        }
133
134 12
        Widget::registerTranslations();
135 12
    }
136
137
    /**
138
     * @inheritdoc
139
     */
140 12
    public function run()
141
    {
142 12
        if (Yii::$app->request->isPost) {
143 9
            Yii::$app->response->format = Response::FORMAT_JSON;
144
145 9
            $file = UploadedFile::getInstanceByName($this->uploadParam);
146 9
            $model = new DynamicModel(['file' => $file]);
147 9
            $model->addRule('file', $this->_validator, $this->validatorOptions)->validate();
148
149 9
            if ($model->hasErrors()) {
150
                $result = [
151 3
                    'error' => $model->getFirstError('file'),
152 1
                ];
153 1
            } else {
154 6
                if ($this->unique === true && $model->file->extension) {
155 3
                    $model->file->name = uniqid() . '.' . $model->file->extension;
156 4
                } elseif ($this->translit === true && $model->file->extension) {
157
                    $model->file->name = Inflector::slug($model->file->baseName) . '.' . $model->file->extension;
158
                }
159
160 8
                if (file_exists($this->path . $model->file->name) && $this->replace === false) {
161 4
                    return [
162 3
                        'error' => Yii::t('vova07/imperavi', 'ERROR_FILE_ALREADY_EXIST'),
163 1
                    ];
164
                }
165
166 3
                if ($model->file->saveAs($this->path . $model->file->name)) {
167
                    $result = ['id' => $model->file->name, 'filelink' => $this->url . $model->file->name];
168
169
                    if ($this->uploadOnlyImage !== true) {
170
                        $result['filename'] = $model->file->name;
171
                    }
172
                } else {
173
                    $result = [
174 3
                        'error' => Yii::t('vova07/imperavi', 'ERROR_CAN_NOT_UPLOAD_FILE'),
175 1
                    ];
176
                }
177
            }
178
179 6
            return $result;
180
        } else {
181 3
            throw new BadRequestHttpException('Only POST is allowed');
182
        }
183
    }
184
}
185