Full implemantation
This commit is contained in:
@ -3,37 +3,65 @@ namespace ProVM\Common\Service;
|
||||
|
||||
use Ddeboer\Imap\Message\AttachmentInterface;
|
||||
use Ddeboer\Imap\MessageInterface;
|
||||
use ProVM\Emails\Model\Attachment;
|
||||
use ProVM\Common\Exception\Message\NoAttachments;
|
||||
use ProVM\Emails\Model\Message;
|
||||
use ProVM\Emails\Repository\Attachment;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Safe\Exceptions\FilesystemException;
|
||||
|
||||
class Attachments
|
||||
class Attachments extends Base
|
||||
{
|
||||
public function __construct(Decrypt $decrypt, \ProVM\Emails\Repository\Attachment $repository, string $attachments_folder)
|
||||
public function __construct(Messages $messages, Attachment $repository, Remote\Attachments $remoteService,
|
||||
Decrypt $decrypt, string $attachments_folder, LoggerInterface $logger)
|
||||
{
|
||||
$this->setDecrypt($decrypt);
|
||||
$this->setAttachmentsFolder($attachments_folder);
|
||||
$this->setMessages($messages)
|
||||
->setRepository($repository)
|
||||
->setRemoteService($remoteService)
|
||||
->setDecrypt($decrypt)
|
||||
->setFolder($attachments_folder)
|
||||
->setLogger($logger);
|
||||
}
|
||||
|
||||
protected string $attachments_folder;
|
||||
protected Messages $messages;
|
||||
protected Attachment $repository;
|
||||
protected Remote\Attachments $remoteService;
|
||||
protected Decrypt $decrypt;
|
||||
protected \ProVM\Emails\Repository\Attachment $repository;
|
||||
protected string $folder;
|
||||
|
||||
public function getAttachmentsFolder(): string
|
||||
public function getMessages(): Messages
|
||||
{
|
||||
return $this->attachments_folder;
|
||||
return $this->messages;
|
||||
}
|
||||
public function getRepository(): Attachment
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
public function getRemoteService(): Remote\Attachments
|
||||
{
|
||||
return $this->remoteService;
|
||||
}
|
||||
public function getDecrypt(): Decrypt
|
||||
{
|
||||
return $this->decrypt;
|
||||
}
|
||||
public function getRepository(): \ProVM\Emails\Repository\Attachment
|
||||
public function getFolder(): string
|
||||
{
|
||||
return $this->repository;
|
||||
return $this->folder;
|
||||
}
|
||||
|
||||
public function setAttachmentsFolder(string $folder): Attachments
|
||||
public function setMessages(Messages $messages): Attachments
|
||||
{
|
||||
$this->attachments_folder = $folder;
|
||||
$this->messages = $messages;
|
||||
return $this;
|
||||
}
|
||||
public function setRepository(Attachment $repository): Attachments
|
||||
{
|
||||
$this->repository = $repository;
|
||||
return $this;
|
||||
}
|
||||
public function setRemoteService(Remote\Attachments $service): Attachments
|
||||
{
|
||||
$this->remoteService = $service;
|
||||
return $this;
|
||||
}
|
||||
public function setDecrypt(Decrypt $decrypt): Attachments
|
||||
@ -41,119 +69,164 @@ class Attachments
|
||||
$this->decrypt = $decrypt;
|
||||
return $this;
|
||||
}
|
||||
public function setRepository(\ProVM\Emails\Repository\Attachment $repository): Attachments
|
||||
public function setFolder(string $folder): Attachments
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->folder = $folder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function validateAttachment(AttachmentInterface $remote_attachment): bool
|
||||
public function getLocalAttachment(Message $message, string $relative_filename): \ProVM\Emails\Model\Attachment
|
||||
{
|
||||
return str_contains($remote_attachment->getFilename(), '.pdf');
|
||||
return $this->getRepository()->fetchByMessageAndFilename($message->getId(), $relative_filename);
|
||||
}
|
||||
public function getRemoteAttachment(Message $message, string $relative_filename): AttachmentInterface
|
||||
{
|
||||
$remote_message = $this->getMessages()->getRemoteMessage($message->getUID());
|
||||
return $this->getRemoteService()->get($remote_message, $relative_filename);
|
||||
}
|
||||
|
||||
public function buildAttachment(Message $message, AttachmentInterface $remote_attachment): Attachment
|
||||
public function getAll(): array
|
||||
{
|
||||
return $this->getRepository()->fetchAll();
|
||||
}
|
||||
public function create(int $message_id): array
|
||||
{
|
||||
$message = $this->getMessages()->getRepository()->fetchById($message_id);
|
||||
$remote_message = $this->getMessages()->getRemoteMessage($message->getUID());
|
||||
if (!$remote_message->hasAttachments()) {
|
||||
throw new NoAttachments($remote_message);
|
||||
}
|
||||
$attachments = [];
|
||||
foreach ($remote_message->getAttachments() as $attachment) {
|
||||
if (!$this->getMessages()->validateAttachment($attachment)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->save($message, $attachment, false)) {
|
||||
$attachments []= $attachment->getFilename();
|
||||
}
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
public function grab(int $message_id): array
|
||||
{
|
||||
$message = $this->getMessages()->getRepository()->fetchById($message_id);
|
||||
$remote_message = $this->getMessages()->getRemoteMessage($message->getUID());
|
||||
if (!$remote_message->hasAttachments()) {
|
||||
throw new NoAttachments($remote_message);
|
||||
}
|
||||
$attachments = [];
|
||||
foreach ($remote_message->getAttachments() as $attachment) {
|
||||
if (!$this->getMessages()->validateAttachment($attachment)) {
|
||||
continue;
|
||||
}
|
||||
if ($this->save($message, $attachment)) {
|
||||
$attachments []= $attachment->getFilename();
|
||||
}
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
public function save(Message $message, AttachmentInterface $remote_attachment, bool $upload = true): bool
|
||||
{
|
||||
$data = [
|
||||
'message_id' => $message->getId(),
|
||||
'filename' => $this->buildFilename($message, $remote_attachment)
|
||||
'filename' => $remote_attachment->getFilename()
|
||||
];
|
||||
return $this->getRepository()->create($data);
|
||||
}
|
||||
try {
|
||||
$attachment = $this->getRepository()->create($data);
|
||||
$this->getRepository()->save($attachment);
|
||||
if ($upload and $this->upload($attachment, $remote_attachment)) {
|
||||
$attachment->itIsDownloaded();
|
||||
$message->doesHaveDownloadedAttachments();
|
||||
$this->getMessages()->getRepository()->save($message);
|
||||
|
||||
public function exists(Attachment $attachment): bool
|
||||
{
|
||||
$filename = $this->buildFilename($attachment);
|
||||
return file_exists($filename);
|
||||
}
|
||||
if ($this->isFileEncrypted($attachment->getMessage(), $attachment->getFilename())) {
|
||||
$attachment->itIsEncrypted();
|
||||
|
||||
public function buildFilename(Message $message, AttachmentInterface $attachment): string
|
||||
{
|
||||
$filename = implode(' - ', [
|
||||
$message->getSubject(),
|
||||
$message->getDateTime()->format('Y-m-d'),
|
||||
$attachment->getFilename()
|
||||
]);
|
||||
return implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getAttachmentsFolder(),
|
||||
$filename
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkEncrypted(): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($this->fetchAttachments() as $attachment) {
|
||||
$output[$attachment->getFilename()] = $this->getDecrypt()->isEncrypted($attachment->getRealPath());
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function fetchAttachments(): array
|
||||
{
|
||||
$files = new \FilesystemIterator($this->getAttachmentsFolder());
|
||||
$attachments = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
if ($this->isFileDecrypted($attachment->getMessage(), $attachment->getFilename())) {
|
||||
$attachment->itIsDecrypted();
|
||||
} else {
|
||||
if ($this->decrypt($attachment->getMessage(), $attachment->getFilename())) {
|
||||
$attachment->itIsDecrypted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$attachments []= $file;
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
public function fetchDecryptedAttachments(): array
|
||||
{
|
||||
$folder = implode(DIRECTORY_SEPARATOR, [$this->getAttachmentsFolder(), 'decrypted']);
|
||||
$files = new \FilesystemIterator($folder);
|
||||
$attachments = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
$attachments []= $file;
|
||||
}
|
||||
return $attachments;
|
||||
}
|
||||
public function fetchFullAttachments(): array
|
||||
{
|
||||
$attachments = $this->fetchAttachments();
|
||||
$output = [];
|
||||
foreach ($attachments as $attachment) {
|
||||
$att = [
|
||||
'original_attachment' => $attachment,
|
||||
'encrypted' => $this->getDecrypt()->isEncrypted($attachment->getRealPath())
|
||||
];
|
||||
if ($att['encrypted']) {
|
||||
$att['decrypted_attachment'] = $this->getDecryptedAttachment($attachment);
|
||||
}
|
||||
$output []= $att;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getAttachment(string $filename): \SplFileInfo
|
||||
{
|
||||
if (!str_contains($filename, $this->getAttachmentsFolder())) {
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [$this->getAttachmentsFolder(), $filename]);
|
||||
}
|
||||
return new \SplFileInfo($filename);
|
||||
}
|
||||
public function getDecryptedAttachment(\SplFileInfo $info): \SplFileInfo|bool
|
||||
{
|
||||
$new_file = implode(DIRECTORY_SEPARATOR, [$info->getPath(), 'decrypted', $info->getFilename()]);
|
||||
if (!file_exists($new_file)) {
|
||||
$this->getRepository()->save($attachment);
|
||||
return true;
|
||||
} catch (PDOException $e) {
|
||||
$this->getLogger()->error($e);
|
||||
return false;
|
||||
}
|
||||
return new \SplFileInfo($new_file);
|
||||
}
|
||||
|
||||
public function removeEncryption(string $filename): \SplFileInfo
|
||||
public function upload(\ProVM\Emails\Model\Attachment $attachment, AttachmentInterface $remote_attachment): bool
|
||||
{
|
||||
$attachment = $this->getAttachment($filename);
|
||||
$new_file = implode(DIRECTORY_SEPARATOR, [$attachment->getPath(), 'decrypted', $attachment->getFilename()]);
|
||||
if ($this->getDecrypt()->runCommand($attachment->getRealPath(), $new_file)) {
|
||||
return new \SplFileInfo($new_file);
|
||||
$destination = implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getFolder(),
|
||||
$attachment->getFullFilename()
|
||||
]);
|
||||
try {
|
||||
\Safe\file_put_contents($destination, $remote_attachment->getDecodedContent());
|
||||
return true;
|
||||
} catch (FilesystemException $e) {
|
||||
$this->getLogger()->error($e);
|
||||
return false;
|
||||
}
|
||||
return $attachment;
|
||||
}
|
||||
public function isFileEncrypted(Message $message, string $relative_filename): bool
|
||||
{
|
||||
$attachment = $this->getLocalAttachment($message, $relative_filename);
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getFolder(),
|
||||
$attachment->getFullFilename()
|
||||
]);
|
||||
try {
|
||||
return $this->getDecrypt()->isEncrypted($filename);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function isFileDecrypted(Message $message, string $relative_filename): bool
|
||||
{
|
||||
$attachment = $this->getLocalAttachment($message, $relative_filename);
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getFolder(),
|
||||
'decrypted',
|
||||
$attachment->getFullFilename()
|
||||
]);
|
||||
try {
|
||||
return !$this->getDecrypt()->isEncrypted($filename);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function decrypt(Message $message, string $relative_filename): bool
|
||||
{
|
||||
$attachment = $this->getLocalAttachment($message, $relative_filename);
|
||||
$source = implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getFolder(),
|
||||
$attachment->getFullFilename()
|
||||
]);
|
||||
$destination = implode(DIRECTORY_SEPARATOR, [
|
||||
$this->getFolder(),
|
||||
'decrypted',
|
||||
$attachment->getFullFilename()
|
||||
]);
|
||||
return $this->getDecrypt()->runCommand($source, $destination);
|
||||
}
|
||||
public function isDownloaded(Message $message, MessageInterface $remote_message): bool
|
||||
{
|
||||
if (!$message->hasValidAttachments()) {
|
||||
return false;
|
||||
}
|
||||
foreach ($remote_message->getAttachments() as $attachment) {
|
||||
if (!str_contains($attachment->getFilename(), '.pdf')) {
|
||||
continue;
|
||||
}
|
||||
$attachment = $this->getLocalAttachment($message, $attachment->getFilename());
|
||||
if (!$attachment->isDownloaded()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user