<?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>Don&#039;t Say Geek! Say Syntux! &#187; Code</title>
	<atom:link href="http://syntux.net/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://syntux.net/blog</link>
	<description>Your freedom is worth more than you think. Take advantage of it while you can.</description>
	<lastBuildDate>Wed, 01 Feb 2012 09:31:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Free your Mac memory for free</title>
		<link>http://syntux.net/blog/2011/12/30/free-your-mac-memory-for-free/</link>
		<comments>http://syntux.net/blog/2011/12/30/free-your-mac-memory-for-free/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 07:57:01 +0000</pubDate>
		<dc:creator>Syntux</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://syntux.net/blog/?p=365</guid>
		<description><![CDATA[Mac OSX is beautiful, not only in its design, but also in its memory management. However, sometimes the inactive memory takes long time before released. According to Apple support Inactive memory is information in memory is not actively being used, but was recently used. For example, if you&#8217;ve been using Mail and then quit it, [...]]]></description>
			<content:encoded><![CDATA[<p>Mac OSX is beautiful, not only in its design, but also in its <a href="http://en.wikipedia.org/wiki/Mac_OS_memory_management" title="Mac OS memory management">memory management</a>. However, sometimes the inactive memory takes long time before released. </p>
<p>According to Apple support <strong>Inactive memory</strong> is</p>
<blockquote cite="http://support.apple.com/kb/ht1342"><p>
information in memory is not actively being used, but was recently used.</p>
<p>For example, if you&#8217;ve been using Mail and then quit it, the RAM that Mail was using is marked as Inactive memory. This Inactive memory is available for use by another application, just like Free memory.  </p>
<p>However, if you open Mail before its Inactive memory is used by a different application, Mail will open quicker because its Inactive memory is converted to Active memory, instead of loading Mail from the slower hard disk.
</p></blockquote>
<p>In many cases you will need to jump from a heavy application into another, and then you will need either to accept the system performance, which is not deadly bad, or use a simple command line to free your memory.</p>
<p>First, how to monitor your memory?<br />
Mac OS X comes with Activity Monitor Application that gives you a glimpse about your system resources, one major resource is your memory.<br />
Read Apple help on <a href="http://support.apple.com/kb/ht1342" title="Mac OS X: Reading system memory usage in Activity Monitor">Reading system memory usage in Activity Monitor</a></p>
<p><a href="http://syntux.net/blog/wp-content/uploads/2011/12/Screen-Shot-2011-12-30-at-9.43.37-AM.png"><img src="http://syntux.net/blog/wp-content/uploads/2011/12/Screen-Shot-2011-12-30-at-9.43.37-AM.png" alt="" title="Apple Activity Monitor" width="405" height="129" class="alignnone size-full wp-image-367" /></a></p>
<p>Now, how to free the inactive memory without having to reboot? </p>
<p>Open your terminal app and run<br />
<code>purge</code></p>
<p>Checking the ManPage of Purge, purge task defined as <q>force disk cache to be purged (flushed and emptied)</q> with a description <q>Purge can be used to approximate initial boot conditions with a cold  disk buffer cache for performance analysis. It does not affect anonymous memory that has been allocated through malloc, vm_allocate, etc.</q></p>
<p>No need to download an app to free your memory and moreover, you do not need to buy an app for that purpose, it comes for free.</p>
<p>&copy;2012 <a href="http://syntux.net/blog">Don&#039;t Say Geek! Say Syntux!</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://syntux.net/blog/2011/12/30/free-your-mac-memory-for-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postfix options</title>
		<link>http://syntux.net/blog/2007/02/13/postfix-options/</link>
		<comments>http://syntux.net/blog/2007/02/13/postfix-options/#comments</comments>
		<pubDate>Tue, 13 Feb 2007 10:40:07 +0000</pubDate>
		<dc:creator>Syntux</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[colleagues]]></category>
		<category><![CDATA[dnsbl]]></category>
		<category><![CDATA[fqdn]]></category>
		<category><![CDATA[hell]]></category>
		<category><![CDATA[korea]]></category>
		<category><![CDATA[pbl]]></category>
		<category><![CDATA[server mail]]></category>
		<category><![CDATA[smtp server]]></category>
		<category><![CDATA[sorbs]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[spamhaus]]></category>
		<category><![CDATA[zen]]></category>

		<guid isPermaLink="false">http://syntux.net/blog/2007/02/13/postfix-options/</guid>
		<description><![CDATA[Last week I got call from one of my colleagues complaining about the amount of spam she&#8217;s receiving, so I installed SA and implemented some restricted options in postfix smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_rbl_client list.dsbl.org, reject_rbl_client cbl.abuseat.org, reject_rbl_client, dnsbl.sorbs.net, reject_rbl_client spam.dnsbl.sorbs.net, reject_rbl_client korea.services.net, reject_rbl_client zen.spamhaus.org, reject_rbl_client pbl.spamhaus.org, reject_rbl_client sbl.spamhaus.org, permit but [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I got call from one of my colleagues complaining about the amount of spam she&#8217;s receiving, so I installed SA and implemented some restricted options in postfix<br />
<coolcode lang="shell"><br />
smtpd_recipient_restrictions =<br />
        permit_sasl_authenticated,<br />
        permit_mynetworks,<br />
        reject_unauth_destination,<br />
        reject_invalid_hostname,<br />
        reject_non_fqdn_hostname,<br />
        reject_non_fqdn_sender,<br />
        reject_rbl_client list.dsbl.org,<br />
        reject_rbl_client cbl.abuseat.org,<br />
        reject_rbl_client, dnsbl.sorbs.net,<br />
        reject_rbl_client spam.dnsbl.sorbs.net,<br />
        reject_rbl_client korea.services.net,<br />
        reject_rbl_client zen.spamhaus.org,<br />
        reject_rbl_client pbl.spamhaus.org,<br />
        reject_rbl_client sbl.spamhaus.org,<br />
        permit<br />
</coolcode></p>
<p>but later she called complaining that she cannot send emails using our SMTP server so for me it was what the hell is going one? later I found that Postfix is picky about the order of your options so if you do reject_non_fqdn_hostname before permitting sasl authenticated users, those authenticated will not be able to send emails.</p>
<p>and this was new to me.</p>
<p>Tags: <a href="http://syntux.net/blog/?s=server+mail" rel="tag"> server mail</a>, <a href="http://syntux.net/blog/?s=fqdn" rel="tag"> fqdn</a>, <a href="http://syntux.net/blog/?s=smtp+server" rel="tag"> smtp server</a>, <a href="http://syntux.net/blog/?s=spamhaus" rel="tag"> spamhaus</a>, <a href="http://syntux.net/blog/?s=sorbs" rel="tag"> sorbs</a>, <a href="http://syntux.net/blog/?s=zen" rel="tag"> zen</a>, <a href="http://syntux.net/blog/?s=colleagues" rel="tag"> colleagues</a>, <a href="http://syntux.net/blog/?s=spam" rel="tag"> spam</a>, <a href="http://syntux.net/blog/?s=dnsbl" rel="tag"> dnsbl</a>, <a href="http://syntux.net/blog/?s=korea" rel="tag"> korea</a>, <a href="http://syntux.net/blog/?s=hell" rel="tag"> hell</a>, <a href="http://syntux.net/blog/?s=pbl" rel="tag"> pbl</a>, <a href="http://syntux.net/blog/?s=linux" rel="tag"> linux </a></p>
<p>&copy;2012 <a href="http://syntux.net/blog">Don&#039;t Say Geek! Say Syntux!</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://syntux.net/blog/2007/02/13/postfix-options/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing your code</title>
		<link>http://syntux.net/blog/2006/12/12/testing-your-code/</link>
		<comments>http://syntux.net/blog/2006/12/12/testing-your-code/#comments</comments>
		<pubDate>Tue, 12 Dec 2006 07:38:20 +0000</pubDate>
		<dc:creator>Alaa</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[automated tests]]></category>
		<category><![CDATA[business development]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[functionality]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[nature of business]]></category>
		<category><![CDATA[sizeof]]></category>

		<guid isPermaLink="false">http://syntux.net/blog/2006/12/12/testing-your-code/</guid>
		<description><![CDATA[Perhaps no other coding practice is as important as testing your code. Also in the nature of Business Development, where parts of your code always change on the request of a client (including Management), or even when you want to make your code run with better performance, Automated tests are highly needed, you can&#8217;t just [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps no other coding practice is as important as testing your code. Also in the nature of Business Development, where parts of your code always change on the request of a client (including Management), or even when you want to make your code run with better performance, Automated tests are highly needed, you can&#8217;t just spread your print statements all over your code every time you need to test it.<br />
With automated tests, you can just be sure that your interface is not broken after some change, you just run your tests, if they succeed, you know that you didn&#8217;t break your code (this means you should right good tests).<br />
Let&#8217;s start by a simple example, Imagine that we have been asked to test PHP&#8217;s built-in Array. One bit of functionality to test is the function sizeof(). For a newly created array we expect the sizeof() function to return 0. After we add an element, sizeof()  should return 1. (I know it&#8217;s not a big deal, but it&#8217;s just an example).<br />
you can do it with simple print statements (i.e. print (1 == sizeof($myArray) ? &quot;OK&quot;:&quot;Failure&quot;).PHP_EOL; ), but here we are going to do it by using an assertion function.</p>
<p><coolcode lang="php"><br />
< ?php<br />
$fixture = Array();<br />
assertTrue(sizeof($fixture) == 0);</p>
<p>$fixture[] = "element";<br />
assertTrue(sizeof($fixture) == 1);</p>
<p>function assertTrue($condition) {<br />
  if (!$condition) {<br />
    throw new Exception("Assertion failed.");<br />
  }<br />
}<br />
?><br />
</coolcode><br />
Well, we could know if something went wrong if some Exception was raised, of course assertTrue is not the only thing you want to do, UnitTesting has gone far beyond that, usually UnitTesting frameworks provide a whole lot of features that you need for your testing.<br />
Lot&#8217;s of Testing frameworks are available for PHP, I&#8217;m going to point to 2 of them, the first one is SimpleTest (<a href="http://simpletest.org/">http://simpletest.org/</a>), it&#8217;s written in PHP 4 (Although they are going to migrate to PHP 5 when they reach version 2), so you can use it on both PHP 4 and 5 programs, also it includes a nice HTML reporter for some good looking html results the same test above could be written using this framework as:<br />
<coolcode lang="php"><br />
< ?php<br />
require_once 'simpletest/unit_tester.php';<br />
require_once 'simpletest/reporter.php';</p>
<p>class TestingFixtureArray extends UnitTestCase {<br />
  function TestArray() {<br />
    $this->UnitTestCase(&#8220;Testing Fixture Array&#8221;);<br />
    $fixture = Array();<br />
    $this->assertTrue(sizeof($fixture) == 0);</p>
<p>    $fixture[] = &#8220;element&#8221;;<br />
    $this->assertTrue(sizeof($fixture) == 1);<br />
  }<br />
}</p>
<p>//run the Test<br />
$test = new TestingFixtureArray();<br />
$test->run(new HtmlReporter());<br />
?><br />
</coolcode><br />
Another Well know testing framework is known as PHPUnit2 (<a href="http://www.phpunit.de/">http://www.phpunit.de/</a>), it&#8217;s available through the PEAR Repository, you can install it as<br />
<em>$ pear install PHPUnit2</em><br />
It&#8217;s written in PHP 5, and is so widely used within PHP Developers, a good resource for learning how to use it is the free available online book PHPUnit Pocket Guide (<a href="http://www.phpunit.de/pocket_guide/index.en.php">http://www.phpunit.de/pocket_guide/index.en.php</a>), the same example could be:<br />
<coolcode lang="php"><br />
< ?php<br />
require_once 'PHPUnit2/Framework/TestCase.php';</p>
<p>class ArrayTest extends PHPUnit2_Framework_TestCase {<br />
  public function testNewArrayIsEmpty() {<br />
    // Create the Array fixture.<br />
    $fixture = Array();</p>
<p>    // Assert that the size of the Array fixture is 0.<br />
    $this->assertEquals(0, sizeof($fixture));<br />
  }</p>
<p>  public function testArrayContainsAnElement() {<br />
    // Create the Array fixture.<br />
    $fixture = Array();</p>
<p>    // Add an element to the Array fixture.<br />
    $fixture[] = &#8216;Element&#8217;;</p>
<p>    // Assert that the size of the Array fixture is 1.<br />
    $this->assertEquals(1, sizeof($fixture));<br />
  }<br />
}<br />
?><br />
</coolcode><br />
and you can run it on command line as<br />
<em>$ phpunit ArrayTest</em></p>
<p>Additional benefits that you can realize by thoroughly testing your code:</p>
<ul>
<li>Testing forces you to write code that is easily testable. This leads to looser coupling, flexible designs, and good modularity.</li>
<li>Writing tests forces you to explicitly clarify your expectations of how your code is to behave, distilling your design into sharper focus from the beginning. Writing tests forces you to consider the universe of possible inputs and the corresponding results.</li>
<li>Tests are very explicit way of communicating the intent of your code. In other words, test cases act as example and documentation, showing exactly how a given class, method, or function should behave. A test case defines how code works in a non-ambiguous way.</li>
</ul>
<p>Finally, if your test suite &#8211; your set of test cases &#8211; is very thorough, you can say your code is complete when all of your test pass. Interestingly, that notion is one of the hallmarks of Test Driven Development.<br />
Test Driven Development (TDD), also referred to as Test First Coding, is a methodology that takes testing one step further: you write your tests before you ever write any code. A nice, brief summary of the tenants of TDD is available at <a href="http://xprogramming.com/xpmag/testFirstGuidelines.htm">http://xprogramming.com/xpmag/testFirstGuidelines.htm</a>, and a good introductory book on the strategy is <a href="http://www.amazon.com/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530">&#8220;Test Driven Development: By Example&#8221; by Kent Beck</a>. (The book&#8217;s examples are in Java, but it&#8217;s a quick read and gives you a very good overview and introduction to the subject.)</p>
<p><font size="2">Agile Development<br />
Recently, unit testing &#8211; in particular Test Driven Development &#8211; has been associated with agile Development methodologies such as Extreme Programming (XP)g that focus on rapid iterations of releasing functional code to customers and welcoming changing customer requirements as a natural part of the development process. Some good online resources for learning about agile development include:<br />
</font></p>
<ul>
<li><font size="2"><a href="http://en.wikikpedia.org/wiki/Agile_software_development">http://en.wikikpedia.org/wiki/Agile_software_development</a></font></li>
<li><font size="2"><a href="http://agilemanifesto.org/">http://agilemanifesto.org/</a></font></li>
<li><font size="2"><a href="http://www.extremeprogramming.org/">http://www.extremeprogramming.org</a></font></li>
</ul>
<p>Tags: <a href="http://syntux.net/blog/?s=automated+tests" rel="tag"> automated tests</a>, <a href="http://syntux.net/blog/?s=sizeof" rel="tag"> sizeof</a>, <a href="http://syntux.net/blog/?s=business+development" rel="tag"> business development</a>, <a href="http://syntux.net/blog/?s=array" rel="tag"> array</a>, <a href="http://syntux.net/blog/?s=functionality" rel="tag"> functionality</a>, <a href="http://syntux.net/blog/?s=element" rel="tag"> element</a>, <a href="http://syntux.net/blog/?s=nature+of+business" rel="tag"> nature of business</a>, <a href="http://syntux.net/blog/?s=interface" rel="tag"> interface</a></p>
<p>&copy;2012 <a href="http://syntux.net/blog">Don&#039;t Say Geek! Say Syntux!</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://syntux.net/blog/2006/12/12/testing-your-code/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Advanced Caching Technique &#8211; Block Randomization</title>
		<link>http://syntux.net/blog/2006/08/21/advanced-caching-technique-block-randomization/</link>
		<comments>http://syntux.net/blog/2006/08/21/advanced-caching-technique-block-randomization/#comments</comments>
		<pubDate>Mon, 21 Aug 2006 13:31:12 +0000</pubDate>
		<dc:creator>Ammar Ibrahim</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[all sorts]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[blogs]]></category>
		<category><![CDATA[dynamic content]]></category>
		<category><![CDATA[lifetime]]></category>
		<category><![CDATA[output html]]></category>
		<category><![CDATA[output options]]></category>
		<category><![CDATA[php4]]></category>
		<category><![CDATA[pleasent experience]]></category>
		<category><![CDATA[random posts]]></category>
		<category><![CDATA[simple solution]]></category>

		<guid isPermaLink="false">http://syntux.net/blog/2006/08/21/advanced-caching-technique-block-randomization/</guid>
		<description><![CDATA[Introduction I&#8217;m currenlty working on a site where I want to improve performance of dynamic pages. One of the greatest techniques to do is to cache dynamic content and serve the generated output (HTML). It&#8217;s not as easy as we all want it to be when you have all sorts of weird blocks on the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>I&#8217;m currenlty working on a site where I want to improve performance of dynamic pages. One of the greatest techniques to do is to cache dynamic content and serve the generated output (HTML).</p>
<p>It&#8217;s not as easy as we all want it to be when you have all sorts of weird blocks on the page: User login area, random content, ..etc</p>
<p>As I had a very pleasent experience with eZ components last week, I decided to take a look at the components, but then i remembered it works on PHP5. This project is on PHP4, I had to look for an alternative and decided to use PEAR::Cache_Lite.</p>
<p><span id="more-23"></span></p>
<p><strong>Example</strong></p>
<p><img alt="Blocks" id="image22" src="http://syntux.net/blog/wp-content/uploads/2006/08/cache-ex.gif" /><br />
In the figure above we can see that we have 4 content blocks coming from tha database, let&#8217;s assume this is our homepage. And let&#8217;s also assume that we are trying to get random content, e.g. 3 random blogs, 3 random posts ..etc</p>
<p>An example would look something like this before caching</p>
<p>[coolcode lang="php"]</p>
<p>$query = &#8220;SELECT title, username FROM blogs ORDER BY RAND() LIMIT 3&#8243;;<br />
$result=mysql_query($query);</p>
<p>while( $row = mysql_fetch_assoc($result) ){</p>
<p>echo $row['title'];</p>
<p>}</p>
<p>[/coolcode]</p>
<p><strong>Caching: Take 1</strong></p>
<p>We can easily cache this block using Cache_Lite output caching as follows:</p>
<p>[coolcode lang="php"]</p>
<p>require_once &#8216;Cache/Lite/Output.php&#8217;;</p>
<p>$options = array(<br />
&#8216;cacheDir&#8217;     => &#8216;/tmp/site_cache/&#8217;,<br />
&#8216;lifeTime&#8217;    => 1000,<br />
);</p>
<p>$cache = new Cache_Lite_Output($options);<br />
if (!($cache->start(&#8216;blogs_block&#8217; ))) {<br />
// Cache missed&#8230; start caching this block</p>
<p>$query = &#8220;SELECT title, username FROM blogs ORDER BY RAND() LIMIT 3&#8243;;<br />
$result=mysql_query($query);</p>
<p>while( $row = mysql_fetch_assoc($result) ){</p>
<p>echo $row['title'];</p>
<p>}</p>
<p>}</p>
<p>[/coolcode]</p>
<p>Well, there&#8217;s a clear problem, after the first hit, the block will be cached, and anyone who vists the page during the lifetime of the cache will keep seeing the same block! This abuses the whole concept of serving random content. We need to figure out a solution&#8230;</p>
<p><strong>Caching: Take 2</strong></p>
<p>I came up with a very simple solution! I will make the content appear as random, but infact it is cached, just modify the line that starts the cache as follows:</p>
<p>[coolcode lang="php"]</p>
<p>if (!($cache->start(&#8216;blogs_block&#8217; . rand(1,10) ))) {<br />
[/coolcode]</p>
<p>What this does is allow for caching of 10 blocks, this will do the trick, give the users  10 cached blocks. If we have  4 different content blocks and allow 10 random blocks each, we end up by having 10x10x10x10 =10000 different page combinations.</p>
<p><strong>Caching: Take 3</strong></p>
<p>While the solution above meets my needs, I need something a bit cleaner than having rand() everytime. The first solution I came up with was to write the following class that extends Cache_lite and allows for cache randomization. Download the Class.</p>
<p>Using the cache randomizer is very simple, here&#8217;s an example.</p>
<p>[coolcode lang="php"]</p>
<p>require_once &#8216;Cache/Lite/Output/Random.php&#8217;;</p>
<p>$options = array(<br />
&#8230;&#8230;&#8230;.<br />
);</p>
<p>$cache = new Cache_Lite_Output_Random($options);</p>
<p>//Set the number of random blocks to be cached<br />
$cache->setRand( 10 );</p>
<p>if (!($cache->start(&#8216;blogs_block&#8217; ))) {<br />
// Cache missed&#8230; start caching this block</p>
<p>$query = &#8220;SELECT title, username FROM blogs ORDER BY RAND() LIMIT 3&#8243;;<br />
$result=mysql_query($query);</p>
<p>while( $row = mysql_fetch_assoc($result) ){</p>
<p>echo $row['title'];<br />
}</p>
<p>}</p>
<p>//to disable caching and go back to normal behaviour to keep using the same object<br />
$cache->clearRand();</p>
<p>//to change the number of random blocks for another block<br />
$cache->setRand( 20 );<br />
[/coolcode]</p>
<p><strong>Conclusion</strong></p>
<p>Random block caching is very useful when you want to acheive high performance, yet allow random content from a datasource (Database). If we had a page with 4 blocks, and allow 10 random blocks, we get (Theoritically) 10000 page combinations. Although we only have 40 cache blocks stored on the server.</p>
<p>Tags: <a href="http://syntux.net/blog/?s=pleasent+experience" rel="tag"> pleasent experience</a>, <a href="http://syntux.net/blog/?s=random+posts" rel="tag"> random posts</a>, <a href="http://syntux.net/blog/?s=output+html" rel="tag"> output html</a>, <a href="http://syntux.net/blog/?s=output+options" rel="tag"> output options</a>, <a href="http://syntux.net/blog/?s=simple+solution" rel="tag"> simple solution</a>, <a href="http://syntux.net/blog/?s=dynamic+content" rel="tag"> dynamic content</a>, <a href="http://syntux.net/blog/?s=php4" rel="tag"> php4</a>, <a href="http://syntux.net/blog/?s=pear" rel="tag"> pear</a>, <a href="http://syntux.net/blog/?s=all+sorts" rel="tag"> all sorts</a>, <a href="http://syntux.net/blog/?s=lifetime" rel="tag"> lifetime</a>, <a href="http://syntux.net/blog/?s=array" rel="tag"> array</a>, <a href="http://syntux.net/blog/?s=blogs" rel="tag"> blogs </a></p>
<p>&copy;2012 <a href="http://syntux.net/blog">Don&#039;t Say Geek! Say Syntux!</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://syntux.net/blog/2006/08/21/advanced-caching-technique-block-randomization/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>eZ components &#8220;Mail&#8221; to save the day</title>
		<link>http://syntux.net/blog/2006/08/14/ez-components-mail-to-save-the-day/</link>
		<comments>http://syntux.net/blog/2006/08/14/ez-components-mail-to-save-the-day/#comments</comments>
		<pubDate>Mon, 14 Aug 2006 09:08:40 +0000</pubDate>
		<dc:creator>Ammar Ibrahim</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[attachements]]></category>
		<category><![CDATA[attachments]]></category>
		<category><![CDATA[e mail]]></category>
		<category><![CDATA[edited version]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[ez systems]]></category>
		<category><![CDATA[few days]]></category>
		<category><![CDATA[fi]]></category>
		<category><![CDATA[fpm]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[mail body]]></category>
		<category><![CDATA[mail messages]]></category>
		<category><![CDATA[multipart messages]]></category>
		<category><![CDATA[norway]]></category>
		<category><![CDATA[package mail]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[rfcs]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[solidarity campaign]]></category>

		<guid isPermaLink="false">http://syntux.net/blog/2006/08/14/ez-components-mail-to-save-the-day/</guid>
		<description><![CDATA[A few days ago I was asked to develop a simple script for a solidarity campaign. The idea is that people send their photos as attachements to some email. The script would download all images attached and insert a record for that in the database. I got introduced to eZ components during my last visit [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I was asked to develop a simple script for a solidarity campaign. The idea is that people send their photos as attachements to some email. The script would download all images attached and insert a record for that in the database.</p>
<p>I got introduced to <a title="eZ components" href="http://ez.no/products/ez_components">eZ components</a> during my last visit to Norway to attend the eZ systems conference. I decided to give it a shot, and oh boy it&#8217;s just amazing, probably the cleanest and simplest API ever.</p>
<p>I managed to find the package &#8220;Mail&#8221;:</p>
<blockquote><p>The components allows you construct Mail messages conforming to the RFCs. It has support for attachments, multipart messages and HTML mail. It also interfaces with SMTP to send the e-mail. Reading and parsing mail messages comes in version 1.1.</p></blockquote>
<p>The package is <a href="http://ez.no/doc/components/view/1.1/(file)/classtrees_Mail.html">well documented</a> and includes many examples. Here&#8217;s the script I ended up writing (edited version):<br />
<span id="more-20"></span><br />
[coolcode lang="php"]<br />
< ?php<br />
define( 'PHOTOS_DIR', 'email_photos/' );<br />
define( 'FILE_PARSED_MAILS', '.fpm' );</p>
<p>require_once 'Base/src/base.php';<br />
function __autoload( $className )<br />
{<br />
ezcBase::autoload( $className );<br />
}</p>
<p>//get the list of emails that we alread processed<br />
$parsedEmailsIds = array();<br />
$parsedEmailsIds = @unserialize( file_get_contents(FILE_PARSED_MAILS) );</p>
<p>if( 'array' != gettype($parsedEmailsIds) ){<br />
$parsedEmailsIds = array();<br />
}</p>
<p>$pop3 = new ezcMailPop3Transport( 'mail.example.org' );<br />
$pop3->authenticate( &#8216;username&#8217;, &#8216;password&#8217; );</p>
<p>//get the list of emails from the server<br />
$severEmailsIds = $pop3->listUniqueIdentifiers();<br />
$emailsToFetch = array_diff($severEmailsIds, $parsedEmailsIds);<br />
if( !count($emailsToFetch) ){<br />
//no emails to get!<br />
exit;<br />
}</p>
<p>$set = $pop3->fetchAll(false, $emailsToFetch );<br />
$parser = new ezcMailParser();<br />
$parser->setTmpDir( &#8216;tmp/&#8217; );<br />
$mails = $parser->parseMail( $set );</p>
<p>foreach ( $mails as $mail )<br />
{</p>
<p>//Get email parts<br />
foreach( $mail->body->getParts() as $part ){<br />
if( get_class($part) == &#8216;ezcMailFile&#8217; ){</p>
<p>//get the destination file name after some cleanups<br />
$fileName = nameToSafe( basename($part->fileName) );</p>
<p>//the new destintation filename, this function makes sure we get a unique file name everytime<br />
$destFileName = PHOTOS_DIR . nameToSeq(PHOTOS_DIR,$fileName);</p>
<p>rename( $part->fileName, $destFileName );</p>
<p>}</p>
<p>//after we&#8217;re done, we need to update the file that stores the list of parsed emails<br />
file_put_contents( FILE_PARSED_MAILS, serialize( $severEmailsIds ) );</p>
<p>?></p>
<p>[/coolcode]</p>
<p>I&#8217;m sure there&#8217;s a better way to get the <em>new </em>emails only, probably with <a href="http://www.php.net/var_export">var_export</a>()</p>
<p><strong> Note</strong>: The only problem I faced, which is VERY strange, is the ability to fetch a single email or list of emails. Surprisingly, the API didn&#8217;t provide such feature. I did an ugly hack to &#8220;Mail/transports/pop3/pop3_transport.php&#8221; to function fetchAll(), I should have created another function, but I was in a hurry. Here&#8217;s the modified version:</p>
<p>[coolcode lang="php"]<br />
/**<br />
* @throws ezcMailTransportException if the mail could not be retrieved.<br />
* @param bool $deleteFromServer<br />
* @param array $messages<br />
* @return ezcMailParserSet<br />
*/<br />
public function fetchAll( $deleteFromServer = false, $messages = null )<br />
{<br />
if( !isset($messages) ){<br />
$message = $this->listMessages();<br />
}<br />
return new ezcMailPop3Set( $this->connection, array_keys( $messages ), $deleteFromServer );<br />
}</p>
<p>[/coolcode]</p>
<div class="cbw snap_nopreview">
<div class="cbw_header"><script src="http://www.crunchbase.com/javascripts/widget.js" type="text/javascript"></script>
<div class="cbw_header_text"><a href="http://www.crunchbase.com/">CrunchBase Information</a></div>
</div>
<div class="cbw_content">
<div class="cbw_subheader"><a href="http://www.crunchbase.com/company/ez-systems">eZ Systems</a></div>
<div class="cbw_subcontent"><script src="http://www.crunchbase.com/cbw/company/ez-systems.js" type="text/javascript"></script></div>
<div class="cbw_footer">Information provided by <a href="http://www.crunchbase.com/">CrunchBase</a></div>
</div>
</div>
<p>Tags: <a href="http://syntux.net/blog/?s=package+mail" rel="tag"> package mail</a>, <a href="http://syntux.net/blog/?s=mail+body" rel="tag"> mail body</a>, <a href="http://syntux.net/blog/?s=solidarity+campaign" rel="tag"> solidarity campaign</a>, <a href="http://syntux.net/blog/?s=mail+messages" rel="tag"> mail messages</a>, <a href="http://syntux.net/blog/?s=multipart+messages" rel="tag"> multipart messages</a>, <a href="http://syntux.net/blog/?s=ez+systems" rel="tag"> ez systems</a>, <a href="http://syntux.net/blog/?s=attachements" rel="tag"> attachements</a>, <a href="http://syntux.net/blog/?s=edited+version" rel="tag"> edited version</a>, <a href="http://syntux.net/blog/?s=fpm" rel="tag"> fpm</a>, <a href="http://syntux.net/blog/?s=rfcs" rel="tag"> rfcs</a>, <a href="http://syntux.net/blog/?s=e+mail" rel="tag"> e mail</a>, <a href="http://syntux.net/blog/?s=parsing" rel="tag"> parsing</a>, <a href="http://syntux.net/blog/?s=smtp" rel="tag"> smtp</a>, <a href="http://syntux.net/blog/?s=array" rel="tag"> array</a>, <a href="http://syntux.net/blog/?s=few+days" rel="tag"> few days</a>, <a href="http://syntux.net/blog/?s=attachments" rel="tag"> attachments</a>, <a href="http://syntux.net/blog/?s=email" rel="tag"> email</a>, <a href="http://syntux.net/blog/?s=norway" rel="tag"> norway</a>, <a href="http://syntux.net/blog/?s=fi" rel="tag"> fi</a>, <a href="http://syntux.net/blog/?s=images" rel="tag"> images </a></p>
<p>&copy;2012 <a href="http://syntux.net/blog">Don&#039;t Say Geek! Say Syntux!</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://syntux.net/blog/2006/08/14/ez-components-mail-to-save-the-day/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

