1 | <?php |
||||
2 | /** |
||||
3 | * Created by PhpStorm. |
||||
4 | * User: floor12 |
||||
5 | * Date: 01.01.2018 |
||||
6 | * Time: 12:56 |
||||
7 | */ |
||||
8 | |||||
9 | namespace floor12\files\logic; |
||||
10 | |||||
11 | use floor12\files\components\SimpleImage; |
||||
12 | use floor12\files\models\File; |
||||
13 | use floor12\files\models\FileType; |
||||
14 | use Yii; |
||||
15 | use yii\base\ErrorException; |
||||
16 | use yii\web\BadRequestHttpException; |
||||
17 | use yii\web\IdentityInterface; |
||||
18 | use yii\web\UploadedFile; |
||||
19 | |||||
20 | /** |
||||
21 | * Class FileCreateFromInstance |
||||
22 | * @package floor12\files\logic |
||||
23 | */ |
||||
24 | class FileCreateFromInstance |
||||
25 | { |
||||
26 | private $_model; |
||||
27 | private $_owner; |
||||
28 | private $_attribute; |
||||
29 | private $_instance; |
||||
30 | private $_fullPath; |
||||
31 | private $_onlyUploaded; |
||||
32 | |||||
33 | public function __construct(UploadedFile $file, array $data, IdentityInterface $identity = null, $onlyUploaded = true) |
||||
34 | { |
||||
35 | |||||
36 | $this->_onlyUploaded = $onlyUploaded; |
||||
37 | |||||
38 | if (!isset($data['attribute']) || !$data['attribute'] || !isset($data['modelClass']) || !$data['modelClass']) |
||||
39 | throw new BadRequestHttpException("Attribute or class name not set."); |
||||
40 | |||||
41 | // Загружаем полученные данные |
||||
42 | $this->_instance = $file; |
||||
43 | $this->_attribute = $data['attribute']; |
||||
44 | |||||
45 | if (!file_exists($this->_instance->tempName)) |
||||
46 | throw new ErrorException("Tmp file not found on disk."); |
||||
47 | |||||
48 | // Инициализируем класс владельца файла для валидаций и ставим сценарий |
||||
49 | $this->_owner = new $data['modelClass']; |
||||
50 | |||||
51 | if (isset($data['scenario'])) |
||||
52 | $this->_owner->setScenario($data['scenario']); |
||||
53 | |||||
54 | |||||
55 | if (isset($this->_owner->behaviors['files']->attributes[$this->_attribute]['validator'])) { |
||||
56 | foreach ($this->_owner->behaviors['files']->attributes[$this->_attribute]['validator'] as $validator) { |
||||
57 | if ($validator->maxFiles && (int)$data['count'] > $validator->maxFiles) { |
||||
58 | throw new BadRequestHttpException('The maximum number of files has been exceeded: ' . $validator->maxFiles); |
||||
59 | } |
||||
60 | |||||
61 | if (!$validator->validate($this->_instance, $error)) |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||||
62 | throw new BadRequestHttpException($error); |
||||
63 | } |
||||
64 | |||||
65 | } |
||||
66 | |||||
67 | // Создаем модель нового файла и заполняем первоначальными данными |
||||
68 | $this->_model = new File(); |
||||
69 | $this->_model->created = time(); |
||||
70 | $this->_model->field = $this->_attribute; |
||||
71 | $this->_model->class = $data['modelClass']; |
||||
72 | |||||
73 | $this->_model->filename = new PathGenerator(Yii::$app->getModule('files')->storageFullPath) . '.' . $this->_instance->extension; |
||||
74 | $this->_model->title = $this->_instance->name; |
||||
75 | $this->_model->content_type = \yii\helpers\FileHelper::getMimeType($this->_instance->tempName); |
||||
76 | $this->_model->size = $this->_instance->size; |
||||
77 | $this->_model->type = $this->detectType(); |
||||
0 ignored issues
–
show
The property
$type was declared of type integer , but $this->detectType() is of type string . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||||
78 | if ($identity) |
||||
79 | $this->_model->user_id = $identity->getId(); |
||||
0 ignored issues
–
show
It seems like
$identity->getId() can also be of type string . However, the property $user_id is declared as type integer . 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 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;
}
![]() |
|||||
80 | if ($this->_model->type == FileType::VIDEO) |
||||
81 | $this->_model->video_status = 0; |
||||
82 | |||||
83 | //Генерируем полный новый адрес сохранения файла |
||||
84 | $this->_fullPath = Yii::$app->getModule('files')->storageFullPath . DIRECTORY_SEPARATOR . $this->_model->filename; |
||||
0 ignored issues
–
show
Are you sure
Yii::app->getModule('files')->storageFullPath of type mixed|null|object can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
85 | } |
||||
86 | |||||
87 | /** |
||||
88 | * @return string |
||||
89 | */ |
||||
90 | public function detectType() |
||||
91 | { |
||||
92 | $contentTypeArray = explode('/', $this->_model->content_type); |
||||
93 | if ($contentTypeArray[0] == 'image') |
||||
94 | return FileType::IMAGE; |
||||
95 | if ($contentTypeArray[0] == 'video') |
||||
96 | return FileType::VIDEO; |
||||
97 | return FileType::FILE; |
||||
98 | } |
||||
99 | |||||
100 | /** |
||||
101 | * @return File |
||||
102 | */ |
||||
103 | |||||
104 | public function execute() |
||||
105 | { |
||||
106 | $path = Yii::$app->getModule('files')->storageFullPath . $this->_model->filename; |
||||
0 ignored issues
–
show
Are you sure
Yii::app->getModule('files')->storageFullPath of type mixed|null|object can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
107 | |||||
108 | if ($this->_model->save()) { |
||||
109 | if (!$this->_onlyUploaded) |
||||
110 | copy($this->_instance->tempName, $this->_fullPath); |
||||
111 | else |
||||
112 | $this->_instance->saveAs($this->_fullPath, false); |
||||
113 | } |
||||
114 | |||||
115 | if ($this->_model->type == FileType::IMAGE) { |
||||
116 | $this->rotateAfterUpload(); |
||||
117 | $this->resizeAfterUpload(); |
||||
118 | } |
||||
119 | |||||
120 | return $this->_model; |
||||
121 | } |
||||
122 | |||||
123 | |||||
124 | protected function rotateAfterUpload() |
||||
125 | { |
||||
126 | $exif = ''; |
||||
0 ignored issues
–
show
|
|||||
127 | @$exif = exif_read_data($this->_fullPath); |
||||
128 | if (isset($exif['Orientation'])) { |
||||
129 | $ort = $exif['Orientation']; |
||||
130 | $rotatingImage = new SimpleImage(); |
||||
131 | $rotatingImage->load($this->_fullPath); |
||||
132 | switch ($ort) { |
||||
133 | case 3: // 180 rotate left |
||||
134 | $rotatingImage->rotateDegrees(180); |
||||
135 | $rotatingImage->save($this->_fullPath); |
||||
136 | break; |
||||
137 | case 6: // 90 rotate right |
||||
138 | $rotatingImage->rotateDegrees(270); |
||||
139 | $rotatingImage->save($this->_fullPath); |
||||
140 | break; |
||||
141 | case 8: // 90 rotate left |
||||
142 | $rotatingImage->rotateDegrees(90); |
||||
143 | $rotatingImage->save($this->_fullPath); |
||||
144 | } |
||||
145 | |||||
146 | } |
||||
147 | } |
||||
148 | |||||
149 | protected function resizeAfterUpload() |
||||
150 | { |
||||
151 | $maxWidth = $this->_owner->behaviors['files']->attributes[$this->_attribute]['maxWidth'] ?? 0; |
||||
152 | $maxHeight = $this->_owner->behaviors['files']->attributes[$this->_attribute]['maxHeight'] ?? 0; |
||||
153 | |||||
154 | if ($maxWidth && $maxHeight) { |
||||
155 | $resizer = new FileResize($this->_model, $maxWidth, $maxHeight); |
||||
156 | $resizer->execute(); |
||||
157 | } |
||||
158 | |||||
159 | } |
||||
160 | } |
||||
161 |