187 $this->isBitrix24 = Main\ModuleManager::isModuleInstalled(
'bitrix24');
189 $this->isCloudAvailable =
190 Main\ModuleManager::isModuleInstalled(
'clouds') &&
191 Main\Loader::includeModule(
'clouds');
193 $this->processToken = $this->request->get(
'PROCESS_TOKEN');
194 $this->exportType = $this->request->get(
'EXPORT_TYPE');
195 $this->componentName = $this->request->get(
'COMPONENT_NAME');
197 $signedParameters = $this->request->getPost(
'signedParameters');
198 if (!empty($signedParameters))
203 $initialOptions = $this->request->getPost(
'INITIAL_OPTIONS');
204 if (!empty($initialOptions))
206 $this->componentParameters[
'STEXPORT_INITIAL_OPTIONS'] = $initialOptions;
210 if (!empty($progressData))
212 $this->isNewProcess = (empty($progressData[
'processToken']) || $progressData[
'processToken'] !==
$this->processToken);
213 if (!$this->isNewProcess)
216 foreach ($this->fieldToStoreInProcess as $fieldName)
218 if (isset($progressData[$fieldName]))
220 $this->{$fieldName} = $progressData[$fieldName];
226 if ($this->isCloudAvailable)
229 if (empty($bucketList))
231 $this->isCloudAvailable =
false;
275 if ($this->isCloudAvailable && $this->useCloud ===
null)
278 ($this->bucketId < 0) &&
279 ($this->totalItems > 0) &&
280 ($this->processedItems > 0) &&
281 ($this->fileName !==
'') &&
283 (($this->
getSizeTempFile() > $this->cloudMinChunkSize) || $this->isExportCompleted)
286 if ($this->isExportCompleted)
292 $predictedFileSize = round($this->
getSizeTempFile() * ceil($this->totalItems / $this->processedItems) * 1.5);
295 if ($this->
findInitBucket(array(
'fileSize' => $predictedFileSize,
'fileName' => $this->fileName)) ===
true)
298 $this->useCloud =
true;
303 $this->useCloud =
false;
304 $this->isCloudAvailable =
false;
309 if ($this->isNewProcess)
312 $this->stepCount = 0;
313 $this->timeStart = time();
316 elseif ($this->isBitrix24)
318 if ($this->isExportCompleted && !$this->isUploadFinished)
323 elseif ($this->isExportCompleted && $this->isUploadFinished)
342 if ($this->isExportCompleted && ($this->useCloud ===
true) && !$this->isUploadFinished)
347 elseif ($this->isExportCompleted && ($this->useCloud ===
true) && $this->isUploadFinished)
352 elseif ($this->isExportCompleted && ($this->useCloud ===
false || $this->useCloud ===
null))
357 elseif (($this->useCloud ===
true) && ($this->
getSizeTempFile() > $this->cloudMinChunkSize))
369 if ($nextAction === self::ACTION_PURGE)
373 if ($nextAction === self::ACTION_EXPORT)
378 if ($nextAction === self::ACTION_UPLOAD)
383 if ($nextAction === self::ACTION_FINISH)
430 if ($this->isNewProcess)
435 $this->processedItems = 0;
436 $this->totalItems = 0;
444 $nextPage = (int)floor($this->processedItems / $this->pageSize) + 1;
447 $this->componentParameters,
449 'STEXPORT_MODE' =>
'Y',
450 'EXPORT_TYPE' => $this->exportType,
451 'STEXPORT_PAGE_SIZE' => $this->pageSize,
452 'STEXPORT_TOTAL_ITEMS' => $this->totalItems,
453 'STEXPORT_LAST_EXPORTED_ID' => $this->lastExportedId,
454 'PAGE_NUMBER' => $nextPage,
459 $componentResult = $APPLICATION->IncludeComponent(
460 $this->componentName,
464 $exportData = ob_get_contents();
467 $processedItemsOnStep = 0;
469 if (is_array($componentResult))
471 if (isset($componentResult[
'ERROR']))
478 if (isset($componentResult[
'PROCESSED_ITEMS']))
480 $processedItemsOnStep = (int)$componentResult[
'PROCESSED_ITEMS'];
484 if ($nextPage === 1 && isset($componentResult[
'TOTAL_ITEMS']))
486 $this->totalItems = (int)$componentResult[
'TOTAL_ITEMS'];
489 if (isset($componentResult[
'LAST_EXPORTED_ID']))
491 $this->lastExportedId = (int)$componentResult[
'LAST_EXPORTED_ID'];
496 if ($this->totalItems == 0)
501 if ($processedItemsOnStep > 0)
503 $this->processedItems += $processedItemsOnStep;
510 if ($this->isExportCompleted && !$this->isCloudAvailable)
516 elseif ($processedItemsOnStep == 0)
519 $this->isExportCompleted =
true;
521 if (!$this->isCloudAvailable)
527 if ($this->isExportCompleted ===
true)
540 if ($this->totalItems == 0)
542 $this->isExportCompleted =
true;
573 $isUploadStarted = ($this->uploadedPart > 0);
574 if (!$isUploadStarted)
576 $reservedSize = round($chunkSize * ceil($this->totalItems / $this->pageSize) * 1.5);
581 'fileSize' => $reservedSize,
582 'fileName' => $this->uploadPath,
589 if ($this->bucket->FileExists($this->uploadPath))
591 if(!$this->bucket->DeleteFile($this->uploadPath))
606 if (!file_exists($this->filePath))
613 return AjaxJson::createError($this->errorCollection);
619 if ($this->isExportCompleted && !$isUploadStarted)
623 'name' => $this->fileName,
624 'size' => $this->fileSize,
625 'type' => $this->fileType,
626 'tmp_name' => $this->filePath,
629 if ($this->bucket->SaveFile($this->uploadPath, $uploadFile))
631 $this->uploadedPart ++;
632 $this->uploadedSize += $chunkSize;
634 $this->isUploadFinished =
true;
643 $uploader = new \CCloudStorageUpload($this->uploadPath);
644 if (!$uploader->isStarted())
646 if (!$uploader->Start($this->bucketId, $reservedSize, $this->fileType))
650 return AjaxJson::createError($this->errorCollection);
656 while ($uploader->hasRetries())
658 if ($uploader->Next($part, $this->bucket))
660 $this->uploadedPart ++;
661 $this->uploadedSize += $chunkSize;
669 if ($isSuccess && $this->isExportCompleted)
671 if ($uploader->Finish())
673 $this->isUploadFinished =
true;
760 if ($this->bucket instanceof \CCloudStorageBucket)
764 $now = new \DateTime(
'now');
767 if (preg_match(
'/^([^_]+)_([0-9]{8})_([^_]+)_.+$/i',
$fileName, $parts))
771 $date = \DateTime::createFromFormat(
'Ymd', $parts[2]);
772 $interval = $now->diff($date);
773 if ($interval->d > self::EXPIRE_DAYS)
813 if ($action == self::ACTION_CLEAR || $action == self::ACTION_CANCEL || $action == self::ACTION_PURGE)
820 if (!$this->isExportCompleted && $this->uploadedSize > 0)
824 elseif ($this->isExportCompleted && $this->uploadedSize > $this->fileSize)
831 'PROCESSED_ITEMS' => $this->processedItems,
832 'TOTAL_ITEMS' => $this->totalItems,
833 'UPLOADED_PART' => $this->uploadedPart,
834 'UPLOADED_SIZE' => $this->uploadedSize,
835 'UPLOADED_SIZE_FORMAT' => \CFile::FormatSize($this->uploadedSize),
836 'FILE_SIZE_FORMAT' => \CFile::FormatSize(
$fileSize),
839 $messagePlaceholders = array(
840 '#PROCESSED_ITEMS#' => $this->processedItems,
841 '#TOTAL_ITEMS#' => $this->totalItems,
842 '#UPLOADED_PART#' => $this->uploadedPart,
843 '#UPLOADED_SIZE#' => $this->uploadedSize,
844 '#UPLOADED_SIZE_FORMAT#' => \CFile::FormatSize($this->uploadedSize),
845 '#FILE_SIZE_FORMAT#' => \CFile::FormatSize(
$fileSize),
849 if ($action == self::ACTION_VOID)
853 elseif ($action == self::ACTION_PURGE)
857 elseif ($action == self::ACTION_CLEAR)
859 $message = htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_FILE_DROPPED'));
861 elseif ($action == self::ACTION_CANCEL)
863 $message = htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_ACTION_CANCEL'));
865 elseif ($action == self::ACTION_UPLOAD)
868 htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_ACTION_UPLOAD', $messagePlaceholders)).
'<br>'.
871 elseif ($action == self::ACTION_EXPORT)
874 htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_ACTION_EXPORT', $messagePlaceholders)).
'<br>'.
877 elseif ($this->isExportCompleted)
881 htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_ACTION_EXPORT', $messagePlaceholders));
884 if ($this->isBitrix24 || $this->useCloud ===
true)
886 if ($this->isUploadFinished)
895 if ($downloadLink !==
'')
897 $result[
'DOWNLOAD_LINK'] = $downloadLink;
899 $result[
'DOWNLOAD_LINK_NAME'] = htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_DOWNLOAD'));
900 $result[
'CLEAR_LINK_NAME'] = htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_CLEAR'));
906 htmlspecialcharsbx(
Loc::getMessage(
'MAIN_EXPORT_ACTION_EXPORT', $messagePlaceholders)).
'<br>'.
910 $result[
'SUMMARY_HTML'] = $message;
923 $avgStepDuration = $predictedStepCount = $predictedTimeDuration = 0;
925 if ($this->stepCount > 0 && $this->timeStart > 0)
927 $avgStepDuration = round((time() - $this->timeStart) / $this->stepCount);
928 if ($this->processedItems > 0)
930 $avgRowsPerStep = round($this->processedItems / $this->stepCount);
933 if ($this->totalItems > 0)
935 $predictedStepCount = round(($this->totalItems - $this->processedItems) / $avgRowsPerStep);
936 if ($this->useCloud ===
true)
938 $predictedStepCount *= 2;
941 if ($avgStepDuration > 0 && $predictedStepCount > 0)
943 $predictedTimeDuration = $avgStepDuration * $predictedStepCount * 1.1;
945 if ($predictedTimeDuration > 0)
947 $predictedTimeDurationHours = floor($predictedTimeDuration / 3600);
948 if ($predictedTimeDurationHours > 0)
950 $predictedTimeDurationMinutes = ceil(($predictedTimeDuration - $predictedTimeDurationHours * 3600) / 60);
954 '#HOURS#' => $predictedTimeDurationHours,
955 '#MINUTES#' => $predictedTimeDurationMinutes,
960 $predictedTimeDurationMinutes = round($predictedTimeDuration / 60);
964 '#MINUTES#' => ($predictedTimeDurationMinutes < 1 ?
"< 1" : $predictedTimeDurationMinutes),
1080 if (!($this->bucket instanceof \CCloudStorageBucket))
1082 $this->bucket = \CCloudStorage::FindBucketForFile(
1084 'FILE_SIZE' => $attributes[
'fileSize'],
1085 'MODULE_ID' => $this->module,
1087 $attributes[
'fileName']
1091 $this->bucket ===
null ||
1092 !($this->bucket instanceof \CCloudStorageBucket) ||
1093 !$this->bucket->init()
1099 $this->bucketId = $this->bucket->ID;
1100 $this->cloudMinChunkSize = $this->bucket->GetService()->GetMinUploadPartSize();
1323 $file = fopen($this->filePath,
'ab');
1324 if(is_resource($file))
1329 if($precedeUtf8Bom ===
true && (filesize($this->filePath) === 0))
1331 fwrite($file, chr(239).chr(187).chr(191));
1334 fwrite($file, $data);
1338 $this->fileSize = filesize($this->filePath);