<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>David Golding</title>
	
	<link>http://www.davidgolding.net</link>
	<description>CakePHP, Cappuccino, Objective-J, and otherwise Web Musings</description>
	<lastBuildDate>Tue, 13 Sep 2011 20:19:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DavidGolding" /><feedburner:info uri="davidgolding" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>New to Lithium: Part 1</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/AxiLmWA-Ujo/new-to-lithium-part-1.html</link>
		<comments>http://www.davidgolding.net/lithium/new-to-lithium-part-1.html#comments</comments>
		<pubDate>Fri, 12 Aug 2011 07:19:51 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=296</guid>
		<description><![CDATA[I enjoy writing prose more than writing code, though I must say that the two writing environments seem to reinforce each other. I come to understand complexity by distilling it to its most basic logic, and putting programming concepts into prose serves to sharpen my coding skills. So as an exercise in bringing together code [...]]]></description>
			<content:encoded><![CDATA[<p>I enjoy writing prose more than writing code, though I must say that the two writing environments seem to reinforce each other. I come to understand complexity by distilling it to its most basic logic, and putting programming concepts into prose serves to sharpen my coding skills. So as an exercise in bringing together code and prose, I&#8217;ve put together a draft of a tutorial for newcomers to the Lithium framework.</p>
<p>The tutorial is available as &#8220;New to Lithium&#8221; and is the first installment in what I hope can be a series of articles working with Lithium at the most basic levels through more moderate and advanced concepts. Be advised that this is only a draft. I&#8217;m making it available in the hopes that it generates feedback and serves the Lithium community in some constructive way. Feel free to provide critical feedback in the comments here or shoot me a line on Scribd where the document is currently published.</p>
<p><a href="http://www.scribd.com/doc/62146078/New-to-Lithium-Part-1">Read the first part of &#8220;New to Lithium&#8221; on Scribd</a></p>
<p><a href='http://www.davidgolding.net/wp-content/uploads/2011/09/new-to-lithium_1.pdf'>Download PDF Version</a></p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/AxiLmWA-Ujo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/lithium/new-to-lithium-part-1.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/lithium/new-to-lithium-part-1.html</feedburner:origLink></item>
		<item>
		<title>Running Authorize.net Transactions in Lithium</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/QnbeXYa3UbY/running-authorize-net-transactions-in-lithium.html</link>
		<comments>http://www.davidgolding.net/lithium/running-authorize-net-transactions-in-lithium.html#comments</comments>
		<pubDate>Tue, 12 Jul 2011 18:13:52 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=293</guid>
		<description><![CDATA[Here&#8217;s a class I built for running transactions in Lithium. More information is available on the GitHub page. Be sure to check it out. It&#8217;s meant for use in Lithium, but with some minor tweaking, could be used in almost any PHP script. Just delete the namespace line and references to the parent class, and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.github.com/davidgolding/Authorizer">Here&#8217;s a class</a> I built for running transactions in Lithium. More information is available on the GitHub page. Be sure to check it out. It&#8217;s meant for use in Lithium, but with some minor tweaking, could be used in almost any PHP script. Just delete the namespace line and references to the parent class, and it should still work fine.</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/QnbeXYa3UbY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/lithium/running-authorize-net-transactions-in-lithium.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/lithium/running-authorize-net-transactions-in-lithium.html</feedburner:origLink></item>
		<item>
		<title>Lithium for Newbies</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/r8_yJ0bPOSE/lithium-for-newbies.html</link>
		<comments>http://www.davidgolding.net/lithium/lithium-for-newbies.html#comments</comments>
		<pubDate>Thu, 30 Jun 2011 23:02:16 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=291</guid>
		<description><![CDATA[I have a special place in my heart for newbies, mostly because at one level or another I&#8217;m always a newbie to something out there. Technology and computing just has a way of always keeping us on our toes, always learning and relearning things, which I take as an excellent sign that legitimate improvements have [...]]]></description>
			<content:encoded><![CDATA[<p>I have a special place in my heart for newbies, mostly because at one level or another I&#8217;m always a newbie to something out there. Technology and computing just has a way of always keeping us on our toes, always learning and relearning things, which I take as an excellent sign that legitimate improvements have occurred in our respective platforms and fields. It has now been over a year that I&#8217;ve been working with <a href="http://lithify.me">Lithium</a> and while the documentation effort for this framework has grown and improved significantly, I keep finding folks asking about how newcomers to the framework can get their feet wet. It seems there is still demand for a set of docs geared toward the absolute newbie, or perhaps the expert in one area of web development but a novice at Lithium&#8217;s unique (and fabulous) combination of aspect-oriented, object-oriented, MVC, and structured storage (NoSQL) paradigms.</p>
<p>I should apologize: this post isn&#8217;t about actually providing these docs or explaining Lithium to newbies. Rather, it is an invitation for the Lithium community to join me in remembering the freshman class of our larger professional network. Strange as it may seem, my day job is actually in academics: I&#8217;m wrapping up a PhD in religious studies at Claremont Graduate University and have worked as a professor in teaching the more abstracted and secular approach to understanding religion and religious movements. And if there&#8217;s one thing I&#8217;ve learned in this field, it&#8217;s that the life blood of any social movement is the youths in the crowd, the converts, the rising generation. Those movements that lead these new initiates by the hand endure better than those that stand on the sideline while people transition.</p>
<p>I believe a key opportunity to capture more interest and users to the Lithium platform just surfaced: with the release of <a href="http://dev.lithify.me/lithium/wiki/blog/Getting-Ourselves-Together-Lithium-0-10">Lithium 0.10</a>, MySQL and model associations <a href="http://masom.posterous.com/relationships-in-lithium-010">are now supported</a> to enough of a degree that a far wider net of PHP developers can transition over to what is more importantly concepts and structures Lithium provides that other frameworks don&#8217;t, or maybe don&#8217;t do very well. The time for a robust entrée to Lithium for this wider constituency of developers is now.</p>
<p>Billionaire entrepreneurs have made a mantra of the three most important aspects of a successful business plan: &#8220;Location, location, location.&#8221; If I were to translate this clichéd mantra for developer communities, it&#8217;d be &#8220;documentation, documentation, documentation.&#8221; (Sorry, Steve Ballmer, but it&#8217;s not <a href="http://www.youtube.com/watch?v=KMU0tzLwhbE">developers</a> that count: you don&#8217;t have developers without docs.)</p>
<p>I would like to try my hand at writing newbie docs, but I will make one confession: I already know that these will have to be rough drafts because of my own learning curve at play. But the real strength of open source communities is their collective writing process. So I&#8217;ll be forking <a href="https://github.com/UnionOfRAD/manual/tree/master/en">the Lithium manual on GitHub</a> and re-posting any updates I make to it here for your editorial comments. Screencasts are an especially effective medium for teaching processes and concepts; maybe I&#8217;ll be able to put some together as well. And last, but not least, I&#8217;d like to err on the side of trying when offering solutions in forums, chat rooms, and Q&#038;A sites. If there&#8217;s a more elegant way to accomplish something, I&#8217;ll invite your critique. It&#8217;d be a tragedy if we held back in giving advice and in sharing solutions for fear of being called out or corrected in public view. When there&#8217;s such a fabulous tool coming out of a group of developers, I have to believe there&#8217;s something more to the community at work. I like to think that something includes a genuine camaraderie that anyone new to anything would appreciate, from one developer to another.</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/r8_yJ0bPOSE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/lithium/lithium-for-newbies.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/lithium/lithium-for-newbies.html</feedburner:origLink></item>
		<item>
		<title>Cappuccino and Titanium for Building Desktop Apps</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/1uLk8CMugeM/cappuccino-and-titanium-for-building-desktop-apps.html</link>
		<comments>http://www.davidgolding.net/cappuccino/cappuccino-and-titanium-for-building-desktop-apps.html#comments</comments>
		<pubDate>Wed, 15 Jun 2011 18:03:33 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Cappuccino]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=288</guid>
		<description><![CDATA[Just discovered how easy it is to get a desktop app off the ground with Cappuccino and Titanium frameworks. 280North, the developers behind Cappuccino, have already created a beta of Atlas that enables you to distribute a Cappuccino application for the desktop. Atlas is fabulous, but it renders the interface using its own skin and [...]]]></description>
			<content:encoded><![CDATA[<p>Just discovered how easy it is to get a desktop app off the ground with <a href="http://cappuccino.org">Cappuccino</a> and <a href="http://www.appcelerator.com">Titanium</a> frameworks. 280North, the developers behind Cappuccino, have already created a beta of <a href="http://280atlas.com">Atlas</a> that enables you to distribute a Cappuccino application for the desktop. Atlas is fabulous, but it renders the interface using its own skin and not the native Cocoa window. Windows, therefore, aren&#8217;t bounded to the screen&#8217;s edges and resize fairly clumsily.</p>
<p>Titanium provides a useful platform for not only building desktop apps that are more consistent with the operating system&#8217;s UI, but also allows for cross-platform distribution to Mac, Windows, Linux, and even the major mobile platforms like iOS and Android. Because Titanium caters to web developers, it makes sense to combine the powers of Cappuccino and Titanium to leverage the strengths of both frameworks. Cappuccino ports sleek Cocoa concepts to its own JavaScript superclasses (Objective-J), making it possible to develop powerful web applications with the same feel and consistency as desktop applications. It has already succeeded well at bringing the powers of the desktop to the web browser; for one example, check out 280North&#8217;s <a href="http://280slides.com">280 Slides</a> application. (It&#8217;s essentially Keynote in the web browser.)</p>
<p>Combining the two frameworks was a simple two-step process. First, I got a Titanium desktop application project started. Second, I placed the contents of the main Cappuccino project into the Resources directory in the Titanium project directory, replacing the index.html file that comes with Titanium with the one used by Cappuccino. That was it. Now I can proceed to apply Titanium goodness where I like and base most of the application in Cappuccino. At this point, I&#8217;ll have to test for conflicts between the Titanium SDK and Objective-J, but so far, it&#8217;s been smooth as butter.</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/1uLk8CMugeM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/cappuccino/cappuccino-and-titanium-for-building-desktop-apps.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/cappuccino/cappuccino-and-titanium-for-building-desktop-apps.html</feedburner:origLink></item>
		<item>
		<title>Installing MongoDB on MAMP 1.9.5</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/u3CutQV_kWI/installing-mongodb-on-mamp-1-9-5.html</link>
		<comments>http://www.davidgolding.net/mongodb/installing-mongodb-on-mamp-1-9-5.html#comments</comments>
		<pubDate>Sat, 12 Mar 2011 07:13:03 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[MongoDB]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=277</guid>
		<description><![CDATA[Appsolute launched MAMP version 1.9.5 today, so I thought it&#8217;d be a great time to add MongoDB to it and improve my NoSQL skills. 1. Prepare MAMP for MongoDB files Create a new folder at Applications/MAMP/db/mongo with three additional subfolders named bin, data, and tmp. Provide these folders with chmod 0755 access permissions. These folders [...]]]></description>
			<content:encoded><![CDATA[<p>Appsolute launched <a href="http://mamp.info/en/downloads/index.html">MAMP version 1.9.5</a> today, so I thought it&#8217;d be a great time to add MongoDB to it and improve my NoSQL skills.</p>
<h3>1. Prepare MAMP for MongoDB files</h3>
<p>Create a new folder at <b>Applications/MAMP/db/mongo</b> with three additional subfolders named <b>bin</b>, <b>data</b>, and <b>tmp</b>. Provide these folders with <b>chmod 0755</b> access permissions. These folders will be the main runtime location for Mongo once MAMP gets it running.</p>
<h3>2. Download MongoDB</h3>
<p>Grab the <a href="http://www.mongodb.org/downloads">latest Mac OS install package of MongoDB</a>. My server setup called for OS X 64-bit, version 1.6.5. It&#8217;ll have a directory named <b>bin</b>. Drop the files from this folder into the <b>/Applications/MAMP/db/mongo/bin</b> folder you already created.</p>
<h3>3. Download Mongo Driver for PHP</h3>
<p>I&#8217;m running PHP 5.3 (why use MongoDB with any earlier version of PHP?), so I&#8217;ll need the <b>mongo.so</b> extension to get PHP and Mongo working together. This is available at the MongoDB GitHub repository, <a href="https://github.com/mongodb/mongo-php-driver/downloads">under the PHP 5.3 for Mac binary</a>. After unpacking the downloaded file, place the <b>mongo.so</b> extension file in the <b>/Applications/MAMP/bin/php5.3/lib/php/extensions</b> folder.</p>
<div style="border: 1px solid #ccc; padding: 10px;"><b style="color: red;">Update:</b> An alternative is to place the <b>mongo.so</b> file in the <b>/Applications/MAMP/bin/php5.3/lib/php/extensions/no-debug-non-zts-20090626</b> folder and avoid having to edit the <b>php.ini</b> file. It appears that MAMP 1.9.5 already has the <b>extension=mongo.so</b> line in the extensions block of the <b>php.ini</b> file, even though version 1.9.5 doesn&#8217;t come bundled with Mongo.</div>
<h3>4. Create Startup Routines for MAMP</h3>
<p>Lastly, you&#8217;ll need to create the startup routines so that MAMP will launch Mongo along with MySQL and Apache. Create a new file at <b>/Applications/MAMP/bin/startMongo.sh</b> and place in it the following code:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># /bin/sh<br />
/Applications/MAMP/db/mongo/bin/mongod --dbpath /Applications/MAMP/db/mongo/data --logpath /Applications/MAMP/db/mongo/mongodb.log --pidfilepath /Applications/MAMP/db/mongo/tmp/mongo.pid --fork --logappend</div></td></tr></tbody></table></div>
</pre>
<p>When called, this script will launch Mongo using the MAMP-relative paths rather than Mongo&#8217;s system defaults.</p>
<p>Create another file at <b>/Applications/MAMP/bin/stopMongo.sh</b> and place the shutdown method:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># /bin/sh<br />
/bin/kill `cat /Applications/MAMP/db/mongo/tmp/mongo.pid`</div></td></tr></tbody></table></div>
</pre>
<p>This works like the previous script, except it kills the <b>mongo.pid</b> process, effectively shutting down Mongo.</p>
<p>To have MAMP automatically call these Mongo startup scripts, open the <b>/Applications/MAMP/bin/start.sh</b> and <b>/Applications/MAMP/bin/stop.sh</b> files, and insert the following lines above the <b>startMysql.sh</b> lines, respectively:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/Applications/MAMP/bin/startMongo.sh</div></td></tr></tbody></table></div>
</pre>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/Applications/MAMP/bin/stopMongo.sh</div></td></tr></tbody></table></div>
</pre>
<p>Now MAMP will automatically launch Mongo upon startup.</p>
<p>The only thing left to do is tell PHP to run the <b>mongo.so</b> extension. If you&#8217;re running MAMP Pro, edit the php.ini file by selecting <b>File &gt; Edit Template &gt; PHP 5.3 php.ini</b>, otherwise you&#8217;ll need to lookup the path the php.ini file from the MAMP startup screen, under &#8220;phpInfo&#8221; and &#8220;Loaded Configuration File.&#8221;</p>
<p>Insert the following line in the php.ini file/template, save the file, then restart MAMP.</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">extension=&quot;/Applications/MAMP/bin/php5.3/lib/php/extensions/mongo.so&quot;</div></td></tr></tbody></table></div>
</pre>
<p>Mongo should now run in the background on MAMP, which you can connect with from PHP using the main connection routines listed on the <a href="http://www.php.net/manual/en/mongo.tutorial.php">PHP site</a>. Welcome to NoSQL on MAMP!</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/u3CutQV_kWI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/mongodb/installing-mongodb-on-mamp-1-9-5.html/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/mongodb/installing-mongodb-on-mamp-1-9-5.html</feedburner:origLink></item>
		<item>
		<title>A Quick Unit Test in Lithium 0.5</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/PqDhcsxoS7k/a-quick-unit-test-in-lithium-0-5.html</link>
		<comments>http://www.davidgolding.net/lithium/a-quick-unit-test-in-lithium-0-5.html#comments</comments>
		<pubDate>Sat, 06 Feb 2010 16:49:42 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=260</guid>
		<description><![CDATA[Unit testing has always proven a chore in past projects. But a necessary one. The more specific the testing, the more effectively one isolates problems in the code. Well, and the more aesthetic, provided one knows how to use unit testing right. I have found Lithium&#8217;s built-in unit testing environment amazingly simple, and since a [...]]]></description>
			<content:encoded><![CDATA[<p>Unit testing has always proven a chore in past projects. But a necessary one. The more specific the testing, the more effectively one isolates problems in the code. Well, and the more aesthetic, provided one knows how to use unit testing right. I have found <a href="http://www.lithify.me">Lithium&#8217;s</a> built-in unit testing environment amazingly simple, and since a couple of folks have asked me recently about this feature, I thought I&#8217;d post a very quick unit test just to demonstrate how even a beginner can take up unit testing in Lithium in minutes. (This example already assumes you have Lithium 0.5 working in your localhost environment; if you don&#8217;t, take a look at Union of Rad&#8217;s <a href="http://rad-dev.org/lithium/wiki/guides/installation">installation tutorial</a> or the project lead Garrett Woodworth&#8217;s <a href="http://lithify.me/li3-library-install.mov">screencast</a>.)</p>
<h3>Create the Test Class</h3>
<p>To launch Lithium&#8217;s unit test dashboard, simply add <span class="code">test</span> after your application&#8217;s root path. Assuming our new app is named &#8220;basic,&#8221; you&#8217;d type something like <span class="code">http://localhost/basic/test</span> as your URL. By default, the dashboard only displays Lithium&#8217;s core tests. Let&#8217;s add one for our own app to evaluate a model.</p>
<p>Create a model test file in <span class="code">app/tests/cases/models</span> and name it after the model class you intend to simulate. In my case, I&#8217;m testing a table holding data on composers for a sheet music application, so I&#8217;ll name my file <span class="code">ComposerTest.php</span>. Now, place some standard code in this file so that the test classes will execute the unit tests appropriately:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<br />
<span style="color: #000000; font-weight: bold;">namespace</span> app\tests\cases\models<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> \app\models\Composer<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ComposerTest <span style="color: #000000; font-weight: bold;">extends</span> \lithium\test\Unit <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<p>On line 3, we specify the namespace for this class, which corresponds to the path in the application where this test class appears. Lines 5 and 6 call two classes that will allow the <span class="code">ComposerTest</span> class to connect to the database and/or run methods in the <span class="code">Composer</span> model, which, of course, is my runtime model for all of my <span class="code">Composer</span> methods in the live app. Line 8 names the class following a convention: we add &#8220;Test&#8221; to the end of the model name we&#8217;re testing and we extend from the core unit testing class available as <span class="code">lithium/test/Unit.php</span>.</p>
<p>Go back to the unit test dashboard and your new test class should appear on the left under <span class="code">app > cases > models > ComposerTest</span>. Click the link to run tests on <span class="code">ComposerTest</span>, and the results should light up green with zero passes, fails, or exceptions.</p>
<h3>Perform a Unit Test</h3>
<p>A very basic unit test performs a query to see whether the model connects to the database and can fetch records. I&#8217;m going to write a test function that allows me to see whether my model can perform a basic find query. In the <span class="code">ComposerTest</span> class, I&#8217;ve written a function called <span class="code">testWhetherDbQueryWorks()</span> that asserts whether a result set is null or populated with table data. It looks like this:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testWhetherDbQueryWorks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> Composer<span style="color: #339933;">::</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'first'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><a href="http://www.php.net/empty"><span style="color: #990000;">empty</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Query did not pull data'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Simple enough. Lithium provides several other assertion methods, which are all described at <a href="http://lithify.me/docs/lithium/test/Unit">the Unit class entry in the Lithium API</a>.</p>
<p>Now, when I run the test in the dashboard, it ought to pass, provided I&#8217;ve set up my <span class="code">Composer</span> class correctly.</p>
<p>Hope this helps for those beginners out there looking to try out Lithium. I&#8217;ll try adding more detailed information, or using screencasts, when I&#8217;ve got a little more time for documenting my experiences in Lithium.</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/PqDhcsxoS7k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/lithium/a-quick-unit-test-in-lithium-0-5.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://lithify.me/li3-library-install.mov" length="10439265" type="video/quicktime" />
		<feedburner:origLink>http://www.davidgolding.net/lithium/a-quick-unit-test-in-lithium-0-5.html</feedburner:origLink></item>
		<item>
		<title>Transitioning from CakePHP to Lithium</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/f6ZgCexfTmI/transitioning-from-cakephp-to-lithium.html</link>
		<comments>http://www.davidgolding.net/cakephp/transitioning-from-cakephp-to-lithium.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 17:04:56 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=258</guid>
		<description><![CDATA[For anyone following the CakePHP project, you likely already know about the Cake3 project spinning off and becoming a separate framework called Lithium (li3 for short). After a couple of months of testing the Lithium framework and using it for my current web development needs, I&#8217;m so encouraged by the experience and the results, that [...]]]></description>
			<content:encoded><![CDATA[<p>For anyone following the CakePHP project, you likely already know about the Cake3 project spinning off and becoming a separate framework called <a href="http://www.lithify.me">Lithium</a> (li3 for short). After a couple of months of testing the Lithium framework and using it for my current web development needs, I&#8217;m so encouraged by the experience and the results, that I had to suggest to my readers that they consider making the transition from Cake to Lithium. As the framework nears its 1.0 release, I expect the core feature set to include all of the essentials that we Cake users already enjoy, but with some significant improvements. For those that appreciate good code like good art, Lithium is clearly a step in the right direction.</p>
<p>So far, I&#8217;ve only had occasion to try out a few features, and the outcomes have already been promising. Here are differences I&#8217;ve picked up from how things are done in Cake.</p>
<h3>Bootstrapping and Additional Libraries</h3>
<p>Lithium&#8217;s way of bootstrapping the various libraries allow for various server configuration settings more easily than Cake. Rather than defining constants in the <span class="code">app/webroot/index.php</span> file, server paths are stored in the <span class="code">app/config/boostrap.php</span> file. Only two constants need changing if you adjust the folder structure on your server: <span class="code">LITHIUM_LIBRARY_PATH</span>, which points to the core libraries directory, and <span class="code">LITHIUM_APP_PATH</span>, which points to the application itself. Other core settings may be included in <span class="code">bootstrap.php</span>; as good practice, I added</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://www.php.net/ini_set"><span style="color: #990000;">ini_set</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'display_errors'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Lithium uses third-party libraries much more seamlessly than Cake. Before, the scripts would have to be included through a vendors folder and brought into the application using, essentially, an include-like function. What I had wanted was a little more flexibility for where third-party scripts could be stored, since the possibilities for what third-party scripts require, in terms of server configuration and installations, usually call for install paths very different from how Cake structures itself in the background. Lithium provides a configuration file, <span class="code">app/config/boostrap/libraries.php</span>, which allows you to add libraries either with a <span class="code">require</span> directive or by using its built-in <span class="code">Libraries</span> class. I was able to drop the Doctrine ORM library in the <span class="code">app/libraries</span> directory and bring it into my app with:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Libraries<span style="color: #339933;">::</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Doctrine'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">'path'</span> <span style="color: #339933;">=&gt;</span> LITHIUM_APP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/libraries/doctrine/DoctrineORM-2.0.0/Doctrine'</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Easy enough!</p>
<h3>Namespaces and MVC</h3>
<p>How Lithium makes use of PHP 5.3&#8242;s namespaces improves the flexibility of building model and controller classes. In one app, I have a sheet music database that provides downloads to web users. On the home page, it provides a list of all the composers in the database and a list of the top ten most downloaded files. In Cake, to do this, the <span class="code">ComposersController</span> class has two options to fetch those top ten downloads. One is to perform a <span class="code">requestAction</span> call to the <span class="code">DownloadsController</span> class. The other is to call its own model class and perform a <span class="code">bindModel</span> on the <span class="code">Download</span> model, then run a <span class="code">find</span> method to pull the top ten downloads. This isn&#8217;t too difficult or bloated, code-wise, but notice how Lithium improves upon this scenario.</p>
<p>I simply add:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> app\models\Download<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>to the <span class="code">ComposersController</span> class, then run the find method like so:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$downloads</span> <span style="color: #339933;">=</span> Download<span style="color: #339933;">::</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'all'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'orderBy'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'Download.downloads DESC'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'limit'</span><span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">to</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'array'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>One advantage here is that I don&#8217;t have to directly instantiate the Download model class in the controller; I simply call its namespace with the <span class="code">use</span> method, and all of its methods are available to the controller. I don&#8217;t have to worry about table associations if I don&#8217;t want to. And, well, the code just feels cleaner and yet still adheres to the MVC paradigm that keeps the various classes abstracted from one another.</p>
<h3>Console</h3>
<p>When it comes to Lithium&#8217;s console, it&#8217;s just a fun piece of work, and much easier to implement than Cake&#8217;s Bake script, in my opinion. Because Lithium makes more direct use with its <span class="code">li3</span> console app, the integration with your application comes pre-built and ready to go. What I&#8217;ve always appreciated about Ruby On Rails and Symfony is their use of the console to automate development processes. But I&#8217;ve also admired Cake for not being overly tied down to the console that you must create a particular shell environment to get the framework to install easily. In fact, in my earliest days of web frameworks experience, this factor pulled me over to Cake in the first place; I had spent hours trying to get Symfony to run correctly in my local console environment, but Cake just worked after dropping the main folder into my server root. I didn&#8217;t care what core features Symfony offered at the time because I could get right to work in Cake without any headache.</p>
<p>Lithium, on the other hand, improves upon both of these paradigms of console development, if you ask me. It maintains the same drag-and-drop installation capabilities as Cake, but comes packaged with console features that rival Ruby On Rails and Symfony. (I realize, though, that I&#8217;m speaking of a framework that is currently at 0.6, so some of this is my own predictions of what will come through at the 1.0 phase.)</p>
<p>Getting <span class="code">li3</span> to run required a simple adjustment to my <span class="code">.profile</span> file. I simply added:</p>
<div class="codecolorer-container php vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">export PATH<span style="color: #339933;">=/</span>usr<span style="color: #339933;">/</span>lib<span style="color: #339933;">/</span>lithium<span style="color: #339933;">/</span>console<span style="color: #339933;">:</span><span style="color: #000088;">$PATH</span></div></td></tr></tbody></table></div>
<p>to my <span class="code">.profile</span> (I have the Lithium core installed in my <span class="code">/usr/lib</span> directory) and was able to call <span class="code">li3</span> in the terminal, and was in business. After following the <a href="http://li3.rad-dev.org/docs/lithium/console">Console Tutorial</a> on the Lithium site, I had a numbers game up in minutes. In short, I created my own console class in the <span class="code">app/extensions/command</span> directory and then ran it quite easily by pointing to the application with <span class="code">cd</span>, and from there calling <span class="code">li3 numbers</span> (numbers was the name of the console class). I didn&#8217;t have to add any flags to the command line, just simply browsed to the app folder, and <span class="code">li3</span> knew what to do from there. Now, obviously the numbers game is a trivial way of learning the capabilities of a shell environment for a framework. But the integration is such that I&#8217;ll be able to customize console commands to perform unit tests, populate the datasource with schematics, manage sessions, perform cron jobs, build custom classes automagically, and so on.</p>
<h3>Datasources</h3>
<p>I&#8217;ll admit that the hardest chapter to write for my Beginning CakePHP book was the one on datasources. This was simply because the documentation was sparse on even how to get datasources working, let alone explain a normative way for optimally doing so in the Cake environment. Since then, the documentation has gotten much better. Nevertheless, the datasource schema for bridging various sources favors a kind of database model, meaning, you still use the <span class="code">$useDbConfig</span> property and define that value in the <span class="code">config/database.php</span> file to attach a datasource to your Cake app.</p>
<p>Lithium, on the other hand, assumes wildly different ways of sourcing data to your app. In fact, it comes pre-built to handle cutting-edge datasources like MongoDB and CouchDB which require a little more flexibility to leverage their feature sets. It handles these sources not as databases per se, or as PDO abstractions, but as connections. This semantic difference actually amplifies the capabilities of the datasource structure because it further abstracts the way data is pulled, manipulated, and otherwise handled by the framework. Web services like the dozens Google and Facebook applications are providing all could interact with a Lithium app the same way a database would, without attaching duct tape here and there in your code base. This makes for leaner code, and above all, improves performance significantly.</p>
<h3>Concluding Thoughts</h3>
<p>Dedicating two months to Lithium after years on the CakePHP platform has made me a convert for one basic reason. In the end, they both will get it done, and will get it done well. But, to be honest, the experience feels different, and however else the pieces fall into place that make the two frameworks semantically and structurally different doesn&#8217;t really matter when push comes to shove. As a developer, I just want to enjoy coding and I want it to be lean and clean. </p>
<p>So it really has begun to feel a lot like my experiences on the Mac and PC platforms. On the one hand, the Apple paradigm fights vigorously to streamline the feature set and to zero-in on each feature as a unique contribution to the user experience. They are ready to scrap features if they have to in order to maintain an intuitive and clean experience because they know that in the end, the user has to come away with a positive and simple interaction with their software. But the Microsoft paradigm has always been one of amplifying the feature set as much as possible and creating a platform that cannot be brushed aside. They want to drag-race the competition and compete as a total platform, one that out-does everyone else&#8217;s feature set, though only recently are they working harder to focus on the user experience. (Check out The Marketing Playbook by John Zagula and Rich Tong for a detailed explanation of how Microsoft thinks about platform plays behind the scenes and demolishing competition through Windows integration.) </p>
<p>Cake has started to feel less clean and more like Zend Framework feels; chock full of features, but lacking in performance and rigorous streamlining of the core feature set. I give kudos to Garrett Woodworth, Nate Abele, Joel Perras, Alexander Morland, and David Persson for their vision for Lithium and encourage you to give their new rising-star framework a go.</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/f6ZgCexfTmI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/cakephp/transitioning-from-cakephp-to-lithium.html/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/cakephp/transitioning-from-cakephp-to-lithium.html</feedburner:origLink></item>
		<item>
		<title>Formatting Dates in Cappuccino with CPDateHelper</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/Tqzigee75to/formatting-dates-in-cappuccino-with-cpdatehelper.html</link>
		<comments>http://www.davidgolding.net/cappuccino/formatting-dates-in-cappuccino-with-cpdatehelper.html#comments</comments>
		<pubDate>Thu, 06 Aug 2009 00:25:11 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[Cappuccino]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=249</guid>
		<description><![CDATA[I missed being able to format dates like I do in PHP and with a current Cappuccino app I&#8217;m working on, I couldn&#8217;t help build a date formatting helper. I&#8217;ve posted it as an open source class on GitHub and invite your contributions, feedback, or use. Using this class is simple. Just download and place [...]]]></description>
			<content:encoded><![CDATA[<p>I missed being able to format dates like I do in PHP and with a current Cappuccino app I&#8217;m working on, I couldn&#8217;t help build a date formatting helper. I&#8217;ve posted it as an open source class on <a href="http://github.com/davidgolding/CPDateHelper/tree/master">GitHub</a> and invite your contributions, feedback, or use.</p>
<p>Using this class is simple. Just download and place the <span class="code">CPDateHelper.j</span> file in your Cappuccino app directory. Then include the class using:</p>
<div class="codecolorer-container objc vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">@import <span style="color: #bf1d1a;">&quot;CPDateHelper.j&quot;</span></div></td></tr></tbody></table></div>
<p>Anywhere in your Cappuccino app, just provide CPDateHelper with a date string and a formatting string and it will return a formatted date string. For example:</p>
<div class="codecolorer-container objc vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">var formattedDateString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CPDateHelper date<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Wed Aug 5 2009 13:00:00&quot;</span> withFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;D M jS Y g:i A&quot;</span><span style="color: #002200;">&#93;</span>;</div></td></tr></tbody></table></div>
<p>In this example, <span class="code">formattedDateString</span> will contain:</p>
<div class="codecolorer-container objc vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Wed Aug 5th <span style="color: #2400d9;">2009</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">:</span>00 PM</div></td></tr></tbody></table></div>
<p>CPDateHelper also returns the formatted date string as a CPString object, so you can use CPString methods on it right out of the box.</p>
<p>Again, <a href="http://github.com/davidgolding/CPDateHelper/tree/master">jump on over to the GitHub project</a> to download the source or</p>
<p><a href="http://github.com/davidgolding/CPDateHelper/zipball/master">Download CPDateHelper.zip</a></p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/Tqzigee75to" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/cappuccino/formatting-dates-in-cappuccino-with-cpdatehelper.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/cappuccino/formatting-dates-in-cappuccino-with-cpdatehelper.html</feedburner:origLink></item>
		<item>
		<title>Cursed Leap Years!</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/YA_OmMR562E/cursed-leap-years.html</link>
		<comments>http://www.davidgolding.net/cakephp/cursed-leap-years.html#comments</comments>
		<pubDate>Wed, 05 Aug 2009 19:45:24 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[Musings]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=246</guid>
		<description><![CDATA[I used to think that leap years only happened every four years. In fact, every centennial year that is not evenly divisible by 400 is not a leap year. I don&#8217;t expect to live to 2100, so it shouldn&#8217;t matter. But, unfortunately, in programming world, remembering this caveat on the leap year could result in [...]]]></description>
			<content:encoded><![CDATA[<p>I used to think that leap years only happened every four years. In fact, every centennial year that is not evenly divisible by 400 is not a leap year.</p>
<p>I don&#8217;t expect to live to 2100, so it shouldn&#8217;t matter. But, unfortunately, in programming world, remembering this caveat on the leap year could result in a bug, or worse, world cataclysm like we <strikeout>saw</strikeout> didn&#8217;t see with Y2K.</p>
<p>I recently landed this bug and had to write a way out of it. Here&#8217;s my solution in PHP, JavaScript, and Cappuccino.</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">function isLeapYear($aYear) {<br />
&nbsp; &nbsp; if (($aYear % 4) == 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; if (($aYear % 100) == 0 &amp;&amp; (($aYear % 400) != 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; }<br />
}</div></td></tr></tbody></table></div>
</pre>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">function isLeapYear(aYear) {<br />
&nbsp; &nbsp; if ((aYear % 4) == 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; if ((aYear % 100) == 0 &amp;&amp; ((aYear % 400) != 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return false;<br />
&nbsp; &nbsp; }<br />
}</div></td></tr></tbody></table></div>
</pre>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">+ (BOOL)isLeapYear:(int)aYear {<br />
&nbsp; &nbsp; if ((aYear % 4) == 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; if ((aYear % 100) == 0 &amp;&amp; ((aYear % 400) != 0) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return NO;<br />
&nbsp; &nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return YES;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; return NO;<br />
&nbsp; &nbsp; }<br />
}</div></td></tr></tbody></table></div>
</pre>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/YA_OmMR562E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/cakephp/cursed-leap-years.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/cakephp/cursed-leap-years.html</feedburner:origLink></item>
		<item>
		<title>Upgrading PHP in MAMP</title>
		<link>http://feedproxy.google.com/~r/DavidGolding/~3/Znku9KMidcU/upgrading-php-in-mamp.html</link>
		<comments>http://www.davidgolding.net/cakephp/upgrading-php-in-mamp.html#comments</comments>
		<pubDate>Tue, 04 Aug 2009 18:45:53 +0000</pubDate>
		<dc:creator>David Golding</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.davidgolding.net/?p=241</guid>
		<description><![CDATA[I wanted to take advantage of PHP 5.3&#8242;s new 1namespace feature but in my localhost environment, I use MAMP. Upgrading PHP proved a little tricky, but actually very easy. The tricky part was figuring out how to make it work, but on the whole, it&#8217;s not too bad. First, run the 1phpinfo() function in a [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to take advantage of PHP 5.3&#8242;s new</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">namespace</div></td></tr></tbody></table></div>
<p>feature but in my localhost environment, I use MAMP. Upgrading PHP proved a little tricky, but actually very easy. The tricky part was figuring out how to make it work, but on the whole, it&#8217;s not too bad.</p>
<p>First, run the</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">phpinfo()</div></td></tr></tbody></table></div>
<p>function in a PHP script on your localhost or go to PHPMyAdmin and hunt down the configuration page. You should see a large chunk of configuration markup at or near the top:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">'./configure' '--with-mysql=/Applications/MAMP/Library' <br />
'--with-apxs2=/Applications/MAMP/Library/bin/apxs' <br />
'--with-gd' '--with-jpeg-dir=/Applications/MAMP/Library'<br />
'--with-png-dir=/Applications/MAMP/Library' '--with-zlib' <br />
'--with-freetype-dir=/Applications/MAMP/Library' <br />
'--prefix=/Applications/MAMP/bin/php5' '--exec-prefix=/Applications/MAMP/bin/php5' <br />
'--sysconfdir=/Applications/MAMP/conf/php5' '--with-soap' <br />
'--with-config-file-path=/Applications/MAMP/conf/php5'<br />
'--enable-track-vars' '--enable-bcmath' '--enable-ftp' '--enable-gd-native-ttf' <br />
'--with-bz2=/usr' '--with-ldap' '--with-mysqli=/Applications/MAMP/Library/bin/mysql_config' <br />
'--with-sqlite' '--with-ttf' '--with-t1lib=/Applications/MAMP/Library' <br />
'--enable-mbstring=all' '--with-curl=/Applications/MAMP/Library' '--enable-dbx' <br />
'--enable-sockets' '--enable-bcmath' '--with-imap=shared,/Applications/MAMP/Library/lib/imap-2006i' <br />
'--enable-soap' '--with-kerberos' '--enable-calendar' <br />
'--with-pgsql=shared,/Applications/MAMP/Library/pg' '--enable-dbase' <br />
'--enable-exif' '--with-libxml-dir=/Applications/MAMP/Library' <br />
'--with-gettext=shared,/Applications/MAMP/Library' '--with-xsl=/Applications/MAMP/Library' <br />
'--with-pdo-mysql=shared,/Applications/MAMP/Library' '--with-pdo-pgsql=shared,/Applications/MAMP/Library/pg' <br />
'--with-mcrypt=shared,/Applications/MAMP/Library' '--with-openssl'</div></td></tr></tbody></table></div>
</pre>
<p>Copy and paste this whole chunk into your text editor and remove the single quotes (search and replace should do it). Look for the flag</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--with-pdo-mysql=shared,/Applications/MAMP/Library</div></td></tr></tbody></table></div>
<p>and replace it with:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--with-pdo-mysql=/Applications/MAMP/Library</div></td></tr></tbody></table></div>
</pre>
<p>If you don&#8217;t do this, you might end up with an</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ld: symbol(s) not found</div></td></tr></tbody></table></div>
<p>error.</p>
<p>Finally, add the following flag to the end:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--without-iconv</div></td></tr></tbody></table></div>
</pre>
<p>After you have downloaded the latest PHP release of your choosing from <a href="http://snaps.php.net">PHP Sources Snapshots</a>,</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd</div></td></tr></tbody></table></div>
<p>to the downloaded directory in Terminal. Paste your reformatted configuration string (all of it, including the beginning</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">./configure</div></td></tr></tbody></table></div>
<p>command) and run it.</p>
<p>After the configuration phase is finished, run:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ make<br />
$ sudo make install</div></td></tr></tbody></table></div>
</pre>
<p>Relaunch MAMP, and you&#8217;re good to go.</p>
<p>For you CakePHP users out there, now you can play with Cake3 releases (which apparently will be optimized for PHP 5.3+).</p>
<img src="http://feeds.feedburner.com/~r/DavidGolding/~4/Znku9KMidcU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.davidgolding.net/cakephp/upgrading-php-in-mamp.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		<feedburner:origLink>http://www.davidgolding.net/cakephp/upgrading-php-in-mamp.html</feedburner:origLink></item>
	</channel>
</rss>

