Completed
Pull Request — master (#108)
by Vasile
01:30
created

UploadAction::run()   D

Complexity

Conditions 9
Paths 11

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10.1197

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 36
ccs 19
cts 25
cp 0.76
rs 4.909
cc 9
eloc 24
nc 11
nop 0
crap 10.1197
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
 * UploadAction 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\UploadAction',
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\UploadAction',
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 UploadAction 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 boolean If `true` unique filename will be generated automatically.
86
     */
87
    public $unique = true;
88
89
    /**
90
     * In case of `true` this option will be ignored if `$unique` will be also enabled.
91
     *
92
     * @var bool Whether to translit the uploaded file name or not.
93
     */
94
    public $translit = false;
95
96
    /**
97
     * @var array Model validator options.
98
     */
99
    public $validatorOptions = [];
100
101
    /**
102
     * @var string Model validator name.
103
     */
104
    private $_validator = 'image';
105
106
    /**
107
     * @inheritdoc
108
     */
109 15
    public function init()
110
    {
111 15
        if ($this->url === null) {
112 3
            throw new InvalidConfigException('The "url" attribute must be set.');
113
        } else {
114 12
            $this->url = rtrim($this->url, '/') . '/';
115
        }
116 12
        if ($this->path === null) {
117 3
            throw new InvalidConfigException('The "path" attribute must be set.');
118
        } else {
119 9
            $this->path = rtrim(Yii::getAlias($this->path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
120
121 9
            if (!FileHelper::createDirectory($this->path)) {
122
                throw new InvalidCallException("Directory specified in 'path' attribute doesn't exist or cannot be created.");
123
            }
124
        }
125 9
        if ($this->uploadOnlyImage !== true) {
126 3
            $this->_validator = 'file';
127 1
        }
128
129 9
        Widget::registerTranslations();
130 9
    }
131
132
    /**
133
     * @inheritdoc
134
     */
135 9
    public function run()
136
    {
137 9
        if (Yii::$app->request->isPost) {
138 6
            $file = UploadedFile::getInstanceByName($this->uploadParam);
139 6
            $model = new DynamicModel(['file' => $file]);
140 6
            $model->addRule('file', $this->_validator, $this->validatorOptions)->validate();
141
142 6
            if ($model->hasErrors()) {
143
                $result = [
144 3
                    'error' => $model->getFirstError('file'),
145 1
                ];
146 1
            } else {
147 3
                if ($this->unique === true && $model->file->extension) {
148 3
                    $model->file->name = uniqid() . '.' . $model->file->extension;
149 1
                } elseif ($this->translit === true && $model->file->extension) {
150
                    $model->file->name = Inflector::slug($model->file->baseName) . '.' . $model->file->extension;
151
                }
152 3
                if ($model->file->saveAs($this->path . $model->file->name)) {
153
                    $result = ['filelink' => $this->url . $model->file->name];
154
155
                    if ($this->uploadOnlyImage !== true) {
156
                        $result['filename'] = $model->file->name;
157
                    }
158 1
                } else {
159
                    $result = [
160 5
                        'error' => Yii::t('vova07/imperavi', 'ERROR_CAN_NOT_UPLOAD_FILE'),
161 3
                    ];
162
                }
163
            }
164 6
            Yii::$app->response->format = Response::FORMAT_JSON;
165
166 6
            return $result;
167
        } else {
168 3
            throw new BadRequestHttpException('Only POST is allowed');
169
        }
170
    }
171
}
172