new: Add classes required to upload identity document during account registration. #5

This commit is contained in:
weichien00
2021-07-03 00:58:24 +08:00
parent 9bcb45e5cc
commit aaf0ff7645
10 changed files with 533 additions and 0 deletions
@@ -0,0 +1,80 @@
<?php
namespace App\Classes\Modules\Documents\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\Modules\Documents\Services\ConvertsBase64ToFile;
class DocumentObject implements DataTransferObject
{
/** @var string */
private $document_type;
/** @var array */
private $files;
/** @var string */
private $reference;
/** @var int */
private $status;
/** @var string|null */
private $path;
/**
* DocumentObject constructor.
* @param string $document_type
* @param array $files
* @param string $reference
* @param int $status
* @param null|string $path
*/
public function __construct(string $document_type, array $files, string $reference, int $status, ?string $path = '')
{
$this->document_type = $document_type;
$this->files = $files;
$this->reference = $reference;
$this->status = $status;
$this->path = $path;
}
/**
* @return string
*/
public function getDocumentType(): string
{
return $this->document_type;
}
/**
* @return string
*/
public function getReference(): string
{
return $this->reference;
}
/**
* @return int
*/
public function getStatus(): int
{
return $this->status;
}
/**
* @return array
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function getFiles(): array
{
return (new ConvertsBase64ToFile($this->path))->convert($this->files);
}
}
@@ -0,0 +1,86 @@
<?php
namespace App\Classes\Modules\Documents\DataTransferObjects;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\ValueObjects\Constants\FileType;
use Illuminate\Support\Str;
use Intervention\Image\ImageManager;
class FileObject implements DataTransferObject
{
/** @var string */
private $data;
/**
* FileInfoObject constructor.
* @param string $data
*/
public function __construct(string $data)
{
$this->data = $data;
}
/**
* @return \Intervention\Image\Image|string
* @throws MalformedRequestException
*/
public function getData()
{
return $this->getExtension() === 'pdf' ? $this->data : (new imageManager())->make($this->data);
}
/**
* @return string
*/
public function getFileName(): string
{
return (string) Str::uuid();
}
/**
* @return string
*/
public function getMimeType(): string
{
return finfo_file(finfo_open(), $this->data, FILEINFO_MIME_TYPE);
}
/**
* @return string
* @throws MalformedRequestException
*/
public function getExtension(): string
{
if(array_key_exists($this->getMimeType(), FileType::EXTENSION)){
return FileType::EXTENSION[$this->getMimeType()];
}
throw new MalformedRequestException('Failed to save file due to Unknown file extension');
}
/**
* @return string
* @throws MalformedRequestException
*/
public function getDecodedData(): string
{
return $this->getExtension() === 'pdf' ?
base64_decode((explode('base64,', $this->getData()))[1]):
$this->getData()->encode('data-url')->encoded;
}
/**
* @param string $data
*/
public function setData(string $data): void
{
$this->data = $data;
}
}
@@ -0,0 +1,46 @@
<?php
namespace App\Classes\Modules\Documents\Processors;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\CompanyType;
use App\Classes\ValueObjects\Constants\DocumentType;
use Illuminate\Http\Request;
use App\Models\Company;
class UploadIdentityDocumentProcessor
{
/**
* UploadIdentityDocumentProcessor constructor.
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFile
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFile)
{
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
}
/**
* @param DocumentObject $object
* @return Array
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function execute(Request $request, Company $company): Array {
$object = new DocumentObject($company->type === CompanyType::COMPANY_BUSINESS ?
DocumentType::SSM_REGISTRATION : DocumentType::IDENTITY_CARD, $request->input('files'),
$request->input('identification_no'), ApprovalStatus::PENDING_VERIFICATION, 'identifications');
/** @var Document $document */
$document = $this->createsDocument->execute($company, $object);
return $this->createsFile->execute($document, $object);
}
}
@@ -0,0 +1,125 @@
<?php
namespace App\Classes\Modules\Documents\Services;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Documents\DataTransferObjects\FileObject;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class ConvertsBase64ToFile
{
/** @var string|null */
private $path;
/** @var array */
private $filesInfo;
/**
* ConvertsBase64ToFile constructor.
* @param null|string $path
*/
public function __construct(?string $path = 'documents')
{
$this->path = $path;
$this->filesInfo = [];
}
/**
* @param array $files
* @return array
* @throws MalformedRequestException
*/
public function convert($files = []){
foreach ($files as $file) {
$object = new FileObject($file);
$object->getExtension() === 'pdf' ? $this->generatePDF($object) : $this->generateImage($object);
}
return $this->filesInfo;
}
/**
* @param FileObject $file
* @throws MalformedRequestException
*/
private function generatePDF(FileObject $file){
$filePath = $this->generateFile($file);
$this->updateFiles($file, [ 'original' => [ 'file' => $filePath ] ]);
}
/**
* @param FileObject $file
* @throws MalformedRequestException
*/
private function generateImage(FileObject $file){
$fileInfo = [];
foreach (['original' => null, 'large' => 800, 'medium' => 480, 'small' => 320] as $size => $value) {
$suffix = $size !== 'original' ? '_'.$size : '';
if($size !== 'original') {
$thumbnail = $file->getData()->widen($value, function ($constraint) {
$constraint->upsize();
})->heighten($value, function ($constraint) {
$constraint->upsize();
});
$file->setData($thumbnail->encode('data-url')->encoded);
}
$filePath = $this->generateFile($file, $suffix);
$fileInfo[] = [ $size => [ 'file' => $filePath, 'width' => $file->getData()->width(), 'height' => $file->getData()->height() ]];
}
$this->updateFiles($file, $fileInfo);
}
/**
* @param FileObject $file
* @param string $suffix
* @return string
* @throws MalformedRequestException
*/
private function generateFile(FileObject $file, string $suffix = '') {
$filePath = $this->path.'/'.$file->getFileName().$suffix.'.'.$file->getExtension();
Storage::disk('documents')->put($filePath, $file->getDecodedData());
return $filePath;
}
/**
* @param FileObject $file
* @param array $fileInfo
* @throws MalformedRequestException
*/
private function updateFiles(FileObject $file, array $fileInfo){
$this->filesInfo[] = json_encode([
'path' => $this->path,
'filename' => $file->getFileName().'.'.$file->getExtension(),
'mime_type' => $file->getMimeType(),
'extension' => $file->getExtension(),
'file_info' => $fileInfo
]);
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\Modules\Documents\Services;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Classes\General\Interfaces\Documentable;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Models\Document;
class CreatesDocument extends AbstractUpdateRelationshipRecord
{
/**
* @param Documentable $documentable
* @param DocumentObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Documentable $documentable, DocumentObject $object)
{
$model = new Document();
$model->document_type = $object->getDocumentType();
$model->reference = $object->getReference();
return $this->handler($documentable->documents(), $model);
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Documents\Services;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Models\Document;
use App\Models\File;
class CreatesFiles extends AbstractUpdateRelationshipRecord
{
/**
* @param Document $document
* @param DocumentObject $object
* @return array
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Document $document, DocumentObject $object)
{
$models = [];
foreach ($object->getFiles() as $file) {
$model = new File(['file' => $file]);
$models[] = $this->handler($document->files(), $model);
}
return $models;
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\ValueObjects\Constants;
final class DocumentType {
public const PROFILE_PICTURE = 'PROFILE_PICTURE';
public const SSM_REGISTRATION = 'SSM_REGISTRATION';
public const IDENTITY_CARD = 'IDENTITY_CARD';
public const IDENTIFICATION_DOCUMENTS = [self::IDENTITY_CARD, self::SSM_REGISTRATION];
public const CUSTOMER_PAYMENT_PROOF = 'CUSTOMER_PAYMENT_PROOF';
public const CURRENCY_VENDOR_PAYMENT_PROOF = 'CURRENCY_VENDOR_PAYMENT_PROOF';
public const CURRENCY_VENDOR_ORDER = 'CURRENCY_VENDOR_ORDER';
public const WALLET_TOP_UP_PAYMENT_PROOF = 'WALLET_TOP_UP_PAYMENT_PROOF';
public const WALLET_REFUND_PAYMENT_PROOF = 'WALLET_REFUND_PAYMENT_PROOF';
public const PURCHASE_ORDER = 'PURCHASE_ORDER';
public const DELIVER_ORDER = 'DELIVER_ORDER';
public const INVOICE = 'INVOICE';
public const SUPPLIER_DELIVER_ORDER = 'SUPPLIER_DELIVER_ORDER';
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\ValueObjects\Constants;
class FileType
{
public const GIF = 'image/gif';
public const PNG = 'image/png';
public const JPEG = 'image/jpeg';
public const PDF = 'application/pdf';
public const EXTENSION = [
'image/gif' => 'gif',
'image/png' => 'png',
'image/jpeg' => 'jpeg',
'application/pdf' => 'pdf',
];
}
+59
View File
@@ -0,0 +1,59 @@
<?php
namespace App\Models;
use Carbon\Traits\Timestamp;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\hasMany;
/**
* Class Document
* @package App\Models
* @version August 4, 2020, 4:36 am
*
* @property int owner_id
* @property int owner_type
* @property int document_type
* @property string reference
* @property int status
* @property \App\Models\User approver
* @property timestamp issued_date
* @property timestamp expired_date
* @property timestamp approved_date
*/
class Document extends AbstractModel
{
use SoftDeletes;
protected $table = 'documents';
protected $dates = ['deleted_at'];
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function owner(): morphTo
{
return $this->morphTo();
}
/**
* @return hasMany
*/
public function files(): hasMany
{
return $this->hasMany(File::class, 'document_id');
}
/**
* @return HasOne
*/
public function approver(): hasOne
{
return $this->hasOne(User::class, 'id', 'approver');
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class File
* @package App\Models
* @version August 4, 2020, 4:36 am
*
* @property \App\Models\Document document_id
* @property text file
* @property int file_type_id
*/
class File extends AbstractModel
{
use SoftDeletes;
protected $table = 'files';
protected $fillable = ['file'];
protected $dates = ['deleted_at'];
public function getFileAttribute($value)
{
return $value ? json_decode($value) : [];
}
}