Skip to content
Snippets Groups Projects
Select Git revision
  • b1f13ce8299d581ccb889e2d98e13574bffcc5ba
  • main default protected
  • step-3263
  • feature/plugins-cli
  • feature/vite
  • step-2484-peerreview
  • biest/issue-5051
  • tests/simplify-jsonapi-tests
  • fix/typo-in-1a70031
  • feature/broadcasting
  • database-seeders-and-factories
  • feature/peer-review-2
  • feature-feedback-jsonapi
  • feature/peerreview
  • feature/balloon-plus
  • feature/stock-images-unsplash
  • tic-2588
  • 5.0
  • 5.2
  • biest/unlock-blocks
  • biest-1514
21 results

CronJob.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    MailQueueEntry.class.php 4.85 KiB
    <?php
    
    /*
     *  Copyright (c) 2013  Rasmus Fuhse <fuhse@data-quest.de>
     *
     *  This program is free software; you can redistribute it and/or
     *  modify it under the terms of the GNU General Public License as
     *  published by the Free Software Foundation; either version 2 of
     *  the License, or (at your option) any later version.
     */
    
    /**
     * Class to handle entries in the mail-queue in Stud.IP.
     * Use MailQueueEntry::add($mail, $message_id, $user_id) to add a mail to the queue
     * and MailQueueEntry::sendAll() or MailQueueEntry::sendNew() to flush the queue
     * and send the mails.
     *
     * @property string $id alias column for mail_queue_id
     * @property string $mail_queue_id database column
     * @property JSONArrayObject $mail database column
     * @property string|null $message_id database column
     * @property string|null $user_id database column
     * @property int $tries database column
     * @property int $last_try database column
     * @property int $mkdate database column
     * @property int $chdate database column
     */
    class MailQueueEntry extends SimpleORMap
    {
        protected static function configure($config = [])
        {
            $config['db_table'] = 'mail_queue_entries';
    
            $config['serialized_fields']['mail'] = JSONArrayObject::class;
    
            parent::configure($config);
        }
    
        /**
         * Add an email to the queue.
         * @param StudipMail $mail : the mailobject that should be added and sent later.
         * @param string|null $message_id : the id of the Stud.IP internal message the
         * mail is related to. Leave this null if it isn't related to any internal message.
         * @param string|null $user_id : user_id of the receiver. Leave null if the
         * receiver has no account in Stud.IP.
         * @return MailQueueEntry : object in the mailqueue.
         */
        public static function add(StudipMail $mail, $message_id = null, $user_id = null)
        {
            $queue_entry = new self();
            $queue_entry['mail'] = $mail->toArray();
            $queue_entry['message_id'] = $message_id;
            $queue_entry['user_id'] = $user_id;
            $queue_entry['tries'] = 0;
            $queue_entry->store();
    
            return $queue_entry;
        }
    
        /**
         * Sends all new mails in the mailqueue (which means they haven't been sent yet).
         */
        public static function sendNew()
        {
            self::findEachBySQL(function ($m) {
                $m->send();
            }, "tries = 0 ORDER BY mkdate");
        }
    
        /**
         * Sends all mails in the mailqueue. Stud.IP will give each mail 24 tries to
         * deliver it. If the mail could not be sent after 24 tries (which are 24
         * hours) it will stay in the mailqueue table but won't be sent anymore.
         * Each mail will only be tried to deliver once per hour. So if it fails
         * Stud.IP will try again next hour.
         *
         * @param int $limit The maximum amount of messages to be sent.
         * @return array An empty array if no status messages are output
         *     or an array with status messages, one for each mail.
         */
        public static function sendAll($limit = null)
        {
            //The status messages will be returned
            $status_messages = [];
    
            self::findEachBySQL(function ($m) use (&$status_messages) {
                // Reconstruct the StudipMail object
                $mail = new StudipMail($m->mail);
                $status_message = sprintf(
                    'sending message %1$s (sender: %2$s, %3$u recipient(s))...',
                    $m->message_id,
                    $mail->getSenderEmail(),
                    count($mail->getRecipients())
                );
    
                $was_sent = $m->send();
                $status_message .= $was_sent ? 'DONE' : 'FAILURE';
    
                if ($m->tries > 0) {
                    // If sending the message has failed at least once
                    // we add the amount of tries to the status message.
                    $status_message .= "(t={$m->tries})";
                }
    
                $status_messages[] = $status_message;
            }, "tries = 0 " .
               "OR (last_try > (UNIX_TIMESTAMP() - 60 * 60) AND tries < 25) ORDER BY mkdate".
               ($limit > 0 ? " LIMIT ". (int) $limit : "")
            );
    
            return $status_messages;
        }
    
        /**
         * Sends the object in the mailqueue. If this succeeds, the object will be
         * deleted immediately. Otherwise the field "tries" in the mailqueue table
         * will be incremented by one.
         *
         * @return bool True, if the mail in the mailqueue entry could be sent,
         *     false otherwise.
         */
        public function send()
        {
            $mail = new StudipMail($this->mail);
    
            if ($mail->getRecipients()) {
                $success = $mail->send();
                if ($success) {
                    $this->delete();
                } else {
                    $this['tries'] = $this['tries'] + 1;
                    $this['last_try'] = time();
                    $this->store();
                }
            } else {
                $success = false;
                $this->delete();
            }
            return $success;
        }
    }