Skip to content
Snippets Groups Projects
scheduler.php 8.3 KiB
Newer Older
use Configuration\models\ConfigurationModel;
use Document\models\DocumentModel;
use Email\controllers\EmailController;
use History\controllers\HistoryController;
use Notification\models\NotificationsScheduleModel;
use Notification\models\NotificationStackModel;
use SrcCore\controllers\LanguageController;
use SrcCore\models\DatabasePDO;
use SrcCore\models\ValidatorModel;
use User\models\UserModel;

require './vendor/autoload.php';

$configPath = $argv[1];

DatabasePDO::reset();
new DatabasePDO(['configPath' => $configPath]);

$configuration = ConfigurationModel::getByIdentifier(['identifier' => 'customization']);
$configuration = $configuration[0];
$configuration['value'] = json_decode($configuration['value'], true);
$applicationUrl = $configuration['value']['applicationUrl'];
$GLOBALS['id'] = 0;
$GLOBALS['webhook'] = 'SCHEDULER';

if (empty($applicationUrl)) {
    HistoryController::add([
        'code'       => 'KO',
        'objectType' => 'configurations',
        'objectId'   => $configuration['id'],
        'type'       => 'ERROR',
        'message'    => "{scheduler} :  {noApplicationUrlDefined}"
    echo "Cannot run scheduler : no applicationUrl defined\n";
    exit(1);
}
$restUser = UserModel::get(['select' => ['id'], 'where' => ['"isRest" = ?'], 'data' => ['true']]);
if (empty($restUser[0])) {
    HistoryController::add([
        'code'       => 'KO',
        'objectType' => 'configurations',
        'objectId'   => $configuration['id'],
        'type'       => 'ERROR',
        'message'    => "{scheduler} : {noRestUserFound}"
    echo "Cannot run scheduler :  no rest user found\n";
    exit(1);
}
$restUser = $restUser[0];
$GLOBALS['id'] = $restUser['id'];

$schedules = NotificationsScheduleModel::get();

$currentDate = new DateTime();

foreach ($schedules as $schedule) {
    if ($schedule['status'] != 'READY') {
        continue;
    }

    $currentMonth = $currentDate->format('n');
    $schedule['months'] = json_decode($schedule['months']);
    if (!empty($schedule['months']) && !in_array($currentMonth, $schedule['months']) && $schedule['months'][0] != '*') {
        continue;
    }

    $currentDayOfMonth = $currentDate->format('j');
    $schedule['days_of_month'] = json_decode($schedule['days_of_month']);
    if (!empty($schedule['days_of_month']) && !in_array($currentDayOfMonth, $schedule['days_of_month']) && $schedule['days_of_month'][0] != '*') {
        continue;
    }

    $currentDayOfWeek = $currentDate->format('N');
    $schedule['days_of_week'] = json_decode($schedule['days_of_week']);
    if (!empty($schedule['days_of_week']) && !in_array($currentDayOfWeek, $schedule['days_of_week']) && $schedule['days_of_week'][0] != '*') {
        continue;
    }

    $lastExecution = new DateTime($schedule['last_execution']);
    if (!empty($schedule['last_execution'])) {
        $difference = $currentDate->diff($lastExecution);
        if (empty($schedule['frequency']) && $lastExecution->format('Y-m-d') == $currentDate->format('Y-m-d')) {
            continue;
        } elseif (!empty($schedule['frequency']) && $schedule['frequency_mode'] == 'minutes' && $difference->i < $schedule['frequency']) {
            continue;
        } elseif(!empty($schedule['frequency']) && $schedule['frequency_mode'] == 'hours' && $difference->h < $schedule['frequency']) {
            continue;
        }
    }

    $startTime = new DateTime($schedule['start_time']);
    $endTime = new DateTime($schedule['end_time']);

    if ($currentDate < $startTime) {
        continue;
    } elseif (!empty($schedule['frequency']) && $endTime < $currentDate) {
        continue;
    }

    // RUN TASK
    NotificationsScheduleModel::update([
        'set'   => ['status' => 'RUNNING'],
        'where' => ['id = ?'],
        'data'  => [$schedule['id']]
    ]);

    $notificationStack = NotificationStackModel::get([
        'select' => ['*'],
        'where'  => ['type = ?'],
        'data'   => [$schedule['type']]
    ]);

    if (!empty($notificationStack)) {
        sendNotifications([
            'type'            => $schedule['type'],
            'stack'           => $notificationStack,
            'restUser'        => $restUser,
            'applicationUrl'  => $applicationUrl,
            'configurationId' => $configuration['id']
    }

    NotificationsScheduleModel::update([
        'set'   => ['status' => 'READY', 'last_execution' => 'CURRENT_TIMESTAMP'],
        'where' => ['id = ?'],
        'data'  => [$schedule['id']]
    ]);
}

function sendNotifications(array $args)
    ValidatorModel::notEmpty($args, ['stack', 'restUser', 'type', 'applicationUrl']);
    ValidatorModel::arrayType($args, ['stack', 'restUser']);
    ValidatorModel::stringType($args, ['type', 'applicationUrl']);

    $notificationStack = $args['stack'];
    $restUser = $args['restUser'];

    if ($args['type'] == 'next_user') {
        $subjectKey = 'notificationDocumentsAddedSubject';
        $bodyKey = 'notificationDocumentsAddedBody';
    } elseif ($args['type'] == 'typist_END') {
        $subjectKey = 'notificationEndOfWorkflowsSubject';
        $bodyKey = 'notificationEndOfWorkflowsBody';
    } elseif ($args['type'] == 'typist_INT') {
        $subjectKey = 'notificationInterruptsSubject';
        $bodyKey = 'notificationInterruptsBody';
    } elseif ($args['type'] == 'typist_REF') {
        $subjectKey = 'notificationRefusedWorkflowsSubject';
        $bodyKey = 'notificationRefusedWorkflowsBody';
    $recipients = array_unique(array_column($notificationStack, 'recipient_id'));

    foreach ($recipients as $recipientId) {
        $recipientNotifications = array_filter($notificationStack, function ($notification) use ($recipientId) {
            return $notification['recipient_id'] == $recipientId;
        });

        $recipient = UserModel::getById(['id' => $recipientId, 'select' => ['email', 'preferences']]);
        $recipient['preferences'] = json_decode($recipient['preferences'], true);
        $lang = LanguageController::get(['lang' => $recipient['preferences']['lang']]);

        $recipientNotificationIds = [];
        foreach ($recipientNotifications as $recipientNotification) {
            $url  = $args['applicationUrl'] . 'dist/#/documents/' . $recipientNotification['main_document_id'];
            $document = DocumentModel::getById(['id' => $recipientNotification['main_document_id'], 'select' => ['title']]);

            $row = str_replace('{{object}}', htmlspecialchars($document['title']), $lang['notificationTemplateRow']);
            $row = str_replace('{{link}}', $url, $row);
            $rows .= $row . "\n";
            $recipientNotificationIds[] = $recipientNotification['id'];
        }

        $emailBody .= str_replace('{{rows}}', $rows, $lang['notificationTemplateTable']);

        $isSent = EmailController::createEmail([
            'userId' => $restUser['id'],
            'data'   => [
                'sender'     => 'Notification',
                'recipients' => [$recipient['email']],
                'subject'    => $lang[$subjectKey],
                'body'       => $emailBody . $lang['notificationFooter'],
                'isHtml'     => true,
                'status'     => 'EXPRESS'

        if (!empty($isSent['errors'])) {
            HistoryController::add([
                'code'       => 'KO',
                'objectType' => 'configurations',
                'objectId'   => $args['configurationId'],
                'type'       => 'ERROR',
                'message'    => "{scheduler} : {sendingSummaryError} : " . $isSent['errors']
            $notificationSent = array_merge($notificationSent, $recipientNotificationIds);
    HistoryController::add([
        'objectType' => 'configurations',
        'objectId'   => $args['configurationId'],
        'type'       => 'ACTION',
        'message'    => "{scheduler} : $nbEmailSent {summariesSent} {notification_{$args['type']}}"
    // Delete only the sent notifications in the stack
    NotificationStackModel::delete([
        'where' => ['id in (?)'],
        'data'  => [$notificationSent]