<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Garrett St. John &#187; Email</title>
	<atom:link href="http://garrettstjohn.com/topics/email/feed/" rel="self" type="application/rss+xml" />
	<link>http://garrettstjohn.com</link>
	<description>I am a web developer and partner at Bold. This is where I share my thoughts, discoveries and other random bits.</description>
	<lastBuildDate>Thu, 17 May 2012 18:12:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Sending Email Attachments in iOS</title>
		<link>http://garrettstjohn.com/entry/sending-email-attachments-ios/</link>
		<comments>http://garrettstjohn.com/entry/sending-email-attachments-ios/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 01:05:02 +0000</pubDate>
		<dc:creator>Garrett</dc:creator>
				<category><![CDATA[text]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPod]]></category>

		<guid isPermaLink="false">http://garrettstjohn.com/?p=370</guid>
		<description><![CDATA[The bottom line is it&#8217;s not possible. At least natively. I discovered this unfortunate circumstance this morning as I was trying to reply to an email with a screenshot from my iPad. I could have sent it from Photos, but that would have required me to write a new email and the recipients weren&#8217;t in my address [<a href="http://garrettstjohn.com/entry/sending-email-attachments-ios/">Keep Reading&#8230;</a>]]]></description>
			<content:encoded><![CDATA[<p>The bottom line is <strong>it&#8217;s not possible</strong>. At least natively.</p>
<p>I discovered this unfortunate circumstance this morning as I was trying to reply to an email with a screenshot from my iPad. I could have sent it from Photos, but that would have required me to write a new email and the recipients weren&#8217;t in my address book. I would also prefer to keep the screenshot associated with the original email for context. No such luck, though.</p>
<p>What about sending non-photo attachments (like a document)? Also, not possible. There is an app called <a href="http://itunes.apple.com/artist/good-iware-ltd/id289191291">GoodReader</a> that (among other things) will allow you to send files as email attachments, but no such functionality is built into iOS. Do I really want <em>another</em> app to enable such a simple process? And for $4.99?</p>
<p>I love my iPad for 101 reasons, but how can we really call the iPad a &#8220;go between&#8221; device or &#8220;laptop killer&#8221; if it can&#8217;t natively do something as simple as send an email attachment. I think this discovery just reinforces for me even further that the iPad is a consumption device and isn&#8217;t suited for creation/productivity.</p>
]]></content:encoded>
			<wfw:commentRss>http://garrettstjohn.com/entry/sending-email-attachments-ios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting Attachments From Emails With PHP</title>
		<link>http://garrettstjohn.com/entry/extracting-attachments-from-emails-with-php/</link>
		<comments>http://garrettstjohn.com/entry/extracting-attachments-from-emails-with-php/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 16:12:50 +0000</pubDate>
		<dc:creator>Garrett</dc:creator>
				<category><![CDATA[text]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://garrettstjohn.com/?p=299</guid>
		<description><![CDATA[Yesterday I wrote about how to read emails with PHP, but I want to dig a bit deeper and discuss another part of the My Slow Low project that needed tackling: Extracting attachments from emails with PHP. For the purposes of this post, I will be specifically discussing file attachments, not HTML inline attached files. [<a href="http://garrettstjohn.com/entry/extracting-attachments-from-emails-with-php/">Keep Reading&#8230;</a>]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I wrote about how to <a href="http://garrettstjohn.com/entry/reading-emails-with-php-my-slow-low/">read emails with PHP</a>, but I want to dig a bit deeper and discuss another part of the <a href="http://myslowlow.com">My Slow Low</a> project that needed tackling: Extracting attachments from emails with PHP. For the purposes of this post, I will be specifically discussing file attachments, not HTML inline attached files.</p>
<p>This project was executed with <a href="http://www.codeigniter.com">CodeIgniter 2.0</a> so there are a few libraries and helper functions used that will not be available in other frameworks or with straight PHP, however, their functionality can be pretty easily replicated.</p>
<pre class="brush:php">function email_pull() {
	// load the Email_reader library from previous post
	$this-&gt;load-&gt;library('email_reader');

	// load the meals_model to store meal information
	$this-&gt;load-&gt;model('meals_model');

	// this method is run on a cronjob and should process all emails in the inbox
	while (1) {
		// get an email
		$email = $this-&gt;email_reader-&gt;get();

		// if there are no emails, jump out
		if (count($email) &lt;= 0) {
			break;
		}

		$attachments = array();
		// check for attachments
		if (isset($email['structure']-&gt;parts) &amp;&amp; count($email['structure']-&gt;parts)) {
			// loop through all attachments
			for ($i = 0; $i &lt; count($email['structure']-&gt;parts); $i++) {
				// set up an empty attachment
				$attachments[$i] = array(
					'is_attachment' =&gt; FALSE,
					'filename'      =&gt; '',
					'name'          =&gt; '',
					'attachment'    =&gt; ''
				);

				// if this attachment has idfparameters, then proceed
				if ($email['structure']-&gt;parts[$i]-&gt;ifdparameters) {
					foreach ($email['structure']-&gt;parts[$i]-&gt;dparameters as $object) {
						// if this attachment is a file, mark the attachment and filename
						if (strtolower($object-&gt;attribute) == 'filename') {
							$attachments[$i]['is_attachment'] = TRUE;
							$attachments[$i]['filename']      = $object-&gt;value;
						}
					}
				}

				// if this attachment has ifparameters, then proceed as above
				if ($email['structure']-&gt;parts[$i]-&gt;ifparameters) {
					foreach ($email['structure']-&gt;parts[$i]-&gt;parameters as $object) {
						if (strtolower($object-&gt;attribute) == 'name') {
							$attachments[$i]['is_attachment'] = TRUE;
							$attachments[$i]['name']          = $object-&gt;value;
						}
					}
				}

				// if we found a valid attachment for this 'part' of the email, process the attachment
				if ($attachments[$i]['is_attachment']) {
					// get the content of the attachment
					$attachments[$i]['attachment'] = imap_fetchbody($this-&gt;email_reader-&gt;conn, $email['index'], $i+1);

					// check if this is base64 encoding
					if ($email['structure']-&gt;parts[$i]-&gt;encoding == 3) { // 3 = BASE64
						$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
					}
					// otherwise, check if this is "quoted-printable" format
					elseif ($email['structure']-&gt;parts[$i]-&gt;encoding == 4) { // 4 = QUOTED-PRINTABLE
						$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
					}
				}
			}
		}

		// for My Slow Low, check if I found an image attachment
		$found_img = FALSE;
		foreach ($attachments as $a) {
			if ($a['is_attachment'] == 1) {
				// get information on the file
				$finfo = pathinfo($a['filename']);

				// check if the file is a jpg, png, or gif
				if (preg_match('/(jpg|gif|png)/i', $finfo['extension'], $n)) {
					$found_img = TRUE;
					// process the image (save, resize, crop, etc.)
					$fname = $this-&gt;_process_img($a['attachment'], $n[1]);

					break;
				}
			}
		}

		// if there was no image, move the email to the Rejected folder on the server
		if ( ! $found_img) {
			$this-&gt;email_reader-&gt;move($email['index'], 'INBOX.Rejected');
			continue;
		}

		// get content from the email that I want to store
		$addr   = $email['header']-&gt;from[0]-&gt;mailbox."@".$email['header']-&gt;from[0]-&gt;host;
		$sender = $email['header']-&gt;from[0]-&gt;mailbox;
		$text   = ( ! empty($email['header']-&gt;subject) ? $email['header']-&gt;subject : '');

		// move the email to Processed folder on the server
		$this-&gt;email_reader-&gt;move($email['index'], 'INBOX.Processed');

		// add the data to the database
		$this-&gt;meals_model-&gt;add(array(
			'username'    =&gt; $sender,
			'email'       =&gt; $addr,
			'photo'       =&gt; $fname,
			'description' =&gt; ($text == '' ? NULL : $text)
		));

		// don't slam the server
		sleep(1);
	}

	// close the connection to the IMAP server
	$this-&gt;email_reader-&gt;close();
}
</pre>
<p>I tried to comment the code above as best as possible to convey what it is I am doing with the information. This code is a method within a Controller, but I&#8217;ve only included the attachment extraction method of the class for this post.</p>
<p>For more information and to credit those I&#8217;ve learned from, please check out David Walsh&#8217;s post on <a href="http://davidwalsh.name/gmail-php-imap">Retriev[ing] Your Gmail Emails with PHP and IMAP</a> as well as Chris Hope&#8217;s post on <a href="http://www.electrictoolbox.com/extract-attachments-email-php-imap/">Extracting attachments from an email message using PHP IMAP functions</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://garrettstjohn.com/entry/extracting-attachments-from-emails-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading Emails with PHP</title>
		<link>http://garrettstjohn.com/entry/reading-emails-with-php/</link>
		<comments>http://garrettstjohn.com/entry/reading-emails-with-php/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 21:11:04 +0000</pubDate>
		<dc:creator>Garrett</dc:creator>
				<category><![CDATA[text]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://garrettstjohn.com/?p=264</guid>
		<description><![CDATA[Last week I got to do a fun little side project which we called My Slow Low. The site is a simple photo collection of slow/low carb meals for those that are out of ideas on what to eat, but want to stick to their diet. While conceptualizing how we would build the site, the [<a href="http://garrettstjohn.com/entry/reading-emails-with-php/">Keep Reading&#8230;</a>]]]></description>
			<content:encoded><![CDATA[<p>Last week I got to do a fun little side project which we called <a href="http://myslowlow.com">My Slow Low</a>. The site is a simple photo collection of slow/low carb meals for those that are out of ideas on what to eat, but want to stick to their diet. While conceptualizing how we would build the site, the idea of emailing in photos came up. We didn&#8217;t want the hassle of account management and were trying to go for a more &#8220;mobile capable&#8221; option. This was my first time coding for IMAP with PHP and I figured some others could use a jump start from what I&#8217;ve learned.</p>
<p>PHP already has a nice <a href="http://php.net/manual/en/book.imap.php">IMAP extension</a> which needs to be installed and enabled before going further. The core functionality is all there, but the specifics on how to use it aren&#8217;t necessarily all that clear.</p>
<p>Here&#8217;s a PHP class I put together to do some basic operations on an IMAP Inbox. It&#8217;s a bit tailored to this project, but could be easily revised to fit other needs or extended to be more full featured.</p>
<pre class="brush: php">&lt;?php

class Email_reader {

	// imap server connection
	public $conn;

	// inbox storage and inbox message count
	private $inbox;
	private $msg_cnt;

	// email login credentials
	private $server = 'yourserver.com';
	private $user   = 'email@yourserver.com';
	private $pass   = 'yourpassword';
	private $port   = 143; // adjust according to server settings

	// connect to the server and get the inbox emails
	function __construct() {
		$this-&gt;connect();
		$this-&gt;inbox();
	}

	// close the server connection
	function close() {
		$this-&gt;inbox = array();
		$this-&gt;msg_cnt = 0;

		imap_close($this-&gt;conn);
	}

	// open the server connection
	// the imap_open function parameters will need to be changed for the particular server
	// these are laid out to connect to a Dreamhost IMAP server
	function connect() {
		$this-&gt;conn = imap_open('{'.$this-&gt;server.'/notls}', $this-&gt;user, $this-&gt;pass);
	}

	// move the message to a new folder
	function move($msg_index, $folder='INBOX.Processed') {
		// move on server
		imap_mail_move($this-&gt;conn, $msg_index, $folder);
		imap_expunge($this-&gt;conn);

		// re-read the inbox
		$this-&gt;inbox();
	}

	// get a specific message (1 = first email, 2 = second email, etc.)
	function get($msg_index=NULL) {
		if (count($this-&gt;inbox) &lt;= 0) {
			return array();
		}
		elseif ( ! is_null($msg_index) &amp;&amp; isset($this-&gt;inbox[$msg_index])) {
			return $this-&gt;inbox[$msg_index];
		}

		return $this-&gt;inbox[0];
	}

	// read the inbox
	function inbox() {
		$this-&gt;msg_cnt = imap_num_msg($this-&gt;conn);

		$in = array();
		for($i = 1; $i &lt;= $this-&gt;msg_cnt; $i++) {
			$in[] = array(
				'index'     =&gt; $i,
				'header'    =&gt; imap_headerinfo($this-&gt;conn, $i),
				'body'      =&gt; imap_body($this-&gt;conn, $i),
				'structure' =&gt; imap_fetchstructure($this-&gt;conn, $i)
			);
		}

		$this-&gt;inbox = $in;
	}

}

?&gt;
</pre>
<p>A fair amount of this is self-explanatory or commented inline, but I will go over the inbox() method because it is the core functionality. The IMAP inbox is much like an array with a numbered key starting at 1. In the inbox() method, I store that index so that the email can be moved, deleted, or read again later.</p>
<p>Next, the header is stored with the function imap_headerinfo(). This pulls down an object from the server containing information like the Subject, From: address, To: address, and text encoding type.</p>
<p>Using imap_body(), the body text of the email is retrieved. What&#8217;s returned isn&#8217;t overly clean as it&#8217;s just the raw body with boundaries included (see: <a href="http://en.wikipedia.org/wiki/MIME#Multipart_messages">multipart messages</a>). If the received email is in HTML, there will be a plain text and HTML version included. It&#8217;s certainly possible to parse through this data like any email client does, but it&#8217;s definitely a little bit messy.</p>
<p>Lastly, &#8216;structure&#8217; is retrieved with the imap_fetchstructure() function. This is very important if you are trying to access attachments as I was with My Slow Low. In my next post, I&#8217;ll go further into the details of saving an attachment from an email and share some more about how I implemented the email processor for My Slow Low.</p>
<p><strong>Update:</strong> I&#8217;ve posted the follow-up to this article on <a href="http://garrettstjohn.com/entry/extracting-attachments-from-emails-with-php/">extracting email attachments with PHP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://garrettstjohn.com/entry/reading-emails-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5 Time Savings Tips For Email</title>
		<link>http://garrettstjohn.com/entry/five-time-savings-tips-email/</link>
		<comments>http://garrettstjohn.com/entry/five-time-savings-tips-email/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 17:00:55 +0000</pubDate>
		<dc:creator>Garrett</dc:creator>
				<category><![CDATA[link]]></category>
		<category><![CDATA[Email]]></category>

		<guid isPermaLink="false">http://garrettstjohn.com/?p=93</guid>
		<description><![CDATA[Link: Email Sucks. 5 Time Saving Tips. I’ve found myself getting more and more email lately. It’s been hard to keep the count down and the days of Inbox Zero are a distant memory. Kevin Rose provides some good ideas for how to manage email and limit time wasted.]]></description>
			<content:encoded><![CDATA[<p>Link: <a href="http://kevinrose.com/blogg/2010/8/17/email-sucks-5-time-saving-tips.html">Email Sucks. 5 Time Saving Tips.</a></p>
<p>I’ve found myself getting more and more email lately. It’s been hard to keep the count down and the days of Inbox Zero are a distant memory. Kevin Rose provides some good ideas for how to manage email and limit time wasted.</p>
]]></content:encoded>
			<wfw:commentRss>http://garrettstjohn.com/entry/five-time-savings-tips-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

