aboutsummaryrefslogtreecommitdiff
path: root/lib/models/MailQueueEntry.php
diff options
context:
space:
mode:
authorMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2024-06-18 13:18:06 +0000
committerMarcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de>2024-06-18 13:18:06 +0000
commit33fd1358507b4a5abb3dcebe78d407d0567717c1 (patch)
tree6bd8f6959da4c3fc1b8907c0bbc28eb9e10d4a5a /lib/models/MailQueueEntry.php
parent42d46671c0309bddb71a91bbfdc5f2fa2e44384e (diff)
Deprecate `StudipAutoloader` and use composer's `autoload`
Closes #4282 Merge request studip/studip!3099
Diffstat (limited to 'lib/models/MailQueueEntry.php')
-rw-r--r--lib/models/MailQueueEntry.php141
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/models/MailQueueEntry.php b/lib/models/MailQueueEntry.php
new file mode 100644
index 0000000..d0f9685
--- /dev/null
+++ b/lib/models/MailQueueEntry.php
@@ -0,0 +1,141 @@
+<?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 tries, 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;
+ }
+}