MDL-41956 messages: Accept attachments in send_message() in email message provider
authorYuliya Bozhko <yuliya.bozhko@totaralms.com>
Wed, 25 Sep 2013 22:34:27 +0000 (10:34 +1200)
committerYuliya Bozhko <yuliya.bozhko@totaralms.com>
Tue, 1 Oct 2013 02:38:02 +0000 (15:38 +1300)
lib/phpmailer/moodle_phpmailer.php
lib/tests/messagelib_test.php
message/output/email/lang/en/message_email.php
message/output/email/message_output_email.php
message/output/email/settings.php
message/upgrade.txt

index 3e0e258..688c336 100644 (file)
@@ -145,7 +145,7 @@ class moodle_phpmailer extends PHPMailer {
      */
     public function postSend() {
         // Now ask phpunit if it wants to catch this message.
-        if (PHPUNIT_TEST && phpunit_util::is_redirecting_messages()) {
+        if (PHPUNIT_TEST && phpunit_util::is_redirecting_phpmailer()) {
             $mail = new stdClass();
             $mail->header = $this->MIMEHeader;
             $mail->body = $this->MIMEBody;
index aeb30fc..c8a6023 100644 (file)
@@ -141,6 +141,55 @@ class core_messagelib_testcase extends advanced_testcase {
         // $this->assertFalse($this->message_type_present('moodle', 'backup', $providers));
     }
 
+    public function test_message_attachment_send() {
+        global $CFG;
+        $this->preventResetByRollback();
+        $this->resetAfterTest();
+
+        // Set config setting to allow attachments.
+        $CFG->allowattachments = true;
+        $CFG->noemailever = false;
+
+        $user = $this->getDataGenerator()->create_user();
+        $context = context_user::instance($user->id);
+
+        // Create a test file.
+        $fs = get_file_storage();
+        $filerecord = array(
+                'contextid' => $context->id,
+                'component' => 'core',
+                'filearea'  => 'unittest',
+                'itemid'    => 99999,
+                'filepath'  => '/',
+                'filename'  => 'emailtest.txt'
+        );
+        $file = $fs->create_file_from_string($filerecord, 'Test content');
+
+        $message = new stdClass();
+        $message->component         = 'moodle';
+        $message->name              = 'instantmessage';
+        $message->userfrom          = get_admin();
+        $message->userto            = $user;
+        $message->subject           = 'message subject 1';
+        $message->fullmessage       = 'message body';
+        $message->fullmessageformat = FORMAT_MARKDOWN;
+        $message->fullmessagehtml   = '<p>message body</p>';
+        $message->smallmessage      = 'small message';
+        $message->attachment        = $file;
+        $message->attachname        = 'emailtest.txt';
+
+        // Make sure we are redirecting emails.
+        $sink = $this->redirectEmails();
+        $this->assertTrue(phpunit_util::is_redirecting_phpmailer());
+        message_send($message);
+
+        // Get the email that we just sent.
+        $emails = $sink->get_messages();
+        $email = reset($emails);
+        $this->assertTrue(strpos($email->body, 'Content-Disposition: attachment;') !== false);
+        $this->assertTrue(strpos($email->body, 'emailtest.txt') !== false);
+    }
+
     /**
      * Is a particular message type in the list of message types.
      * @param string $component
index 248253a..0f0ff8d 100644 (file)
@@ -22,7 +22,9 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['allowattachments'] = 'Allow attachments';
 $string['allowusermailcharset'] = 'Allow user to select character set';
+$string['configallowattachments'] = 'Enabling this setting will allow file attachments to be sent with email messages generated by various features across the site, such as blogs, forums, or badges';
 $string['configallowusermailcharset'] = 'Enabling this, every user in the site will be able to specify his own charset for email.';
 $string['configmailnewline'] = 'Newline characters used in mail messages. CRLF is required according to RFC 822bis, some mail servers do automatic conversion from LF to CRLF, other mail servers do incorrect conversion from CRLF to CRCRLF, yet others reject mails with bare LF (qmail for example). Try changing this setting if you are having problems with undelivered emails or double newlines.';
 $string['confignoreplyaddress'] = 'Emails are sometimes sent out on behalf of a user (eg forum posts). The email address you specify here will be used as the "From" address in those cases when the recipients should not be able to reply directly to the user (eg when a user chooses to keep their address private).';
index 1873d1d..dd59c42 100644 (file)
@@ -66,7 +66,32 @@ class message_output_email extends message_output {
         } else {
             $recipient = $eventdata->userto;
         }
-        $result = email_to_user($recipient, $eventdata->userfrom, $eventdata->subject, $eventdata->fullmessage, $eventdata->fullmessagehtml);
+
+        // Check if we have attachments to send.
+        $attachment = '';
+        $attachname = '';
+        if (!empty($CFG->allowattachments) && !empty($eventdata->attachment)) {
+            if (empty($eventdata->attachname)) {
+                // Attachment needs a file name.
+                debugging('Attachments should have a file name. No attachments have been sent.', DEBUG_DEVELOPER);
+            } else if (!($eventdata->attachment instanceof stored_file)) {
+                // Attachment should be of a type stored_file.
+                debugging('Attachments should be of type stored_file. No attachments have been sent.', DEBUG_DEVELOPER);
+            } else {
+                // Copy attachment file to a temporary directory and get the file path.
+                $attachment = $eventdata->attachment->copy_content_to_temp();
+                // Function email_to_user() adds $CFG->dataroot to file path, so removing it here.
+                $attachment = str_replace($CFG->dataroot, '', $attachment);
+                // Get attachment file name.
+                $attachname = clean_filename($eventdata->attachname);
+            }
+        }
+
+        $result = email_to_user($recipient, $eventdata->userfrom, $eventdata->subject, $eventdata->fullmessage,
+                                $eventdata->fullmessagehtml, $attachment, $attachname);
+
+        // Remove an attachment file if any.
+        @unlink($attachment);
 
         return $result;
     }
index 8f7c2fb..dfd1ad4 100644 (file)
@@ -40,6 +40,7 @@ if ($ADMIN->fulltree) {
     $options = array_merge($options, $charsets);
     $settings->add(new admin_setting_configselect('sitemailcharset', get_string('sitemailcharset', 'message_email'), get_string('configsitemailcharset','message_email'), '0', $options));
     $settings->add(new admin_setting_configcheckbox('allowusermailcharset', get_string('allowusermailcharset', 'message_email'), get_string('configallowusermailcharset', 'message_email'), 0));
+    $settings->add(new admin_setting_configcheckbox('allowattachments', get_string('allowattachments', 'message_email'), get_string('configallowattachments', 'message_email'), 1));
     $options = array('LF'=>'LF', 'CRLF'=>'CRLF');
     $settings->add(new admin_setting_configselect('mailnewline', get_string('mailnewline', 'message_email'), get_string('configmailnewline','message_email'), 'LF', $options));
 }
index 715c9e2..5a96c1e 100644 (file)
@@ -4,6 +4,11 @@ information provided here is intended especially for developers.
 === 2.6 ===
 * Message processor extending message_output, should return true in can_send_to_any_users()
   if it supports message sending to internal (noreply/support) users.
+* Message API has been changed to allow attachments. Message processors that can support
+  attachments can now use additional parameter as a part of $eventdata. To send attachments,
+  $eventdata should contain properties called "attachment" (must be stored_file) and
+  "attachname" (string). Currently, email message processor is the only one to support
+  attachments.
 
 === 2.2 ===