Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
uploader.php
1<?
7use \Bitrix\Main\UI\FileInputUtility;
8use \Bitrix\Main\Web\Json;
9use \Bitrix\Main\Context;
10use \Bitrix\Main\Loader;
11use \Bitrix\Main\Localization\Loc;
12use \Bitrix\Main;
13Loc::loadMessages(__FILE__);
15 "main",
16 array(
17 "bitrix\\main\\ui\\uploader\\storage" => "lib/ui/uploader/storage.php",
18 "bitrix\\main\\ui\\uploader\\cloudstorage" => "lib/ui/uploader/storage.php"
19 ));
20
21class Log implements \ArrayAccess
22{
23 /*
24 * @var \CBXVirtualFileFileSystem $file
25 */
26 protected $file = null;
27 var $data = array();
28
34 function __construct($path)
35 {
36 try
37 {
38 $this->file = \CBXVirtualIo::GetInstance()->GetFile($path);
39
40 if ($this->file->IsExists())
41 {
42 $data = unserialize($this->file->GetContents(), ["allowed_classes" => false]);
43 foreach($data as $key => $val)
44 {
45 if (array_key_exists($key , $this->data) && is_array($this->data[$key]) && is_array($val))
46 $this->data[$key] = array_merge($this->data[$key], $val);
47 else
48 $this->data[$key] = $val;
49 }
50 }
51 }
52 catch (\Throwable $e)
53 {
54 throw new Main\SystemException("Temporary file has wrong structure.", "BXU351.01");
55 }
56 }
57
64 public function setLog($key, $value)
65 {
66 if (array_key_exists($key, $this->data) && is_array($this->data) && is_array($value))
67 $this->data[$key] = array_merge($this->data[$key], $value);
68 else
69 $this->data[$key] = $value;
70 $this->save();
71
72 return $this;
73 }
74
79 public function getValue($key)
80 {
81 return $this->data[$key];
82 }
83
87 public function save()
88 {
89 try
90 {
91 $this->file->PutContents(serialize($this->data));
92 }
93 catch (\Throwable $e)
94 {
95 throw new Main\SystemException("Temporary file was not saved.", "BXU351.02");
96 }
97 }
98
102 public function getLog()
103 {
104 return $this->data;
105 }
106
110 public function unlink()
111 {
112 try
113 {
114 if ($this->file instanceof \CBXVirtualFileFileSystem && $this->file->IsExists())
115 $this->file->unlink();
116 }
117 catch (\Throwable $e)
118 {
119 throw new Main\SystemException("Temporary file was not deleted.", "BXU351.03");
120 }
121 }
122
127 public function offsetExists($offset): bool
128 {
129 return array_key_exists($offset, $this->data);
130 }
131
136 #[\ReturnTypeWillChange]
137 public function offsetGet($offset)
138 {
139 if (array_key_exists($offset, $this->data))
140 return $this->data[$offset];
141 return null;
142 }
143
148 public function offsetSet($offset, $value): void
149 {
150 $this->setLog($offset, $value);
151 }
152
156 public function offsetUnset($offset): void
157 {
158 if (array_key_exists($offset, $this->data))
159 {
160 unset($this->data[$offset]);
161 $this->save();
162 }
163 }
164}
165
167{
168 public $files = array();
169 public $controlId = "fileUploader";
170 public $params = array(
171 "allowUpload" => "A",
172 "allowUploadExt" => "",
173 "copies" => array(
174 "default" => array(
175 "width" => null,
176 "height" => null
177 ),
178 /* "copyName" => array(
179 "width" => 100,
180 "height" => 100
181 )*/
182 ),
183 "storage" => array(
184 "moduleId" => "main",
185 "cloud" => false
186 )
187 );
188/*
189 * @var string $script Url to uploading page for forming url to view
190 * @var string $path Path to temp directory
191 * @var string $CID Controller ID
192 * @var string $mode
193 * @var array $processTime Time limits
194 * @var HttpClient $http
195*/
196 public $script;
197 protected $path = "";
198 protected $CID = null;
199 protected int $version = 0;
200 protected $mode = "view";
201 protected $param = array();
202 protected $requestMethods = array(
203 "get" => true,
204 "post" => true
205 );
206 /* @var HttpRequest $request */
207 protected $request;
208 protected $http;
209
210 const FILE_NAME = "bxu_files";
211 const INFO_NAME = "bxu_info";
212 const EVENT_NAME = "main_bxu";
213 const SESSION_LIST = "MFI_SESSIONS";
214 const SESSION_TTL = 86400;
215
216 public function __construct($params = array())
217 {
218 global $APPLICATION;
219
220 $this->script = $APPLICATION->GetCurPageParam();
221
222 $params = is_array($params) ? $params : array($params);
223 $params["copies"] = (isset($params["copies"]) && is_array($params["copies"]) ? $params["copies"] : array()) + $this->params["copies"];
224 $params["storage"] = (isset($params["storage"]) && is_array($params["storage"]) ? $params["storage"] : array()) + $this->params["storage"];
225 $params["storage"]["moduleId"] = preg_replace("/[^a-z_-]/i", "_", $params["storage"]["moduleId"]);
226 $this->params = $params;
227 if (array_key_exists("controlId", $params))
228 $this->controlId = $params["controlId"];
229 if (array_key_exists("events", $params) && is_array($params["events"]))
230 {
231 foreach($params["events"] as $key => $val)
232 {
233 $this->setHandler($key, $val);
234 }
235 }
236 unset($this->params["events"]);
237
238 $this->path = \CTempFile::GetDirectoryName(
239 12,
240 array(
241 "bxu",
242 $this->params["storage"]["moduleId"],
243 md5(serialize(array(
244 $this->controlId,
245 bitrix_sessid(),
246 \CMain::GetServerUniqID()
247 ))
248 )
249 )
250 );
251 $this->request = Context::getCurrent()->getRequest();
252 }
253
254 public function setControlId($controlId)
255 {
256 $this->controlId = $controlId;
257 }
258
259 public function setHandler($name, $callback)
260 {
261 AddEventHandler(self::EVENT_NAME, $name, $callback);
262 return $this;
263 }
269 protected static function removeTmpPath($item)
270 {
271 if (is_array($item))
272 {
273 if (array_key_exists("tmp_name", $item))
274 {
275 unset($item["tmp_name"]);
276 }
277 foreach ($item as $key => $val)
278 {
279 if ($key == "chunksInfo")
280 {
281 $item[$key]["uploaded"] = count($item[$key]["uploaded"]);
282 $item[$key]["written"] = count($item[$key]["written"]);
283 }
284 else if (is_array($val))
285 {
286 $item[$key] = self::removeTmpPath($val);
287 }
288 }
289 }
290 return $item;
291 }
292
293 public static function prepareData($data)
294 {
295 array_walk_recursive(
296 $data,
297 function(&$v, $k) {
298 if ($k == "error")
299 {
300 $v = preg_replace("/<(.+?)>/is".BX_UTF_PCRE_MODIFIER, "", $v);
301 }
302 }
303 );
304 return self::removeTmpPath($data);
305 }
306
313 protected function fillRequireData()
314 {
315 $this->mode = $this->getRequest("mode");
316 if (!in_array($this->mode, array("upload", "delete", "view")))
317 throw new ArgumentOutOfRangeException("mode");
318
319 if ($this->mode != "view" && !check_bitrix_sessid())
320 throw new AccessDeniedException("Bad sessid.");
321
322 $this->version = (int) $this->getRequest("version");
323
324 $directory = \CBXVirtualIo::GetInstance()->GetDirectory($this->path);
325 $directoryExists = $directory->IsExists();
326 if (!$directory->Create())
327 throw new NotImplementedException("Mandatory directory has not been created.");
328 if (!$directoryExists)
329 {
330 $access = \CBXVirtualIo::GetInstance()->GetFile($directory->GetPath()."/.access.php");
331 $content = '<?$PERM["'.$directory->GetName().'"]["*"]="X";?>';
332
333 if (!$access->IsExists() || mb_strpos($access->GetContents(), $content) === false)
334 {
335 if (($fd = $access->Open('ab')))
336 {
337 fwrite($fd, $content);
338 }
339 fclose($fd);
340 }
341 }
342
343 return false;
344 }
345
346 protected function showJsonAnswer($result)
347 {
348 if (!defined("PUBLIC_AJAX_MODE"))
349 define("PUBLIC_AJAX_MODE", true);
350 if (!defined("NO_KEEP_STATISTIC"))
351 define("NO_KEEP_STATISTIC", "Y");
352 if (!defined("NO_AGENT_STATISTIC"))
353 define("NO_AGENT_STATISTIC", "Y");
354 if (!defined("NO_AGENT_CHECK"))
355 define("NO_AGENT_CHECK", true);
356 if (!defined("DisableEventsCheck"))
357 define("DisableEventsCheck", true);
358
359 require_once(\Bitrix\Main\Application::getInstance()->getContext()->getServer()->getDocumentRoot()."/bitrix/modules/main/include/prolog_before.php");
360 global $APPLICATION;
361
362 $APPLICATION->RestartBuffer();
363
364 $version = IsIE();
365 if ( !(0 < $version && $version < 10) )
366 header('Content-Type:application/json; charset=UTF-8');
367
368 echo Json::encode($result);
369 \CMain::finalActions();
370 die;
371 }
372
378 protected function setRequestMethodToCheck(array $methods)
379 {
380 foreach ($this->requestMethods as $method => $value)
381 $this->requestMethods[$method] = in_array($method, $methods);
382 return $this;
383 }
388 protected function getRequest($key)
389 {
390 if ($this->requestMethods["post"] &&
391 is_array($this->request->getPost(self::INFO_NAME)) &&
392 array_key_exists($key, $this->request->getPost(self::INFO_NAME)))
393 {
394 $res = $this->request->getPost(self::INFO_NAME);
395 return $res[$key];
396 }
397 if ($this->requestMethods["get"] &&
398 is_array($this->request->getQuery(self::INFO_NAME)) &&
399 array_key_exists($key, $this->request->getQuery(self::INFO_NAME)))
400 {
401 $res = $this->request->getQuery(self::INFO_NAME);
402 return $res[$key];
403 }
404
405 return null;
406 }
407
412 public function getParam($key)
413 {
414 return $this->params[$key];
415 }
421 public function checkPost($checkPost = true)
422 {
423 if ($checkPost === false && !is_array($this->request->getQuery(self::INFO_NAME)) ||
424 $checkPost !== false && !is_array($this->request->getPost(self::INFO_NAME)))
425 return false;
426
427 if ($checkPost === false)
428 $this->setRequestMethodToCheck(array("get"));
429
430 try
431 {
432 $this->fillRequireData();
433 $cid = FileInputUtility::instance()->registerControl($this->getRequest("CID"), $this->controlId);
434
435 if ($this->mode == "upload")
436 {
437 $package = new Package(
438 $this->path,
439 $cid,
440 $this->getRequest("packageIndex")
441 );
442 $package
443 ->setStorage($this->params["storage"])
444 ->setCopies($this->params["copies"]);
445
446 $response = $package->checkPost($this->params);
447
448 if ($this->version <= 1)
449 {
450 $response2 = array();
451 foreach ($response as $k => $r)
452 {
453 $response2[$k] = array(
454 "hash" => $r["hash"],
455 "status" => $r["status"],
456 "file" => $r
457 );
458 if (isset($r["error"]))
459 $response2[$k]["error"] = $r["error"];
460 }
461 $result = array(
462 "status" => $package->getLog("uploadStatus") == "uploaded" ? "done" : "inprogress",
463 "package" => array(
464 $package->getIndex() => array_merge(
465 $package->getLog(),
466 array(
467 "executed" => $package->getLog("executeStatus") == "executed",
468 "filesCount" => $package->getLog("filesCount")
469 )
470 )
471 ),
472 "report" => array(
473 "uploading" => array(
474 $package->getCid() => $package->getCidLog()
475 )
476 ),
477 "files" => self::prepareData($response2)
478 );
479 $this->showJsonAnswer($result);
480 }
481 }
482 else if ($this->mode == "delete")
483 {
484 $cid = FileInputUtility::instance()->registerControl($this->getRequest("CID"), $this->controlId);
485 File::deleteFile($cid, $this->getRequest("hash"), $this->path);
486 }
487 else
488 {
489 File::viewFile($cid, $this->getRequest("hash"), $this->path);
490 }
491 return true;
492 }
493 catch (Main\IO\IoException $e)
494 {
495 $this->showJsonAnswer(array(
496 "status" => "error",
497 "error" => "Something went wrong with the temporary file."
498 ));
499 }
500 catch (\Exception $e)
501 {
502 $this->showJsonAnswer(array(
503 "status" => "error",
504 "error" => $e->getMessage()
505 ));
506 }
507 return false;
508 }
509
517 public function checkCanvases($hash, &$file, $canvases = array(), $watermark = array())
518 {
519 if (!empty($watermark))
520 {
521 $file["files"]["default"] = File::createCanvas(
522 $file["files"]["default"],
523 $file["files"]["default"],
524 array(),
525 $watermark
526 );
527 }
528 if (is_array($canvases))
529 {
530 foreach ($canvases as $canvas => $canvasParams)
531 {
532 if (!array_key_exists($canvas, $file["files"]))
533 {
534 $source = $file["files"]["default"]; // TODO pick up more appropriate copy by params
535 $file["files"][$canvas] = File::createCanvas($source,
536 array(
537 "code" => $canvas,
538 "tmp_name" => mb_substr($source["tmp_name"], 0, -7).$canvas,
539 "url" => mb_substr($source["url"], 0, -7).$canvas
540 ), $canvasParams, $watermark);
541 }
542 }
543 }
544 return $file;
545 }
546 public function deleteFile($hash) {
547 $cid = FileInputUtility::instance()->registerControl($this->getRequest("CID"), $this->controlId);
548 File::deleteFile($cid, $hash, $this->path);
549 }
550
555 public static function getPaths($tmpName)
556 {
557 $docRoot = null;
558 $io = \CBXVirtualIo::GetInstance();
559 if (($tempRoot = \CTempFile::GetAbsoluteRoot()) && ($strFilePath = $tempRoot.$tmpName) &&
560 $io->FileExists($strFilePath) && ($url = File::getUrlFromRelativePath($tmpName)))
561 {
562 return array(
563 "tmp_url" => $url,
564 "tmp_name" => $strFilePath
565 );
566 }
567 else if ((($docRoot = \Bitrix\Main\Application::getInstance()->getContext()->getServer()->getDocumentRoot()) && $strFilePath = $docRoot.$tmpName) && $io->FileExists($strFilePath))
568 {
569 return array(
570 "tmp_url" => $tmpName,
571 "tmp_name" => $strFilePath
572 );
573 }
574 else if ($io->FileExists($tmpName) && ($docRoot = \Bitrix\Main\Application::getInstance()->getContext()->getServer()->getDocumentRoot()) &&
575 mb_strpos($tmpName, $docRoot) === 0)
576 {
577 return array(
578 "tmp_url" => str_replace("//", "/", "/".mb_substr($tmpName, mb_strlen($docRoot))),
579 "tmp_name" => $tmpName
580 );
581 }
582 return false;
583 }
584
585}
static getCurrent()
Definition context.php:241
static registerAutoLoadClasses($moduleName, array $classes)
Definition loader.php:273
static loadMessages($file)
Definition loc.php:64
static viewFile($cid, $hash, $path)
Definition file.php:471
static createCanvas($source, $dest, $canvasParams=array(), $watermarkParams=array())
Definition file.php:695
static getUrlFromRelativePath($tmpName)
Definition file.php:520
static deleteFile($cid, $hash, $path)
Definition file.php:450
offsetSet($offset, $value)
Definition uploader.php:148
checkCanvases($hash, &$file, $canvases=array(), $watermark=array())
Definition uploader.php:517
setRequestMethodToCheck(array $methods)
Definition uploader.php:378