Support » Plugin: Postmark Email for WordPress by Yoast » [Plugin: Postmark Email for WordPress by Yoast] New plugin version 0.3.3

  • Hi,

    You will find below a new version of this plugin, which fixes the following 2 issues that have been reported:

    Excerpt from the readme.txt file detailing the addressed issues:

    = 0.3.3 =

    * Fixed errors that appear when user attempts to retrieve forgotten password (no headers passed to the function).
    * Return true to ensure similar behaviour with the original wp_mail function.
    * Improved algorithm used to set from_email, from_name and reply_to values.

    File postmark.php:

    <?php
    /*
    Plugin Name: Postmark Email for WordPress
    Version: 0.3.3
    Plugin URI: http://yoast.com/wordpress/postmark-email-plugin/
    Description: Divert all WordPress mail to <a href="http://postmarkapp.com">Postmarkapp</a>.
    Author: Joost de Valk
    Author URI: http://yoast.com
    
    Copyright 2011 Joost de Valk (email: joost@yoast.com)
    */
    
    // Postmark settings
    define('POSTMARKAPP_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__) );
    
    require_once( POSTMARKAPP_PLUGIN_DIR_PATH.'Postmark/Postmark.php');
    
    /**
     * Break $recipient into name and address parts if in the format "Foo <bar@baz.com>"
     *
     * @since 0.1
     *
     * @param string $recipient
     * @return array array with strings name and email
     */
    function format_email_recipient( $recipient ) {
    	$return = array(
    		'name' => '',
    		'email' => $recipient
    	);
    	if ( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) {
    		if ( count( $matches ) == 3 ) {
    			$return['name'] = trim( $matches[1] );
    			$return['email'] = trim( $matches[2] );
    		}
    	}
    	return $return;
    }
    
    // Wrapper needed because this uses the very annoying concept of pluggable functions.
    if ( !function_exists('wp_mail') && defined('POSTMARKAPP_API_KEY') ) {
    
    	/**
    	 * Send mail, replacing WP's internal normal wp_mail function
    	 *
    	 * A true return value does not automatically mean that the user received the
    	 * email successfully. It just only means that the method used was able to
    	 * process the request without any errors.
    	 *
    	 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
    	 * creating a from address like 'Name <email@address.com>' when both are set. If
    	 * just 'wp_mail_from' is set, then just the email address will be used with no
    	 * name. Note that the email address has to be verified as a sender signature in Postmarkapp.
    	 *
    	 * The default content type is 'text/plain' which does not allow using HTML.
    	 * However, you can set the content type of the email by using the
    	 * 'wp_mail_content_type' filter.
    	 *
    	 * The default charset is based on the charset used on the blog. The charset can
    	 * be set using the 'wp_mail_charset' filter.
    	 *
    	 * @since 1.2.1
    	 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
    	 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
    	 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
    	 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
    	 *
    	 * @param string|array $to Array or comma-separated list of email addresses to send message.
    	 * @param string $subject Email subject
    	 * @param string $message Message contents
    	 * @param string|array $headers Optional. Additional headers.
    	 * @param string|array $attachments Optional. Files to attach.
    	 * @return bool Whether the email contents were sent successfully.
    	 */
    	function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
    
    		// Compact the input, apply the filters, and extract them back out
    		extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) );
    
    		if ( !is_array($attachments) && !empty($attachments) )
    			$attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
    
    		$email = new Mail_Postmark();
    
    		// Headers
    		if ( empty( $headers ) ) {
    			$headers = array();
    		} else {
    			if ( !is_array( $headers ) ) {
    				// Explode the headers out, so this function can take both
    				// string headers and an array of headers.
    				$tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
    			} else {
    				$tempheaders = $headers;
    			}
    			$headers   = array();
    			$cc     = array();
    			$bcc     = array();
    
    			// If it's actually got contents
    			if ( !empty( $tempheaders ) ) {
    				// Iterate through the raw headers
    				foreach ( (array) $tempheaders as $header ) {
    					if ( strpos($header, ':') === false ) {
    						if ( false !== stripos( $header, 'boundary=' ) ) {
    							$parts = preg_split('/boundary=/i', trim( $header ) );
    							$boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
    						}
    						continue;
    					}
    					// Explode them out
    					list( $name, $content ) = explode( ':', trim( $header ), 2 );
    
    					// Cleanup crew
    					$name    = trim( $name    );
    					$content = trim( $content );
    
    					switch ( strtolower( $name ) ) {
    						// Mainly for legacy -- process a From: header if it's there
    						case 'from':
    							$recipient = format_email_recipient( $content );
    							$from_name  = $recipient['name'];
    							$from_email = $recipient['email'];
    							break;
    						case 'content-type':
    							// We don't currently use the charset, but we need the content type to determine which type of mail to set.
    							if ( strpos( $content, ';' ) !== false ) {
    								list( $type, $charset ) = explode( ';', $content );
    								$content_type = trim( $type );
    								if ( false !== stripos( $charset, 'charset=' ) ) {
    									$charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) );
    								} elseif ( false !== stripos( $charset, 'boundary=' ) ) {
    									$boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) );
    									$charset = '';
    								}
    							} else {
    								$content_type = trim( $content );
    							}
    							break;
    						case 'cc':
    							$cc = array_merge( (array) $cc, explode( ',', $content ) );
    							break;
    						case 'bcc':
    							$bcc = array_merge( (array) $bcc, explode( ',', $content ) );
    							break;
    						case 'reply-to':
    							$reply_to = $content;
    							break;
    						default:
    							// Add it to our grand headers array
    							$headers[trim( $name )] = trim( $content );
    							break;
    					}
    				}
    			}
    		}
    
    		// From email and name
    
    		/* If we don't have an email from the input headers default to wordpress@$sitename
    		* Some hosts will block outgoing mail from this address if it doesn't exist but
    		* there's no easy alternative. Defaulting to admin_email might appear to be another
    		* option but some hosts may refuse to relay mail from an unknown domain. See
    		* http://trac.wordpress.org/ticket/5007.
    		*/
    
    		$sitename = strtolower( $_SERVER['SERVER_NAME'] );
    		if ( substr( $sitename, 0, 4 ) == 'www.' ) {
    			$sitename = substr( $sitename, 4 );
    		}
    		$from_email_default = 'wordpress@' . $sitename;
    		$from_name_default  = 'WordPress';
    
    		// If we don't have an email from the input headers
    		if ( !isset( $from_email ) || empty( $from_email ) )
    			$from_email = $from_email_default;
    
    		// If we don't have a name from the input headers or it is the same as the from email
    		if ( !isset( $from_name ) || empty( $from_name ) || ($from_name == $from_email) )
    			$from_name = ( defined('POSTMARKAPP_MAIL_FROM_NAME') ? POSTMARKAPP_MAIL_FROM_NAME : $from_name_default );
    
    		// set this flag to false to prevent overwriting an already set reply-to with the from address
    		$reply_to_overwrite = true;
    
    		// If the from email is not in your list of allowed sender email addresses,
    		// use the first allowed sender email address and move the from name and
    		// email to the reply-to (in some conditions)
    		if ( defined('POSTMARKAPP_MAIL_FROM_ADDRESS') ) {
    			$allowedfrom = explode(',', POSTMARKAPP_MAIL_FROM_ADDRESS);
    			if ( !in_array( $from_email, $allowedfrom ) ) {
    
    				// attempt to change the reply-to only if the from address is not wordpress@$sitename
    				if ( $from_email != $from_email_default ) {
    
    					// overwrite reply-to if above flag says so, or it is not set or empty
    					if ( $reply_to_overwrite || !isset($reply_to) || empty($reply_to) )
    						$reply_to = $from_name . ' <' . $from_email . '>';
    				}
    
    				$from_email = $allowedfrom[0];
    				$from_name = ( defined('POSTMARKAPP_MAIL_FROM_NAME') ? POSTMARKAPP_MAIL_FROM_NAME : $from_name_default );
    			}
    		}
    
    		// Plugin authors can override the potentially troublesome default
    		$email->from(     apply_filters( 'wp_mail_from'     , $from_email ) );
    		$email->fromName( apply_filters( 'wp_mail_from_name', $from_name ) );
    
    		// Set destination addresses
    		if ( !is_array( $to ) )
    			$to = explode( ',', $to );
    
    		foreach ( (array) $to as $recipient ) {
    			$recipient = format_email_recipient( $recipient );
    			$email->addTo( $recipient['email'], $recipient['name'] );
    		}
    
    		// Set mail's subject and body
    		$email->subject( $subject );
    
    		// Set Content-Type and charset
    		// If we don't have a content-type from the input headers
    		if ( !isset( $content_type ) )
    			$content_type = 'text/plain';
    
    		$content_type = apply_filters( 'wp_mail_content_type', $content_type );
    
    		if ( $content_type == 'text/html' )
    			$email->messageHtml( $message );
    		else
    			$email->messagePlain( $message );
    
    		// Add any CC and BCC recipients
    		if ( !empty( $cc ) ) {
    			foreach ( (array) $cc as $recipient ) {
    				$recipient = format_email_recipient( $recipient );
    				$email->addCc( $recipient['email'], $recipient['name'] );
    			}
    		}
    
    		if ( !empty( $bcc ) ) {
    			foreach ( (array) $bcc as $recipient) {
    				$recipient = format_email_recipient( $recipient );
    				$email->addBcc( $recipient['email'], $recipient['name'] );
    			}
    		}
    
    		// Set the reply to
    		if ( isset( $reply_to ) ) {
    			$reply_to = format_email_recipient( $reply_to );
    			$email->replyTo( $reply_to['email'], $reply_to['name'] );
    		}
    
    		// Set custom headers
    		if ( !empty( $headers ) ) {
    			foreach( (array) $headers as $name => $content ) {
    				$email->addHeader( $name, $content );
    			}
    		}
    
    		if ( !empty( $attachments ) ) {
    			foreach ( $attachments as $attachment ) {
    				$email->addAttachment($attachment);
    			}
    		}
    
    		$email->send();
    
    		return true;
    	}
    
    }

    File readme.txt:

    === Postmark Email for WordPress by Yoast ===
    Contributors: joostdevalk
    Donate link: http://yoast.com/
    Tags: email, reliability, email reliability, postmark, yoast, postmarkapp, smtp, wildbit, notifications, wp_mail
    Requires at least: 3.1
    Tested up to: 3.3
    Stable tag: 0.3.3
    
    Reroute all WordPress mail through Postmark to increase email reliability.
    
    == Description ==
    
    This plugin replaces WordPress' internal email sending functionality by routing all email through [Postmark](http://postmarkapp.com), greatly enhancing email reliability. If you rely on your WordPress install to send you email, this plugin along with the awesome service from Postmark makes sure that it actually does reach its destination.
    
    Why you should use this plugin over the official Postmark approved plugin or other Postmark plugins? 
    
    * Uses the [WordPress HTTP API](http://yoast.com/wp-best-practice/wordpress-http-api/) instead of CURL, so it even works when there's no CURL available.
    * This plugin sends your email over a secure (SSL) connection (and actually checks whether the host on the other side is really the host we expect).
    * Handles From / CC / BCC headers correctly, when set by plugins like [Gravity Forms](http://yoast.com/wp-plugin-review/gravity-forms/).
    * The plugin handles attachments correctly.
    
    More info about the plugin:
    
    * [Sending reliable email with Postmark](http://yoast.com/postmark-reliable-email/).
    * [Plugin page on yoast.com](http://yoast.com/wordpress/postmark-email-plugin/).
    
    == Screenshots ==
    
    1. An email sent through Postmark, properly signed by the domain.
    
    == Installation ==
    
    How to install this plugin?
    
    1. Search for "postmark email" in the "Add new plugin" interface.
    1. Install the plugin and activate it.
    1. Open your wp-config.php file and add your Postmark API key in the following way: <code>define('POSTMARKAPP_API_KEY', '<API KEY>');</code>. (Find your API key under Your Rack -> Your Server -> Credentials).
    1. Set your FROM address in the same way: <code>define('POSTMARKAPP_MAIL_FROM_ADDRESS', 'from@example.com');</code>, make sure it's a valid Postmark [Sender Signature](https://postmarkapp.com/signatures).
    1. You're done!
    
    == Frequently Asked Questions ==
    
    = Why would I use Postmark instead of sending email with my web server? =
    
    Because sending email with your web server is horribly unreliable. While this might not be a problem when all it emails is some comment emails, but when you start relying on emails from your WordPress install for inquiries, order forms or transaction emails, you really should make 100% sure these emails arrive. Postmark makes that part easy. You might want to read the authors posts about [email reliability](http://yoast.com/email-reliability/) and [sending reliable email with Postmark](http://yoast.com/postmark-reliable-email/). 
    
    There are definitely other choices of email parties out there, so far the author has just used Postmark and loves its simplicity.
    
    = How do I specify multiple allowed from addresses? =
    
    By comma separating the from addresses in the wp-config: 
    
    <code>define('POSTMARKAPP_MAIL_FROM_ADDRESS', 'from@example.com,secondfrom@example.com');</code>
    
    = Can I use this plugin as a Must Use plugin too? =
    
    Yes, simply copy the contents of the plugin directory (so not the entire directory itself) into your <code>wp-content/mu-plugins/</code> directory. This is the main reason why the plugin doesn't have an admin screen; it's meant as a drop-in functionality for sites.
    
    == Changelog ==
    
    = 0.3.3 =
    
    * Fixed errors that appear when user attempts to retrieve forgotten password (no headers passed to the function).
    * Return true to ensure similar behaviour with the original <code>wp_mail</code> function.
    * Improved algorithm used to set <code>from_email</code>, <code>from_name</code> and <code>reply_to</code> values.
    
    = 0.3.2 =
    
    * Apparently I can't type so I made ANOTHER error in the <code>function_exists</code> call.
    
    = 0.3.1 =
    
    * You can now specify several allowed from addresses, by comma separating them in the <code>POSTMARKAPP_MAIL_FROM_ADDRESS</code> constant.
    * If from address is not in list of allowed from addresses, the from address is changed to the first allowed email address and the set from address and name is used in the reply-to instead.
    * Improved the readme.txt, adding an [FAQ](http://wordpress.org/extend/plugins/postmark-email-for-wordpress/faq/).
    
    = 0.3 =
    
    * Fixed typo in 0.2 that would still cause activation issues.
    * Plugin no longer activates when API key is not set.
    
    = 0.2 =
    
    * Properly wrap in a <code>function_exists</code> call so the plugin will activate when used as a normal plugin.
    
    = 0.1 =
    
    * Initial beta release.

    Just copy the above content in the relevant files from the plugin folder.

    Hope this helps.

    Kind regards,
    John

  • The topic ‘[Plugin: Postmark Email for WordPress by Yoast] New plugin version 0.3.3’ is closed to new replies.