Newer
Older
<?php
/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
*
*/
/**
* @brief Email Controller
* @author dev@maarch.org
*/
namespace Email\controllers;
use Attachment\controllers\AttachmentController;
use Attachment\models\AttachmentModel;
use Docserver\models\DocserverModel;
use Docserver\models\DocserverTypeModel;
use Group\controllers\PrivilegeController;
use History\controllers\HistoryController;
use History\models\HistoryModel;
use Note\controllers\NoteController;
use Note\models\NoteEntityModel;
use Note\models\NoteModel;
use PHPMailer\PHPMailer\PHPMailer;
use Resource\controllers\ResController;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\ValidatorModel;
use User\models\UserModel;
class EmailController
{
public function send(Request $request, Response $response)
if (!PrivilegeController::hasPrivilege(['privilegeId' => 'sendmail', 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
}
$isSent = EmailController::createEmail(['userId' => $GLOBALS['id'], 'data' => $body]);
$httpCode = empty($isSent['code']) ? 400 : $isSent['code'];
return $response->withStatus($httpCode)->withJson(['errors' => $isSent['errors']]);
return $response->withJson(['id' => $isSent]);
}
public static function createEmail(array $args)
{
ValidatorModel::notEmpty($args, ['userId', 'data']);
ValidatorModel::intVal($args, ['userId']);
$check = EmailController::controlCreateEmail(['userId' => $args['userId'], 'data' => $args['data']]);
if (!empty($check['errors'])) {
return ['errors' => $check['errors'], 'code' => $check['code']];
}
'sender' => empty($args['data']['sender']) ? '{}' : json_encode($args['data']['sender']),
'recipients' => empty($args['data']['recipients']) ? '[]' : json_encode($args['data']['recipients']),
'cc' => empty($args['data']['cc']) ? '[]' : json_encode($args['data']['cc']),
'cci' => empty($args['data']['cci']) ? '[]' : json_encode($args['data']['cci']),
'object' => empty($args['data']['object']) ? null : $args['data']['object'],
'body' => empty($args['data']['body']) ? null : $args['data']['body'],
'document' => empty($args['data']['document']) ? null : json_encode($args['data']['document']),
'isHtml' => $args['data']['isHtml'] ? 'true' : 'false',
'status' => $args['data']['status'] == 'DRAFT' ? 'DRAFT' : 'WAITING',
'messageExchangeId' => empty($args['data']['messageExchangeId']) ? null : $args['data']['messageExchangeId']
if ($args['data']['status'] == 'EXPRESS') {
$isSent = EmailController::sendEmail(['emailId' => $id, 'userId' => $args['userId']]);
if (!empty($isSent['success'])) {
EmailModel::update(['set' => ['status' => 'SENT', 'send_date' => 'CURRENT_TIMESTAMP'], 'where' => ['id = ?'], 'data' => [$id]]);
} else {
EmailModel::update(['set' => ['status' => 'ERROR', 'send_date' => 'CURRENT_TIMESTAMP'], 'where' => ['id = ?'], 'data' => [$id]]);
$customId = CoreConfigModel::getCustomId();
if (empty($customId)) {
$customId = 'null';
}
$encryptKey = CoreConfigModel::getEncryptKey();
$options = empty($args['options']) ? '' : serialize($args['options']);
exec("php src/app/email/scripts/sendEmail.php {$customId} {$id} {$args['userId']} '{$encryptKey}' '{$options}' > /dev/null &");
}
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
if (!empty($isSent)) {
HistoryController::add([
'tableName' => 'emails',
'recordId' => $id,
'eventType' => 'ADD',
'eventId' => 'emailCreation',
'info' => _EMAIL_ADDED
]);
if (!empty($args['data']['document']['id'])) {
HistoryController::add([
'tableName' => 'res_letterbox',
'recordId' => $args['data']['document']['id'],
'eventType' => 'ADD',
'eventId' => 'emailCreation',
'info' => _EMAIL_ADDED
]);
}
}
} else {
HistoryController::add([
'tableName' => 'emails',
'recordId' => $id,
'eventType' => 'ADD',
'eventId' => 'emailDraftCreation',
'info' => _EMAIL_DRAFT_SAVED
]);
if (!empty($args['data']['document']['id'])) {
HistoryController::add([
'tableName' => 'res_letterbox',
'recordId' => $args['data']['document']['id'],
'eventType' => 'ADD',
'eventId' => 'emailDraftCreation',
'info' => _EMAIL_DRAFT_SAVED
]);
}
if (!empty($isSent['errors'])) {
return $isSent;
}
return $id;
public function getById(Request $request, Response $response, array $args)
$rawEmail = EmailModel::getById(['id' => $args['id']]);
$document = json_decode($rawEmail['document'], true);
if (!empty($document['id']) && !ResController::hasRightByResId(['resId' => [$document['id']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
Guillaume Heurtier
committed
$sender = json_decode($rawEmail['sender'], true);
$entityLabel = null;
if (!empty($sender['entityId'])) {
$entityLabel = EntityModel::getById(['select' => ['entity_label'], 'id' => $sender['entityId']]);
$entityLabel = $entityLabel['entity_label'];
}
$sender['label'] = $entityLabel;
$email = [
'id' => $rawEmail['id'],
Guillaume Heurtier
committed
'sender' => $sender,
'recipients' => json_decode($rawEmail['recipients'], true),
'cc' => json_decode($rawEmail['cc'], true),
'cci' => json_decode($rawEmail['cci'], true),
'userId' => $rawEmail['user_id'],
'object' => $rawEmail['object'],
'body' => $rawEmail['body'],
'isHtml' => $rawEmail['is_html'],
'status' => $rawEmail['status'],
'creationDate' => $rawEmail['creation_date'],
'sendDate' => $rawEmail['send_date'],
'document' => $document
];
return $response->withJson($email);
public function update(Request $request, Response $response, array $args)
$body = $request->getParsedBody();
$check = EmailController::controlCreateEmail(['userId' => $GLOBALS['id'], 'data' => $body]);
return $response->withStatus($check['code'])->withJson(['errors' => $check['errors']]);
'sender' => empty($body['sender']) ? '{}' : json_encode($body['sender']),
'recipients' => empty($body['recipients']) ? '[]' : json_encode($body['recipients']),
'cc' => empty($body['cc']) ? '[]' : json_encode($body['cc']),
'cci' => empty($body['cci']) ? '[]' : json_encode($body['cci']),
'object' => empty($body['object']) ? null : $body['object'],
'body' => empty($body['body']) ? null : $body['body'],
'document' => empty($body['document']) ? null : json_encode($body['document']),
'is_html' => $body['isHtml'] ? 'true' : 'false',
'status' => $body['status'] == 'DRAFT' ? 'DRAFT' : 'WAITING'
if ($body['status'] != 'DRAFT') {
$customId = CoreConfigModel::getCustomId();
if (empty($customId)) {
$customId = 'null';
}
$encryptKey = CoreConfigModel::getEncryptKey();
exec("php src/app/email/scripts/sendEmail.php {$customId} {$args['id']} {$GLOBALS['id']} '{$encryptKey}' > /dev/null &");
HistoryController::add([
'tableName' => 'emails',
'recordId' => $args['id'],
'eventType' => 'ADD',
'eventId' => 'emailCreation',
'info' => _EMAIL_ADDED
]);
if (!empty($args['data']['document']['id'])) {
HistoryController::add([
'tableName' => 'res_letterbox',
'recordId' => $args['data']['document']['id'],
'eventType' => 'ADD',
'eventId' => 'emailCreation',
'info' => _EMAIL_ADDED
]);
}
} else {
HistoryController::add([
'tableName' => 'emails',
'recordId' => $args['id'],
'eventType' => 'UP',
'eventId' => 'emailModification',
'info' => _EMAIL_UPDATED
]);
if (!empty($args['data']['document']['id'])) {
HistoryController::add([
'tableName' => 'res_letterbox',
'recordId' => $args['data']['document']['id'],
'eventType' => 'UP',
'eventId' => 'emailModification',
'info' => _EMAIL_UPDATED
]);
}
}
return $response->withStatus(204);
}
public function delete(Request $request, Response $response, array $args)
{
$email = EmailModel::getById(['select' => ['user_id', 'document'], 'id' => $args['id']]);
if (empty($email)) {
return $response->withStatus(400)->withJson(['errors' => 'Email does not exist']);
}
if ($email['user_id'] != $GLOBALS['id']) {
return $response->withStatus(403)->withJson(['errors' => 'Email out of perimeter']);
}
EmailModel::delete([
'where' => ['id = ?'],
'data' => [$args['id']]
]);
HistoryController::add([
'tableName' => 'emails',
'recordId' => $args['id'],
'eventType' => 'DEL',
'eventId' => 'emailDeletion',
'info' => _EMAIL_REMOVED
]);
if (!empty($email['document'])) {
$document = json_decode($email['document'], true);
HistoryController::add([
'tableName' => 'res_letterbox',
'recordId' => $document['id'],
'eventType' => 'DEL',
'eventId' => 'emailDeletion',
'info' => _EMAIL_REMOVED
]);
}
return $response->withStatus(204);
}
public function getByResId(Request $request, Response $response, array $args)
{
if (!Validator::intVal()->validate($args['resId']) || !ResController::hasRightByResId(['resId' => [$args['resId']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);

Florian Azizian
committed
$queryParams = $request->getQueryParams();
if (!empty($queryParams['limit']) && !Validator::intVal()->validate($queryParams['limit'])) {
return $response->withStatus(400)->withJson(['errors' => 'Query limit is not an int value']);

Florian Azizian
committed
}
$where = ["document->>'id' = ?", "(status != 'DRAFT' or (status = 'DRAFT' and user_id = ?))"];
if (!empty($queryParams['type'])) {
if (!Validator::stringType()->validate($queryParams['type'])) {
return $response->withStatus(400)->withJson(['errors' => 'Query type is not a string value']);
}
if ($queryParams['type'] == 'ar') {
$where[] = "object LIKE '[AR]%'";
} elseif ($queryParams['type'] == 'm2m') {
$where[] = 'message_exchange_id is not null';
} elseif ($queryParams['type'] == 'email') {
$where[] = "(object NOT LIKE '[AR]%' OR object is null)";
$where[] = 'message_exchange_id is null';
}
}
$emails = EmailModel::get([
'select' => ['*'],
'where' => $where,
'data' => [$args['resId'], $GLOBALS['id']],
'limit' => (int)$queryParams['limit']
]);
foreach ($emails as $key => $email) {
$emails[$key]['sender'] = json_decode($emails[$key]['sender']);
$emails[$key]['recipients'] = json_decode($emails[$key]['recipients']);
$emails[$key]['cc'] = json_decode($emails[$key]['cc']);
$emails[$key]['cci'] = json_decode($emails[$key]['cci']);
$emails[$key]['document'] = json_decode($emails[$key]['document']);
return $response->withJson(['emails' => $emails]);
public function getAvailableEmails(Request $request, Response $response)
$availableEmails = EmailController::getAvailableEmailsByUserId(['userId' => $GLOBALS['id']]);
return $response->withJson(['emails' => $availableEmails]);
public function getInitializationByResId(Request $request, Response $response, array $args)
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
{
if (!Validator::intVal()->validate($args['resId']) || !ResController::hasRightByResId(['resId' => [$args['resId']], 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
}
$resource = ResModel::getById(['select' => ['filename', 'version', 'alt_identifier', 'subject', 'typist', 'format', 'filesize'], 'resId' => $args['resId']]);
if (empty($resource)) {
return $response->withStatus(400)->withJson(['errors' => 'Document does not exist']);
}
$document = [];
if (!empty($resource['filename'])) {
$convertedResource = AdrModel::getDocuments([
'select' => ['docserver_id', 'path', 'filename'],
'where' => ['res_id = ?', 'type in (?)', 'version = ?'],
'data' => [$args['resId'], ['PDF', 'SIGN'], $resource['version']],
'orderBy' => ["type='SIGN' DESC"],
'limit' => 1
]);
$convertedDocument = null;
if (!empty($convertedResource[0])) {
$docserver = DocserverModel::getByDocserverId(['docserverId' => $convertedResource[0]['docserver_id'], 'select' => ['path_template']]);
$pathToDocument = $docserver['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $convertedResource[0]['path']) . $convertedResource[0]['filename'];
if (file_exists($pathToDocument)) {
$convertedDocument = [
'size' => StoreController::getFormattedSizeFromBytes(['size' => filesize($pathToDocument)])
];
}
}
$document = [
'id' => $args['resId'],
'chrono' => $resource['alt_identifier'],
'label' => $resource['subject'],
'convertedDocument' => $convertedDocument,
'creator' => UserModel::getLabelledUserById(['id' => $resource['typist']]),
'format' => $resource['format'],
'size' => StoreController::getFormattedSizeFromBytes(['size' => $resource['filesize']])
];
}
$attachments = [];
$attachmentTypes = AttachmentModel::getAttachmentsTypesByXML();
$rawAttachments = AttachmentModel::get([
'select' => ['res_id', 'title', 'identifier', 'attachment_type', 'typist', 'format', 'filesize', 'status'],
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
'where' => ['res_id_master = ?', 'attachment_type not in (?)', 'status not in (?)'],
'data' => [$args['resId'], ['signed_response'], ['DEL', 'OBS']]
]);
foreach ($rawAttachments as $attachment) {
$attachmentId = $attachment['res_id'];
$signedAttachment = AttachmentModel::get([
'select' => ['res_id'],
'where' => ['origin = ?', 'status != ?', 'attachment_type = ?'],
'data' => ["{$attachment['resId']},res_attachments", 'DEL', 'signed_response']
]);
if (!empty($signedAttachment[0])) {
$attachmentId = $signedAttachment[0]['res_id'];
}
$convertedAttachment = AdrModel::getAttachments([
'select' => ['docserver_id', 'path', 'filename'],
'where' => ['res_id = ?', 'type = ?'],
'data' => [$attachmentId, 'PDF'],
]);
$convertedDocument = null;
if (!empty($convertedAttachment[0])) {
$docserver = DocserverModel::getByDocserverId(['docserverId' => $convertedAttachment[0]['docserver_id'], 'select' => ['path_template']]);
$pathToDocument = $docserver['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $convertedAttachment[0]['path']) . $convertedAttachment[0]['filename'];
if (file_exists($pathToDocument)) {
$convertedDocument = [
'size' => StoreController::getFormattedSizeFromBytes(['size' => filesize($pathToDocument)])
];
}
}
$attachments[] = [
'id' => $attachment['res_id'],
'chrono' => $attachment['identifier'],
'label' => $attachment['title'],
'typeLabel' => $attachmentTypes[$attachment['attachment_type']]['label'],
'attachInMail' => $attachmentTypes[$attachment['attachment_type']]['attachInMail'],
'convertedDocument' => $convertedDocument,
'creator' => UserModel::getLabelledUserById(['id' => $attachment['typist']]),
'format' => $attachment['format'],
'size' => StoreController::getFormattedSizeFromBytes(['size' => $attachment['filesize']]),
'status' => $attachment['status']
$userEntities = EntityModel::getByUserId(['userId' => $GLOBALS['id'], 'select' => ['entity_id']]);
$userEntities = array_column($userEntities, 'entity_id');
$rawNotes = NoteModel::get(['select' => ['id', 'note_text', 'user_id'], 'where' => ['identifier = ?'], 'data' => [$args['resId']]]);
foreach ($rawNotes as $rawNote) {
$allowed = false;
if ($rawNote['user_id'] == $GLOBALS['id']) {
$allowed = true;
} else {
$noteEntities = NoteEntityModel::get(['select' => ['item_id'], 'where' => ['note_id = ?'], 'data' => [$rawNote['id']]]);
if (!empty($noteEntities)) {
foreach ($noteEntities as $noteEntity) {
if (in_array($noteEntity['item_id'], $userEntities)) {
$allowed = true;
break;
}
}
} else {
$allowed = true;
}
}
if ($allowed) {
$notes[] = [
'id' => $rawNote['id'],
'label' => $rawNote['note_text'],
'creator' => UserModel::getLabelledUserById(['id' => $rawNote['user_id']]),
'size' => null
];
}
}
return $response->withJson(['resource' => $document, 'attachments' => $attachments, 'notes' => $notes]);
}
public static function sendEmail(array $args)
ValidatorModel::notEmpty($args, ['emailId', 'userId']);
ValidatorModel::intVal($args, ['emailId', 'userId']);
$email = EmailModel::getById(['id' => $args['emailId']]);
$email['sender'] = json_decode($email['sender'], true);
$email['recipients'] = array_unique(json_decode($email['recipients']));
$email['cc'] = array_unique(json_decode($email['cc']));
$email['cci'] = array_unique(json_decode($email['cci']));
$hierarchyMail = ['cci' => ['recipients', 'cc'], 'cc' => ['recipients']];
foreach ($hierarchyMail as $lowEmail => $ahighEmail) {
foreach ($ahighEmail as $highEmail) {
foreach ($email[$lowEmail] as $currentKey => $currentEmail) {
if (in_array($currentEmail, $email[$highEmail])) {
unset($email[$lowEmail][$currentKey]);
}
$configuration = ConfigurationModel::getByService(['service' => 'admin_email_server', 'select' => ['value']]);
$configuration = json_decode($configuration['value'], true);
if (empty($configuration)) {
return ['errors' => 'Configuration is missing'];
}
$user = UserModel::getById(['id' => $args['userId'], 'select' => ['firstname', 'lastname', 'user_id']]);

Florian Azizian
committed
$emailFrom = empty($configuration['from']) ? $email['sender']['email'] : $configuration['from'];
if (empty($email['sender']['entityId'])) {
// Usefull for old sendmail server which doesn't support accent encoding
$setFrom = TextFormatModel::normalize(['string' => "{$user['firstname']} {$user['lastname']}"]);
$phpmailer->setFrom($emailFrom, ucwords($setFrom));
} else {
$entity = EntityModel::getById(['id' => $email['sender']['entityId'], 'select' => ['short_label']]);
// Usefull for old sendmail server which doesn't support accent encoding
$setFrom = TextFormatModel::normalize(['string' => $entity['short_label']]);
$phpmailer->setFrom($emailFrom, ucwords($setFrom));
}
if (in_array($configuration['type'], ['smtp', 'mail'])) {
if ($configuration['type'] == 'smtp') {
$phpmailer->isSMTP();
} elseif ($configuration['type'] == 'mail') {
$phpmailer->isMail();
}
$phpmailer->Host = $configuration['host'];
$phpmailer->Port = $configuration['port'];
$phpmailer->SMTPAutoTLS = false;
if (!empty($configuration['secure'])) {
$phpmailer->SMTPSecure = $configuration['secure'];
}
$phpmailer->SMTPAuth = $configuration['auth'];
if ($configuration['auth']) {
$phpmailer->Username = $configuration['user'];
if (!empty($configuration['password'])) {
$phpmailer->Password = PasswordModel::decrypt(['cryptedPassword' => $configuration['password']]);
}
} elseif ($configuration['type'] == 'sendmail') {
$phpmailer->isSendmail();
} elseif ($configuration['type'] == 'qmail') {
$phpmailer->isQmail();
$phpmailer->addReplyTo($email['sender']['email']);
$phpmailer->CharSet = $configuration['charset'];
foreach ($email['recipients'] as $recipient) {
$phpmailer->addAddress($recipient);
}
foreach ($email['cc'] as $recipient) {
$phpmailer->addCC($recipient);
}
foreach ($email['cci'] as $recipient) {
$phpmailer->addBCC($recipient);
}
if ($email['is_html']) {
$phpmailer->isHTML(true);
$internalErrors = libxml_use_internal_errors(true);
$dom->loadHTML($email['body'], LIBXML_NOWARNING);
$images = $dom->getElementsByTagName('img');
foreach ($images as $key => $image) {
$originalSrc = $image->getAttribute('src');
if (preg_match('/^data:image\/(\w+);base64,/', $originalSrc)) {
$encodedImage = substr($originalSrc, strpos($originalSrc, ',') + 1);
$imageFormat = substr($originalSrc, 11, strpos($originalSrc, ';') - 11);
$phpmailer->addStringEmbeddedImage(base64_decode($encodedImage), "embeded{$key}", "embeded{$key}.{$imageFormat}");
$email['body'] = str_replace($originalSrc, "cid:embeded{$key}", $email['body']);
}
}
$phpmailer->Subject = $email['object'];
$phpmailer->Body = $email['body'];
if (empty($email['body'])) {
$phpmailer->AllowEmpty = true;
}
//zip M2M
if ($email['message_exchange_id']) {
$messageExchange = MessageExchangeModel::getMessageByIdentifier(['messageId' => $email['message_exchange_id'], 'select' => ['docserver_id','path','filename','fingerprint','reference']]);

Florian Azizian
committed
$docserver = DocserverModel::getByDocserverId(['docserverId' => $messageExchange['docserver_id']]);
$docserverType = DocserverTypeModel::getById(['id' => $docserver['docserver_type_id']]);

Florian Azizian
committed
$pathDirectory = str_replace('#', DIRECTORY_SEPARATOR, $messageExchange['path']);
$filePath = $docserver['path_template'] . $pathDirectory . $messageExchange['filename'];
$fingerprint = StoreController::getFingerPrint([
'filePath' => $filePath,
'mode' => $docserverType['fingerprint_mode'],
]);

Florian Azizian
committed
if ($fingerprint != $messageExchange['fingerprint']) {
$email['document'] = json_decode($email['document'], true);
return ['errors' => 'Pb with fingerprint of document. ResId master : ' . $email['document']['id']];
}
if (is_file($filePath)) {
$fileContent = file_get_contents($filePath);
if ($fileContent === false) {
return ['errors' => 'Document not found on docserver'];

Florian Azizian
committed
$title = preg_replace(utf8_decode('@[\\/:*?"<>|]@i'), '_', substr($messageExchange['reference'], 0, 30));
$phpmailer->addStringAttachment($fileContent, $title . '.zip');
$email['document'] = json_decode($email['document'], true);
if ($email['document']['isLinked']) {
$encodedDocument = ResController::getEncodedDocument(['resId' => $email['document']['id'], 'original' => $email['document']['original']]);
if (empty($encodedDocument['errors'])) {
$phpmailer->addStringAttachment(base64_decode($encodedDocument['encodedDocument']), $encodedDocument['fileName']);
}
}
if (!empty($email['document']['attachments'])) {
foreach ($email['document']['attachments'] as $attachment) {
$encodedDocument = AttachmentController::getEncodedDocument(['id' => $attachment['id'], 'original' => $attachment['original']]);
if (empty($encodedDocument['errors'])) {
$phpmailer->addStringAttachment(base64_decode($encodedDocument['encodedDocument']), $encodedDocument['fileName']);
}
}
}
if (!empty($email['document']['notes'])) {
$encodedDocument = NoteController::getEncodedPdfByIds(['ids' => $email['document']['notes']]);
if (empty($encodedDocument['errors'])) {
$phpmailer->addStringAttachment(base64_decode($encodedDocument['encodedDocument']), 'notes.pdf');
}
$phpmailer->Timeout = 30;
$phpmailer->SMTPDebug = 1;
$phpmailer->Debugoutput = function ($str) {
if (strpos($str, 'SMTP ERROR') !== false) {
HistoryController::add([
'tableName' => 'emails',
'recordId' => 'email',
'eventType' => 'ERROR',
'eventId' => 'sendEmail',
'info' => $str
]);
}
};
$history = HistoryModel::get([
'select' => ['info'],
'where' => ['user_id = ?', 'event_id = ?', 'event_type = ?'],
'data' => [$args['userId'], 'sendEmail', 'ERROR'],
'orderBy' => ['event_date DESC'],
'limit' => 1
]);
if (!empty($history[0]['info'])) {
return ['errors' => $history[0]['info']];
}
return ['errors' => $phpmailer->ErrorInfo];
Guillaume Heurtier
committed
public static function getAvailableEmailsByUserId(array $args)
{
$currentUser = UserModel::getById(['select' => ['firstname', 'lastname', 'mail', 'user_id'], 'id' => $args['userId']]);
$availableEmails = [
[
'entityId' => null,
'label' => $currentUser['firstname'] . ' ' . $currentUser['lastname'],
'email' => $currentUser['mail']
]
];
if (PrivilegeController::hasPrivilege(['privilegeId' => 'use_mail_services', 'userId' => $args['userId']])) {
$entities = EntityModel::getWithUserEntities([
'select' => ['entities.entity_label', 'entities.email', 'entities.entity_id', 'entities.id'],
'where' => ['users_entities.user_id = ?'],
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
]);
foreach ($entities as $entity) {
if (!empty($entity['email'])) {
$availableEmails[] = [
'entityId' => $entity['id'],
'label' => $entity['entity_label'],
'email' => $entity['email']
];
}
}
$emailsEntities = CoreConfigModel::getXmlLoaded(['path' => 'modules/sendmail/xml/externalMailsEntities.xml']);
if (!empty($emailsEntities)) {
$userEntities = array_column($entities, 'entity_id');
foreach ($emailsEntities->externalEntityMail as $entityMail) {
$entityId = (string)$entityMail->targetEntityId;
if (empty($entityId)) {
$availableEmails[] = [
'entityId' => null,
'label' => (string)$entityMail->defaultName,
'email' => trim((string)$entityMail->EntityMail)
];
} elseif (in_array($entityId, $userEntities)) {
$entity = EntityModel::getByEntityId([
'select' => ['entity_label', 'id'],
'entityId' => $entityId
]);
if (!empty($entity)) {
$availableEmails[] = [
'entityId' => $entity['id'],
'label' => $entity['entity_label'],
'email' => trim((string)$entityMail->EntityMail)
];
}
}
}
}
}
return $availableEmails;
}
private static function controlCreateEmail(array $args)
{
ValidatorModel::notEmpty($args, ['userId']);
ValidatorModel::intVal($args, ['userId']);
if (!Validator::stringType()->notEmpty()->validate($args['data']['status'])) {
return ['errors' => 'Data status is not a string or empty', 'code' => 400];
} elseif ($args['data']['status'] != 'DRAFT' && (!Validator::arrayType()->notEmpty()->validate($args['data']['sender']) || !Validator::stringType()->notEmpty()->validate($args['data']['sender']['email']))) {
return ['errors' => 'Data sender email is not set', 'code' => 400];
} elseif ($args['data']['status'] != 'DRAFT' && !Validator::arrayType()->notEmpty()->validate($args['data']['recipients'])) {
return ['errors' => 'Data recipients is not an array or empty', 'code' => 400];
} elseif (!Validator::boolType()->validate($args['data']['isHtml'])) {
return ['errors' => 'Data isHtml is not a boolean or empty', 'code' => 400];
}
if (!empty($args['data']['sender']['email'])) {
$configuration = ConfigurationModel::getByService(['service' => 'admin_email_server', 'select' => ['value']]);
$configuration = json_decode($configuration['value'], true);
$availableEmails = EmailController::getAvailableEmailsByUserId(['userId' => $args['userId']]);
$emails = array_column($availableEmails, 'email');
if (!empty($configuration['from'])) {
$emails[] = $configuration['from'];
}
if (!in_array($args['data']['sender']['email'], $emails)) {
return ['errors' => 'Data sender email is not allowed', 'code' => 400];
}
if (!empty($args['data']['sender']['entityId'])) {
$entities = array_column($availableEmails, 'entityId');
if (!in_array($args['data']['sender']['entityId'], $entities)) {
return ['errors' => 'Data sender entityId is not allowed', 'code' => 400];
}
}
}
if (!empty($args['data']['document'] && !empty($args['data']['document']['id']))) {
$check = Validator::intVal()->notEmpty()->validate($args['data']['document']['id']);
$check = $check && Validator::boolType()->validate($args['data']['document']['isLinked']);
$check = $check && Validator::boolType()->validate($args['data']['document']['original']);
if (!$check) {
return ['errors' => 'Data document errors', 'code' => 400];
}
if (!ResController::hasRightByResId(['resId' => [$args['data']['document']['id']], 'userId' => $args['userId']])) {
return ['errors' => 'Document out of perimeter', 'code' => 403];
}
if (!empty($args['data']['document']['attachments'])) {
if (!is_array($args['data']['document']['attachments'])) {
return ['errors' => 'Data document[attachments] is not an array', 'code' => 400];
}
foreach ($args['data']['document']['attachments'] as $attachment) {
$check = Validator::intVal()->notEmpty()->validate($attachment['id']);
$check = $check && Validator::boolType()->validate($attachment['original']);
if (!$check) {
return ['errors' => 'Data document[attachments] errors', 'code' => 400];
}
$checkAttachment = AttachmentModel::getById(['id' => $attachment['id'], 'select' => ['res_id_master']]);
if (empty($checkAttachment) || $checkAttachment['res_id_master'] != $args['data']['document']['id']) {
return ['errors' => 'Attachment out of perimeter', 'code' => 403];
}
}
}
if (!empty($args['data']['document']['notes'])) {
if (!is_array($args['data']['document']['notes'])) {
return ['errors' => 'Data document[notes] is not an array', 'code' => 400];
}
foreach ($args['data']['document']['notes'] as $note) {
if (!Validator::intVal()->notEmpty()->validate($note)) {
return ['errors' => 'Data document[notes] errors', 'code' => 400];
}
$checkNote = NoteModel::getById(['id' => $note, 'select' => ['identifier', 'user_id']]);
if (empty($checkNote) || $checkNote['identifier'] != $args['data']['document']['id']) {
return ['errors' => 'Note out of perimeter', 'code' => 403];
} elseif ($checkNote['user_id'] == $args['userId']) {
continue;
$rawUserEntities = EntityModel::getByUserId(['userId' => $args['userId'], 'select' => ['entity_id']]);
$userEntities = [];
foreach ($rawUserEntities as $rawUserEntity) {
$userEntities[] = $rawUserEntity['entity_id'];
}
$noteEntities = NoteEntityModel::get(['select' => ['item_id'], 'where' => ['note_id = ?'], 'data' => [$note]]);
if (!empty($noteEntities)) {
$found = false;
foreach ($noteEntities as $noteEntity) {
if (in_array($noteEntity['item_id'], $userEntities)) {
$found = true;
}
}
if (!$found) {
return ['errors' => 'Note out of perimeter', 'code' => 403];
}
}
}
}