1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
Chunk.php
См. документацию.
1<?php
2
3namespace Bitrix\UI\FileUploader;
4
5use Bitrix\Main\Error;
6use Bitrix\Main\File;
7use Bitrix\Main\HttpRequest;
8use Bitrix\Main\IO;
9use Bitrix\Main\Result;
10use Bitrix\Main\Text\Encoding;
11
12class Chunk
13{
14 protected int $size = 0;
15 protected ?int $fileSize = null;
16 protected ?int $startRange = null;
17 protected ?int $endRange = null;
18 protected string $type = '';
19 protected string $name = '';
20 protected int $width = 0;
21 protected int $height = 0;
22
23 protected IO\File $file;
24
25 protected function __construct(IO\File $file)
26 {
27 $this->setFile($file);
28 }
29
31 {
32 $result = new Result();
33
34 $fileMimeType = (string)$request->getHeader('Content-Type');
35 if (!preg_match('~\w+/[-+.\w]+~', $fileMimeType))
36 {
38 }
39
40 $contentLength = $request->getHeader('Content-Length');
41 if ($contentLength === null)
42 {
44 }
45
46 $contentLength = (int)$contentLength;
47 $filename = static::normalizeFilename((string)$request->getHeader('X-Upload-Content-Name'));
48 if (empty($filename))
49 {
51 }
52
53 if (!static::isValidFilename($filename))
54 {
56 }
57
58 $contentRangeResult = static::getContentRange($request);
59 if (!$contentRangeResult->isSuccess())
60 {
61 return $result->addErrors($contentRangeResult->getErrors());
62 }
63
64 $file = static::getFileFromHttpInput();
65 $contentRange = $contentRangeResult->getData();
66 $rangeChunkSize = empty($contentRange) ? 0 : ($contentRange['endRange'] - $contentRange['startRange'] + 1);
67
68 if ($rangeChunkSize && $contentLength !== $rangeChunkSize)
69 {
70 return $result->addError(new UploaderError(
72 [
73 'rangeChunkSize' => $rangeChunkSize,
74 'contentLength' => $contentLength,
75 ]
76 ));
77 }
78
79 $chunk = new Chunk($file);
80 if ($chunk->getSize() !== $contentLength)
81 {
82 return $result->addError(new UploaderError(
84 [
85 'chunkSize' => $chunk->getSize(),
86 'contentLength' => $contentLength,
87 ]
88 ));
89 }
90
91 $chunk->setName($filename);
92 $chunk->setType($fileMimeType);
93
94 if (!empty($contentRange))
95 {
96 $chunk->setStartRange($contentRange['startRange']);
97 $chunk->setEndRange($contentRange['endRange']);
98 $chunk->setFileSize($contentRange['fileSize']);
99 }
100
101 $result->setData(['chunk' => $chunk]);
102
103 return $result;
104 }
105
106 private static function getFileFromHttpInput(): IO\File
107 {
108 // This file will be automatically removed on shutdown
109 $tmpFilePath = TempFile::generateLocalTempFile();
110 $file = new IO\File($tmpFilePath);
111 $file->putContents(HttpRequest::getInput());
112
113 return $file;
114 }
115
116 private static function getContentRange(HttpRequest $request): Result
117 {
118 $contentRange = $request->getHeader('Content-Range');
119 if ($contentRange === null)
120 {
121 return new Result();
122 }
123
124 $result = new Result();
125 if (!preg_match('/(\d+)-(\d+)\/(\d+)$/', $contentRange, $match))
126 {
127 return $result->addError(new UploaderError(UploaderError::INVALID_CONTENT_RANGE));
128 }
129
130 [$startRange, $endRange, $fileSize] = [(int)$match[1], (int)$match[2], (int)$match[3]];
131
133 {
134 return $result->addError(new UploaderError(UploaderError::INVALID_CONTENT_RANGE));
135 }
136
137 if ($fileSize <= $endRange)
138 {
139 return $result->addError(new UploaderError(UploaderError::INVALID_CONTENT_RANGE));
140 }
141
142 $result->setData([
143 'startRange' => $startRange,
144 'endRange' => $endRange,
145 'fileSize' => $fileSize,
146 ]);
147
148 return $result;
149 }
150
151 private static function normalizeFilename(string $filename): string
152 {
153 $filename = urldecode($filename);
154 $filename = Encoding::convertEncodingToCurrent($filename);
155
156 return \getFileName($filename);
157 }
158
159 private static function isValidFilename(string $filename): bool
160 {
161 if (mb_strlen($filename) > 255)
162 {
163 return false;
164 }
165
166 if (mb_strpos($filename, '\0') !== false)
167 {
168 return false;
169 }
170
171 return true;
172 }
173
174 public function getFile(): IO\File
175 {
176 return $this->file;
177 }
178
182 public function setFile(IO\File $file): void
183 {
184 $this->file = $file;
185 $this->size = $file->getSize();
186 }
187
188 public function getSize(): int
189 {
190 return $this->size;
191 }
192
193 public function getFileSize(): int
194 {
195 return $this->fileSize ?? $this->size;
196 }
197
198 protected function setFileSize(int $fileSize): void
199 {
200 $this->fileSize = $fileSize;
201 }
202
203 public function getType(): string
204 {
205 return $this->type;
206 }
207
208 public function setType(string $type): void
209 {
210 $this->type = $type;
211 }
212
213 public function getName(): string
214 {
215 return $this->name;
216 }
217
218 public function setName(string $name): void
219 {
220 $this->name = $name;
221 }
222
223 public function getWidth(): int
224 {
225 return $this->width;
226 }
227
228 public function setWidth(int $width): void
229 {
230 $this->width = $width;
231 }
232
233 public function getHeight(): int
234 {
235 return $this->height;
236 }
237
238 public function setHeight(int $height): void
239 {
240 $this->height = $height;
241 }
242
243 public function getStartRange(): ?int
244 {
245 return $this->startRange;
246 }
247
248 protected function setStartRange(int $startRange): void
249 {
250 $this->startRange = $startRange;
251 }
252
253 public function getEndRange(): ?int
254 {
255 return $this->endRange;
256 }
257
258 protected function setEndRange(int $endRange): void
259 {
260 $this->endRange = $endRange;
261 }
262
263 public function isFirst(): bool
264 {
265 return $this->startRange === null || $this->startRange === 0;
266 }
267
268 public function isLast(): bool
269 {
270 return $this->endRange === null || ($this->endRange + 1) === $this->fileSize;
271 }
272
273 public function isOnlyOne(): bool
274 {
275 return (
276 $this->startRange === null
277 || ($this->startRange === 0 && ($this->endRange - $this->startRange + 1) === $this->fileSize)
278 );
279 }
280
282 {
283 $result = new Result();
284
285 if (in_array(mb_strtolower($this->getName()), $config->getIgnoredFileNames()))
286 {
288 }
289
290 if ($config->getMaxFileSize() !== null && $this->getFileSize() > $config->getMaxFileSize())
291 {
292 return $result->addError(
293 new UploaderError(
295 [
296 'maxFileSize' => \CFile::formatSize($config->getMaxFileSize()),
297 'maxFileSizeInBytes' => $config->getMaxFileSize(),
298 ]
299 )
300 );
301 }
302
303 if ($this->getFileSize() < $config->getMinFileSize())
304 {
305 return $result->addError(
306 new UploaderError(
308 [
309 'minFileSize' => \CFile::formatSize($config->getMinFileSize()),
310 'minFileSizeInBytes' => $config->getMinFileSize(),
311 ]
312 )
313 );
314 }
315
316 if (!$this->validateFileType($config->getAcceptedFileTypes()))
317 {
319 }
320
321 $width = 0;
322 $height = 0;
323 if (\CFile::isImage($this->getName(), $this->getType()))
324 {
325 $image = new File\Image($this->getFile()->getPhysicalPath());
326 $imageInfo = $image->getInfo(false);
327 if (!$imageInfo)
328 {
329 if ($config->getIgnoreUnknownImageTypes())
330 {
331 $result->setData(['width' => $width, 'height' => $height]);
332
333 return $result;
334 }
335 else
336 {
338 }
339 }
340
341 $width = $imageInfo->getWidth();
342 $height = $imageInfo->getHeight();
343 if ($imageInfo->getFormat() === File\Image::FORMAT_JPEG)
344 {
345 $exifData = $image->getExifData();
346 if (isset($exifData['Orientation']) && $exifData['Orientation'] >= 5 && $exifData['Orientation'] <= 8)
347 {
349 }
350 }
351
352 if (!$config->shouldTreatOversizeImageAsFile())
353 {
354 $imageData = new FileData($this->getName(), $this->getType(), $this->getSize());
355 $imageData->setWidth($width);
356 $imageData->setHeight($height);
357
358 $validationResult = $config->validateImage($imageData);
359 if (!$validationResult->isSuccess())
360 {
361 return $result->addErrors($validationResult->getErrors());
362 }
363 }
364 }
365
366 $result->setData(['width' => $width, 'height' => $height]);
367
368 return $result;
369 }
370
371 private function validateFileType(array $fileTypes): bool
372 {
373 if (count($fileTypes) === 0)
374 {
375 return true;
376 }
377
378 $mimeType = $this->getType();
379 $baseMimeType = preg_replace('/\/.*$/', '', $mimeType);
380
381 foreach ($fileTypes as $type)
382 {
383 if (!is_string($type) || mb_strlen($type) === 0)
384 {
385 continue;
386 }
387
388 $type = mb_strtolower(trim($type));
389 if ($type[0] === '.') // extension case
390 {
391 $filename = mb_strtolower($this->getName());
392 $offset = mb_strlen($filename) - mb_strlen($type);
393 if (mb_strpos($filename, $type, $offset) !== false)
394 {
395 return true;
396 }
397 }
398 elseif (preg_match('/\/\*$/', $type)) // image/* mime type case
399 {
400 if ($baseMimeType === preg_replace('/\/.*$/', '', $type))
401 {
402 return true;
403 }
404 }
405 elseif ($mimeType === $type)
406 {
407 return true;
408 }
409 }
410
411 return false;
412 }
413}
$type
Определения options.php:106
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
putContents($data, $flags=self::REWRITE)
Определения file.php:71
getFileSize()
Определения Chunk.php:193
getEndRange()
Определения Chunk.php:253
static createFromRequest(HttpRequest $request)
Определения Chunk.php:30
__construct(IO\File $file)
Определения Chunk.php:25
setStartRange(int $startRange)
Определения Chunk.php:248
getStartRange()
Определения Chunk.php:243
int $fileSize
Определения Chunk.php:15
setName(string $name)
Определения Chunk.php:218
setWidth(int $width)
Определения Chunk.php:228
int $width
Определения Chunk.php:20
int $size
Определения Chunk.php:14
int $startRange
Определения Chunk.php:16
string $name
Определения Chunk.php:19
validate(Configuration $config)
Определения Chunk.php:281
isOnlyOne()
Определения Chunk.php:273
int $height
Определения Chunk.php:21
setHeight(int $height)
Определения Chunk.php:238
string $type
Определения Chunk.php:18
IO File $file
Определения Chunk.php:23
getHeight()
Определения Chunk.php:233
setFileSize(int $fileSize)
Определения Chunk.php:198
setFile(IO\File $file)
Определения Chunk.php:182
setEndRange(int $endRange)
Определения Chunk.php:258
int $endRange
Определения Chunk.php:17
setType(string $type)
Определения Chunk.php:208
static generateLocalTempFile()
Определения TempFile.php:423
$filename
Определения file_edit.php:47
hidden PROPERTY[<?=$propertyIndex?>][CODE]<?=htmlspecialcharsEx( $propertyCode)?> height
Определения file_new.php:759
bx popup label bx width30 PAGE_NEW_MENU_NAME text width
Определения file_new.php:677
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
Определения Image.php:9
Определения directory.php:3
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$config
Определения quickway.php:69
font size
Определения invoice.php:442
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936