Custom Module for Sending Emails in Development Servers

Came up with a solution.

I ended up copying the contents of the following block of code in the constructor from the CMailFile class at htdocs/core/class/CMailFile.class.php in a public function called newSmtps() in my custom module’s hook class. The newSmtps() function replaces $object->smtps with a NEW instance of SMTPS.

elseif ($this->sendmode == 'smtps')

So, now my hook function looks like this:

	public function sendMail($parameters, &$object, &$action, $hookmanager)
	{
		if ( ! TEST_MODE ) return 0;
		
		$production_recipients = $object->addr_to;
		$recipients = TEST_MODE ? $this->testemailrecipients : $production_recipients;

		// START: Update the addr_to field value on the CMailFile object
		$object->addr_to = $recipients;
		// END: Update the addr_to field value on the CMailFile object
		
		$email_subject = sprintf( '%s %s', $this->emaildebugsubject, $object->subject );
		$email_message = sprintf( '%s %s', $object->msg, $this->getEmaildebugsnippet($production_recipients) );

		if ( $object->sendmode == 'mail' ) {
			$object->message = $email_message;
		} elseif ( $object->sendmode == 'smtps' ) {
			$object->smtps = $this->newSmtps($object); // 
			$object->smtps->setSubject($email_subject);
			if ( $object->msgishtml ) {
					$object->smtps->setBodyContent($email_message, 'html');
			} else {
					$object->smtps->setBodyContent($email_message, 'plain');
			}
		} elseif ($this->sendmode == 'swiftmailer') {
			// START: Update the to address(s) on the Swift_Message object.
			try {
				$result = $object->message->setTo($object->getArrayAddress($object->addr_to));
			} catch (Exception $e) {
				$object->errors[] = $e->getMessage();
			}
			// END: Update the to address(s) on the Swift_Message object.

			$object->message->setBody($email_message, 'text/html');
		}

		return 0;
	}

It is important to replace $this with $object so that the smtps class has all the values it needs to send out the emails.

	public function newSmtps( &$object ) {
		global $conf;
		$filename_list = $object->filename_list;
		$mimetype_list = $object->mimetype_list;
		$mimefilename_list = $object->mimefilename_list;
		$moreinheader = $object->smtps->getMoreInHeader();
		$css = ( ! empty( $object->css ) ? $object->css : '' );

		// Use SMTPS library
		// ------------------------------------------

		require_once DOL_DOCUMENT_ROOT.'/core/class/smtps.class.php';
		$smtps = new SMTPs();
		$smtps->setCharSet($conf->file->character_set_client);

		

		// Encode subject if required.
		$subjecttouse = $object->subject;
		if (!ascii_check($subjecttouse)) {
			$subjecttouse = $object->encodetorfc2822($subjecttouse);
		}

		$smtps->setSubject($subjecttouse);
		$smtps->setTO($object->getValidAddress($object->addr_to, 0, 1));
		$smtps->setFrom($object->getValidAddress($object->addr_from, 0, 1));
		$smtps->setTrackId($object->trackid);
		$smtps->setReplyTo($object->getValidAddress($object->reply_to, 0, 1));

		if (!empty($moreinheader)) $smtps->setMoreInHeader($moreinheader);

		if (!empty($object->html))
		{
			if (!empty($css))
			{
				$object->css = $css;
				$object->buildCSS();
			}
			$msg = $object->html;
			$msg = $object->checkIfHTML($msg);
		}

		// Replace . alone on a new line with .. to avoid to have SMTP interpret this as end of message
		$msg = preg_replace('/(\r|\n)\.(\r|\n)/ims', '\1..\2', $msg);

		if ($object->msgishtml) $smtps->setBodyContent($msg, 'html');
		else $smtps->setBodyContent($msg, 'plain');

		if ($object->atleastoneimage)
		{
			foreach ($object->images_encoded as $img)
			{
				$smtps->setImageInline($img['image_encoded'], $img['name'], $img['content_type'], $img['cid']);
			}
		}

		if (!empty($object->atleastonefile))
		{
			foreach ($filename_list as $i => $val)
			{
				$content = file_get_contents($filename_list[$i]);
				$smtps->setAttachment($content, $mimefilename_list[$i], $mimetype_list[$i]);
			}
		}

		$smtps->setCC($object->addr_cc);
		$smtps->setBCC($object->addr_bcc);
		$smtps->setErrorsTo($object->errors_to);
		$smtps->setDeliveryReceipt($object->deliveryreceipt);
		if (!empty($conf->global->$keyforsslseflsigned)) $smtps->setOptions(array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)));

		$host = dol_getprefix('email');
		$object->msgid = time().'.SMTPs-dolibarr-'.$object->trackid.'@'.$host;

		return $smtps;
	}

It is important that the newSmtps() function accept $object as ‘&$object’ so you get a reference instead of a clone.

Furthermore, you need to place the Dolibarr global $conf at the top of the new function along with the following constructors. The constructors are important so that files attached to emails are attached properly.

		$filename_list = $object->filename_list;
		$mimetype_list = $object->mimetype_list;
		$mimefilename_list = $object->mimefilename_list;
		$moreinheader = $object->smtps->getMoreInHeader();
		$css = ( ! empty( $object->css ) ? $object->css : '' );
1 Like