aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/StudipMail.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/classes/StudipMail.php')
-rw-r--r--lib/classes/StudipMail.php487
1 files changed, 487 insertions, 0 deletions
diff --git a/lib/classes/StudipMail.php b/lib/classes/StudipMail.php
new file mode 100644
index 0000000..c517847
--- /dev/null
+++ b/lib/classes/StudipMail.php
@@ -0,0 +1,487 @@
+<?php
+/**
+ * StudipMail.php
+ *
+ * class for constructing and sending emails in Stud.IP
+ *
+ *
+ * @author André Noack <noack@data-quest>, Suchi & Berg GmbH <info@data-quest.de>
+ * @version 1
+ * @license GPL2 or any later version
+ * @copyright 2009 authors
+ */
+class StudipMail
+{
+ /**
+ * @var email_message_class
+ * @static
+ */
+ private static $transporter;
+
+ /**
+ * @var string
+ */
+ private $body_text;
+ /**
+ * @var string
+ */
+ private $body_html;
+ /**
+ * @var string
+ */
+ private $subject;
+ /**
+ * Array of all attachments, name ist key
+ * @var array
+ */
+ private $attachments = [];
+ /**
+ * Array of attachments that are related to the content
+ * @var array
+ */
+ private $related_attachments = [];
+ /**
+ * @var array
+ */
+ private $sender;
+ /**
+ * Array of all recipients, mail is key
+ * @var array
+ */
+ private $recipients = [];
+ /**
+ * @var array
+ */
+ private $reply_to;
+
+ /**
+ * Sets the default transporter used in StudipMail::send()
+ * @param email_message_class $transporter
+ * @return void
+ */
+ public static function setDefaultTransporter(email_message_class $transporter)
+ {
+ self::$transporter = $transporter;
+ }
+
+ /**
+ * gets the default transporter used in StudipMail::send()
+ *
+ * @return email_message_class
+ */
+ public static function getDefaultTransporter()
+ {
+ return self::$transporter;
+ }
+
+ /**
+ * Gets the configured abuse mail contact
+ *
+ * @return string
+ */
+ public static function getAbuseEmail()
+ {
+ return $GLOBALS['MAIL_ABUSE'] ?: "abuse@{$mail_localhost}";
+ }
+
+ /**
+ * convenience method for sending a qick, text based email message
+ *
+ * @param string $recipient
+ * @param string $subject
+ * @param string $text Plain text version of the message (required).
+ * @param string $html HTML version of the message (optional).
+ * @return bool
+ */
+ public static function sendMessage($recipient, $subject, $text, $html = null)
+ {
+ $mail = new StudipMail();
+ return $mail->setSubject($subject)
+ ->addRecipient($recipient)
+ ->setBodyText($text)
+ ->setBodyHtml($html)
+ ->send();
+ }
+
+ /**
+ * convenience method for sending a qick, text based email message
+ * to the configured abuse adress
+ *
+ * @param string $subject
+ * @param string $text
+ * @return bool
+ */
+ public static function sendAbuseMessage($subject, $text)
+ {
+ $mail = new StudipMail();
+ $abuse = self::getAbuseEmail();
+ return $mail->setSubject($subject)
+ ->addRecipient($abuse)
+ ->setBodyText($text)
+ ->send();
+ }
+
+ /**
+ * sets some default values for sender and reply to from
+ * configuration settings.
+ *
+ */
+ public function __construct($data = null)
+ {
+ $mail_localhost = $GLOBALS['MAIL_LOCALHOST'] ?: $_SERVER['SERVER_NAME'];
+ $this->setSenderEmail($GLOBALS['MAIL_ENV_FROM'] ?: "wwwrun@{$mail_localhost}");
+ $this->setSenderName($GLOBALS['MAIL_FROM'] ?: 'Stud.IP - ' . Config::get()->UNI_NAME_CLEAN);
+
+ if ($data) {
+ $this->setData($data);
+ }
+ }
+
+ /**
+ * @param string $mail
+ * @return StudipMail provides fluent interface
+ */
+ public function setSenderEmail($mail)
+ {
+ $this->sender['mail'] = $mail;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSenderEmail()
+ {
+ return $this->sender['mail'];
+ }
+
+ /**
+ * @param string $name
+ * @return StudipMail provides fluent interface
+ */
+ public function setSenderName($name)
+ {
+ $this->sender['name'] = $name;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getSenderName()
+ {
+ return $this->sender['name'];
+ }
+
+ /**
+ * @param $mail
+ * @return StudipMail provides fluent interface
+ */
+ public function setReplyToEmail($mail)
+ {
+ $this->reply_to['mail'] = $mail;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getReplyToEmail()
+ {
+ return $this->reply_to['mail'] ?? '';
+ }
+
+ /**
+ * @param $name
+ * @return StudipMail provides fluent interface
+ */
+ public function setReplyToName($name)
+ {
+ $this->reply_to['name'] = $name;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getReplyToName()
+ {
+ return $this->reply_to['name'] ?? '';
+ }
+
+ /**
+ * @param $subject
+ * @return StudipMail provides fluent interface
+ */
+ public function setSubject($subject)
+ {
+ $this->subject = $subject;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getSubject()
+ {
+ return $this->subject;
+ }
+
+ /**
+ * @param $mail
+ * @param $name
+ * @param $type
+ * @return StudipMail provides fluent interface
+ */
+ public function addRecipient($mail, $name = '', $type = 'To')
+ {
+ $type = ucfirst($type);
+ $type = in_array($type, ['To', 'Cc', 'Bcc']) ? $type : 'To';
+ if (!isset($this->recipients[$mail]) || $this->recipients[$mail]['type'] !== 'To') {
+ $this->recipients[$mail] = compact('mail', 'name', 'type');
+ }
+ return $this;
+ }
+
+ /**
+ * @param $mail
+ * @return StudipMail provides fluent interface
+ */
+ public function removeRecipient($mail)
+ {
+ unset($this->recipients[$mail]);
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getRecipients()
+ {
+ return $this->recipients;
+ }
+
+ /**
+ * @param $mail
+ * @return unknown_type
+ */
+ public function isRecipient($mail)
+ {
+ return isset($this->recipients[$mail]);
+ }
+
+ /**
+ * @param $file_name
+ * @param $name
+ * @param $type
+ * @param $disposition
+ * @return StudipMail provides fluent interface
+ */
+ public function addFileAttachment($file_name, $name = '', $type = 'automatic/name', $disposition = 'attachment')
+ {
+ $name = $name ?: basename($file_name);
+ $this->attachments[$name] = compact('file_name', 'name', 'type', 'disposition');
+ return $this;
+ }
+
+ /**
+ * @param $data
+ * @param $name
+ * @param $type
+ * @param $disposition
+ * @return StudipMail provides fluent interface
+ */
+ public function addDataAttachment($data, $name, $type = 'automatic/name', $disposition = 'attachment')
+ {
+ $this->attachments[$name] = compact('data', 'name', 'type', 'disposition');
+ return $this;
+ }
+
+ /**
+ * @param FileRef $file_ref The FileRef object of a file that shall be added to a mail
+ * @return StudipMail provides fluent interface
+ */
+ public function addStudipAttachment(FileRef $file_ref)
+ {
+ if (!$file_ref->isNew()) {
+ $this->addFileAttachment(
+ $file_ref->file->getPath(),
+ $file_ref->name
+ );
+ }
+ return $this;
+ }
+
+ public function addRelatedAttachment(string $file_name, string $name, string $type, string $content_id): void
+ {
+ $this->related_attachments[$name] = [
+ 'FileName' => $file_name,
+ 'Name' => $name,
+ 'Content-Type' => $type,
+ 'Disposition' => 'inline',
+ 'Content-ID' => $content_id
+ ];
+ }
+
+ /**
+ * @param $name
+ * @return StudipMail provides fluent interface
+ */
+ public function removeAttachment($name)
+ {
+ unset($this->attachments[$name]);
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAttachments()
+ {
+ return $this->attachments;
+ }
+
+ /**
+ * @param $name
+ * @return unknown_type
+ */
+ public function isAttachment($name)
+ {
+ return isset($this->attachments[$name]);
+ }
+
+ /**
+ * @param $body
+ * @return StudipMail provides fluent interface
+ */
+ public function setBodyText($body)
+ {
+ $this->body_text = $body;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getBodyText()
+ {
+ return $this->body_text;
+ }
+
+ /**
+ * @param $body
+ * @return StudipMail provides fluent interface
+ */
+ public function setBodyHtml($body)
+ {
+ $this->body_html = $body;
+ return $this;
+ }
+
+ /**
+ * @return unknown_type
+ */
+ public function getBodyHtml()
+ {
+ return $this->body_html;
+ }
+
+ /**
+ * quotes the given string if it contains any characters
+ * reserved for special interpretation in RFC 2822.
+ */
+ protected static function quoteString($string)
+ {
+ // list of reserved characters in RFC 2822
+ if (strcspn($string, '()<>[]:;@\\,.') < mb_strlen($string)) {
+ $string = '"' . addcslashes($string, "\r\"\\") . '"';
+ }
+ return $string;
+ }
+
+ /**
+ * send the mail using the given transporter object, or the
+ * set default transporter
+ *
+ * @param email_message_class $transporter
+ * @return bool
+ */
+ public function send(email_message_class $transporter = null)
+ {
+ if ($transporter === null) {
+ $transporter = self::$transporter;
+ }
+ if ($transporter === null) {
+ throw new Exception('no mail transport defined');
+ }
+ $transporter->ResetMessage();
+ $transporter->SetHeader('Return-Path', $this->getSenderEmail());
+ $transporter->SetEncodedEmailHeader('From', $this->getSenderEmail(), self::quoteString($this->getSenderName()));
+ if($this->getReplyToEmail()){
+ $transporter->SetEncodedEmailHeader('Reply-To', $this->getReplyToEmail(), self::quoteString($this->getReplyToName()));
+ }
+ foreach($this->getRecipients() as $recipient) {
+ $recipients_by_type[$recipient['type']][$recipient['mail']] = self::quoteString($recipient['name']);
+ }
+ foreach($recipients_by_type as $type => $recipients){
+ $transporter->SetMultipleEncodedEmailHeader($type, $recipients);
+ }
+ $transporter->SetEncodedHeader('Subject', $this->getSubject());
+ if($this->getBodyHtml()) {
+ $html_part = 0;
+ $transporter->CreateQuotedPrintableHTMLPart($this->getBodyHtml(), "", $html_part);
+ $text_part = '';
+ $text_message = $this->getBodyText();
+
+ if(!$text_message){
+ $text_message = _('Diese Nachricht ist im HTML-Format verfasst. Sie benötigen eine E-Mail-Anwendung, die das HTML-Format anzeigen kann.');
+ }
+ $transporter->CreateQuotedPrintableTextPart($transporter->WrapText($text_message), "", $text_part);
+
+ $part = [$text_part, $html_part];
+ if (count($this->related_attachments) > 0) {
+ $relparts = [$html_part];
+ $i = 99;
+ $multipart = 0;
+ foreach ($this->related_attachments as $one) {
+ $transporter->CreateFilePart($one, $i);
+ $relparts[] = $i;
+ }
+ $transporter->CreateRelatedMultipart($relparts, $multipart);
+ $part = [$text_part, $multipart];
+ }
+ $transporter->AddAlternativeMultipart($part);
+ } else {
+ $transporter->AddQuotedPrintableTextPart($this->getBodyText());
+ }
+ foreach($this->getAttachments() as $attachment){
+ $part = [
+ 'FileName' => $attachment['file_name'],
+ 'Data' => $attachment['data'],
+ 'Name' => $attachment['name'],
+ 'Content-Type' => $attachment['type'],
+ 'Disposition' => $attachment['disposition'],
+ ];
+ $transporter->addFilePart($part);
+ }
+ $error = $transporter->Send();
+ if (mb_strlen($error) === 0) {
+ return true;
+ } else {
+ Log::error(get_class($transporter) . '::Send() - ' . $error);
+ return false;
+ }
+ }
+
+ public function toArray()
+ {
+ return get_object_vars($this);
+ }
+
+ public function setData($data)
+ {
+ foreach ($data as $name => $value) {
+ $this->$name = $value;
+ }
+ }
+}