portal.mkgtu.ru/common/modules/abiturient/models/ReceivingFile.php

166 lines
4.9 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace common\modules\abiturient\models;
use common\models\SendingFile;
use common\modules\abiturient\models\interfaces\ICanGetPathToStoreFile;
use common\modules\abiturient\models\interfaces\IReceivedFile;
use geoffry304\enveditor\exceptions\UnableReadFileException;
use geoffry304\enveditor\exceptions\UnableWriteToFileException;
use stdClass;
use Throwable;
use Yii;
use yii\helpers\FileHelper;
use yii\web\ServerErrorHttpException;
class ReceivingFile extends \yii\base\BaseObject implements IReceivedFile
{
const BASE_PATH = '@storage/web/tempZip';
protected $transfer_id;
protected $parts_count;
protected $file_hash;
protected $file_uid;
protected $file_name;
protected $temp_file_names = [];
public function __construct(stdClass $file_description_from_1c)
{
parent::__construct();
$this->transfer_id = $file_description_from_1c->TransferId ?? SendingFile::generateGuid();
$this->parts_count = $file_description_from_1c->FilePartsCount ?? 0;
$this->file_hash = $file_description_from_1c->FileHash;
$this->file_uid = $file_description_from_1c->FileUID;
$this->file_name = "{$file_description_from_1c->FileName}.{$file_description_from_1c->FileExt}";
}
public function setTempFileNames(array $temp_file_names)
{
$this->temp_file_names = $temp_file_names;
return $this;
}
public function getHash(): string
{
return $this->file_hash;
}
public function getFileUID(): string
{
return $this->file_uid;
}
public function fetchFilePart(int $part_number): string
{
$result = Yii::$app->soapClientWebApplication->load('GetFilePart', [
'TransferId' => $this->transfer_id,
'PartNumber' => $part_number,
'FileName' => pathinfo($this->uploadName)['filename'],
'FileExt' => $this->extension,
'FileHash' => $this->hash,
'FileUID' => $this->fileUID,
]);
$partData = '';
if (isset($result, $result->return, $result->return->PartData)) {
$partData = $result->return->PartData;
}
return ReceivingFile::StoreFileDataToTempFile($partData);
}
public static function StoreFileDataToTempFile(string $data): string
{
$temp_file = ReceivingFile::GenerateUnusedFileName();
if (file_put_contents($temp_file, $data) === false) {
throw new UnableWriteToFileException("Не удалось записать временный файл");
}
return $temp_file;
}
public function fetchFile()
{
try {
for ($i = 1; $i <= $this->parts_count; $i++) {
$this->temp_file_names[] = $this->fetchFilePart($i);
}
} catch (Throwable $throwable) {
$this->removeTempFiles();
throw $throwable;
}
}
public function removeTempFiles()
{
if ($this->temp_file_names) {
foreach ($this->temp_file_names as $temp_file_name) {
try {
if (file_exists($temp_file_name) && !is_dir($temp_file_name)) {
FileHelper::unlink($temp_file_name);
}
} catch (Throwable $e) {
Yii::error("Не удалось очистить временный файл {$temp_file_name} по причине: {$e->getMessage()}");
return false;
}
}
}
return true;
}
public static function GenerateUnusedFileName(): string
{
$base = Yii::getAlias(ReceivingFile::BASE_PATH);
$iter = 0;
do {
if ($iter > 5) {
throw new ServerErrorHttpException('Не удалось сформировать временный каталог');
}
$name = FileHelper::normalizePath($base . '/' . md5(Yii::$app->security->generateRandomString()));
$iter++;
} while (file_exists($name));
return $name;
}
public function getFileContent(): string
{
$tempFileNames = $this->temp_file_names;
if (!$tempFileNames) {
return '';
}
$result = '';
foreach ($tempFileNames as $temp_file_name) {
$tmp = file_get_contents($temp_file_name);
if ($tmp === false) {
throw new UnableReadFileException('Не удалось прочитать временный файл');
}
$result .= $tmp;
}
return $result;
}
public function getUploadName(): string
{
return $this->file_name;
}
public function getExtension(): string
{
return pathinfo($this->uploadName)['extension'];
}
public function getFile(ICanGetPathToStoreFile $entity_to_link): File
{
return File::GetOrCreateByTempFile(
$entity_to_link->getPathToStoreFiles(),
$this
);
}
}