225 lines
6.2 KiB
PHP
225 lines
6.2 KiB
PHP
|
<?php
|
|||
|
|
|||
|
namespace common\services\abiturientController\questionary;
|
|||
|
|
|||
|
use common\components\UUIDManager;
|
|||
|
use common\models\AbiturientAvatar;
|
|||
|
use common\modules\abiturient\models\AbiturientQuestionary;
|
|||
|
use common\modules\abiturient\models\AlreadyReceivedFile;
|
|||
|
use common\modules\abiturient\models\File;
|
|||
|
use common\modules\abiturient\models\FilesManager;
|
|||
|
use Imagine\Image\Box;
|
|||
|
use Imagine\Image\ImageInterface;
|
|||
|
use Yii;
|
|||
|
use yii\helpers\FileHelper;
|
|||
|
use yii\imagine\Image;
|
|||
|
use yii\web\UploadedFile;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class AvatarService extends AbiturientQuestionaryService
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public function uploadAvatar(AbiturientQuestionary $questionary): array
|
|||
|
{
|
|||
|
$avatarFromPost = UploadedFile::getInstanceByName('file');
|
|||
|
if ($avatarFromPost !== null) {
|
|||
|
$abitAvatar = $this->getAvatar($questionary);
|
|||
|
|
|||
|
$abitAvatar->file = $avatarFromPost;
|
|||
|
if ($abitAvatar->validate()) {
|
|||
|
return $this->saveAvatarProcess($abitAvatar, $avatarFromPost);
|
|||
|
}
|
|||
|
|
|||
|
return [
|
|||
|
'error' => print_r($abitAvatar->errors, true),
|
|||
|
'status' => false,
|
|||
|
'fileLink' => '',
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
return [
|
|||
|
'error' => 'Не удалось загрузить файл',
|
|||
|
'status' => false,
|
|||
|
'fileLink' => '',
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public function deleteAvatar(AbiturientQuestionary $questionary): bool
|
|||
|
{
|
|||
|
$abiturientAvatar = $questionary->abiturientAvatar;
|
|||
|
if (!$abiturientAvatar) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return $abiturientAvatar->archive();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function getAvatar(AbiturientQuestionary $questionary): AbiturientAvatar
|
|||
|
{
|
|||
|
$abitAvatar = $questionary->getComputedAbiturientAvatar();
|
|||
|
if (!$abitAvatar->isNewRecord) {
|
|||
|
$attachmentType = $abitAvatar->attachmentType;
|
|||
|
$abitAvatar->safeDelete(Yii::$app->user->identity);
|
|||
|
|
|||
|
$abitAvatar = new AbiturientAvatar();
|
|||
|
$abitAvatar->attachment_type_id = $attachmentType->id;
|
|||
|
$abitAvatar->deleted = false;
|
|||
|
}
|
|||
|
$abitAvatar->owner_id = $questionary->user_id;
|
|||
|
$abitAvatar->questionary_id = $questionary->id;
|
|||
|
|
|||
|
return $abitAvatar;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function saveAvatarProcess(
|
|||
|
AbiturientAvatar $abitAvatar,
|
|||
|
UploadedFile $avatarFromPost
|
|||
|
): array
|
|||
|
{
|
|||
|
$tmpFile = $this->buildTmpFile($avatarFromPost);
|
|||
|
$abitAvatar->file = $this->getOrCreateByTempAvatar($abitAvatar, $avatarFromPost, $tmpFile);
|
|||
|
|
|||
|
if ($abitAvatar->upload()) {
|
|||
|
$this->changeHistoryAndCleanUp($abitAvatar, $tmpFile);
|
|||
|
|
|||
|
return [
|
|||
|
'error' => '',
|
|||
|
'status' => true,
|
|||
|
'fileLink' => $abitAvatar->getFileDownloadUrl()
|
|||
|
];
|
|||
|
}
|
|||
|
if (file_exists($tmpFile) && !is_dir($tmpFile)) {
|
|||
|
FileHelper::unlink($tmpFile);
|
|||
|
}
|
|||
|
return [
|
|||
|
'error' => 'Не удалось сохранить файл',
|
|||
|
'status' => false,
|
|||
|
'fileLink' => '',
|
|||
|
];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function resizeAvatar(UploadedFile $avatarFromPost): ImageInterface
|
|||
|
{
|
|||
|
$imagine = Image::getImagine();
|
|||
|
$resizedImage = $imagine->open(Yii::getAlias($avatarFromPost->tempName));
|
|||
|
|
|||
|
$selected_height = abs(intval($this->request->post('h')));
|
|||
|
$selected_width = abs(intval($this->request->post('w')));
|
|||
|
|
|||
|
if ($selected_height != 0 && $selected_width != 0) {
|
|||
|
$x = abs(intval($this->request->post('x')));
|
|||
|
$y = abs(intval($this->request->post('y')));
|
|||
|
$showed_image_width = abs(intval($this->request->post('width')));
|
|||
|
$showed_image_height = abs(intval($this->request->post('height')));
|
|||
|
|
|||
|
|
|||
|
$real_image_width = $resizedImage->getSize()->getWidth();
|
|||
|
$real_image_height = $resizedImage->getSize()->getHeight();
|
|||
|
|
|||
|
$map_multiplier_width = $real_image_width / $showed_image_width;
|
|||
|
$map_multiplier_height = $real_image_height / $showed_image_height;
|
|||
|
$mapped_selected_height = $selected_height * $map_multiplier_height;
|
|||
|
$mapped_selected_width = $selected_width * $map_multiplier_width;
|
|||
|
$mapped_x = $x * $map_multiplier_width;
|
|||
|
$mapped_y = $y * $map_multiplier_height;
|
|||
|
|
|||
|
$resizedImage = Image::crop($resizedImage, $mapped_selected_width, $mapped_selected_height, [$mapped_x, $mapped_y]);
|
|||
|
}
|
|||
|
return $resizedImage->resize(new Box(200, 200));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function buildTmpFile(UploadedFile $avatarFromPost): string
|
|||
|
{
|
|||
|
$originalHash = FilesManager::GetFileHash($avatarFromPost->tempName);
|
|||
|
$extension = $avatarFromPost->extension;
|
|||
|
|
|||
|
return FileHelper::normalizePath(sys_get_temp_dir() .
|
|||
|
'/' .
|
|||
|
mb_strtolower($originalHash) .
|
|||
|
str_replace('-', '', UUIDManager::GetUUID()) .
|
|||
|
'.' .
|
|||
|
$extension);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function getOrCreateByTempAvatar(
|
|||
|
AbiturientAvatar $abitAvatar,
|
|||
|
UploadedFile $avatarFromPost,
|
|||
|
string $tmpFile
|
|||
|
): AlreadyReceivedFile
|
|||
|
{
|
|||
|
$saveOptions = ['jpeg_quality' => 100, 'png_compression_level' => 1];
|
|||
|
$image = $this->resizeAvatar($avatarFromPost);
|
|||
|
$image->save($tmpFile, $saveOptions);
|
|||
|
|
|||
|
$uploadFilename = $avatarFromPost->name;
|
|||
|
$fileHash = FilesManager::GetFileHash($tmpFile);
|
|||
|
$file = File::GetOrCreateByTempFile(
|
|||
|
$abitAvatar->getPathToStoreFiles(),
|
|||
|
[
|
|||
|
$uploadFilename,
|
|||
|
pathinfo($uploadFilename, PATHINFO_EXTENSION),
|
|||
|
$fileHash,
|
|||
|
null,
|
|||
|
function (string $path) use ($tmpFile): bool {
|
|||
|
return copy($tmpFile, $path);
|
|||
|
}
|
|||
|
]
|
|||
|
);
|
|||
|
|
|||
|
return new AlreadyReceivedFile($file, null, $uploadFilename, $fileHash, null);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private function changeHistoryAndCleanUp(AbiturientAvatar $abitAvatar, string $tmpFile): void
|
|||
|
{
|
|||
|
$abitAvatar->getChangeHistoryHandler()->getInsertHistoryAction()->proceed();
|
|||
|
|
|||
|
if (file_exists($tmpFile) && !is_dir($tmpFile)) {
|
|||
|
FileHelper::unlink($tmpFile);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|