<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">

    <channel>
    
    <title>WJGilmore.com</title>
    <link>http://localhost/index.php/site/index/</link>
    <description />
    <dc:language>en</dc:language>
    <dc:creator>wj@wjgilmore.com</dc:creator>
    <dc:rights>Copyright 2011</dc:rights>
    <dc:date>2011-08-19T15:19:34+00:00</dc:date>
    <admin:generatorAgent rdf:resource="http://expressionengine.com/" />
    

    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/wjgilmorecom" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="wjgilmorecom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>How I Learned to Stop Worrying and Love Zend_Form</title>
      <link>http://www.wjgilmore.com/index.php/site/how_i_learned_to_stop_worrying_and_love_zend_form/</link>
      <guid>http://www.wjgilmore.com/index.php/site/how_i_learned_to_stop_worrying_and_love_zend_form/#When:15:19:34Z</guid>
      <description>Are Zend_Form decorators driving you crazy? In this blog post I’ll show you how to override the default decorators, and instead wield total control over your form layout by supplying your own layout file.






I’ve long been a fan of the Zend Framework, insomuch that I’ve penned a book on the topic, introduced dozens of students to the framework via several full day workshops, and have contributed well over a framework-related articles to Developer.com and PHPBuilder.com, among others (a compilation of which you can view here). It is a fantastically productive framework, one which I happen to use almost every single day.



There was however one feature which absolutely drove me crazy. The Zend_Form component’s uses the dd, dl, and dt elements as the default form markup decorators, meaning that even a simple contact form consisting of name, email, and message fields and a submit button looks like this:



&amp;lt;form id="contact" enctype="application/x-www-form-urlencoded" 
    method="post" action="/about/contact"&amp;gt;
  &amp;lt;dl class="zend_form"&amp;gt;
    &amp;lt;dt id="name-label"&amp;gt;&amp;lt;label for="name" class="required"&amp;gt;Your Name:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd id="name-element"&amp;gt;
      &amp;lt;input type="text" name="name" id="name" value="" size="35"&amp;gt;
    &amp;lt;/dd&amp;gt;
    &amp;lt;dt id="email-label"&amp;gt;&amp;lt;label for="email" class="required"&amp;gt;Your E-mail Address:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd id="email-element"&amp;gt;
      &amp;lt;input type="text" name="email" id="email" value="" size="35"&amp;gt;
    &amp;lt;/dd&amp;gt;
    &amp;lt;dt id="message-label"&amp;gt;&amp;lt;label for="message" class="required"&amp;gt;Your Message:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd id="message-element"&amp;gt;
      &amp;lt;textarea name="message" id="message" rows="10" cols="55"&amp;gt;&amp;lt;/textarea&amp;gt;
    &amp;lt;/dd&amp;gt;
    &amp;lt;dt id="submit-label"&amp;gt; &amp;lt;/dt&amp;gt;
    &amp;lt;dd id="submit-element"&amp;gt;
      &amp;lt;input type="submit" name="submit" id="submit" value="Send Your Message!"&amp;gt;
    &amp;lt;/dd&amp;gt;
  &amp;lt;/dl&amp;gt;
&amp;lt;/form&amp;gt;



While I am not disputing the wisdom of this decision, because there is technically nothing wrong with the approach. However it goes without saying that the overwhelming majority of developers do not use these elements to mark up their forms, with the sheer number of questions posted to StackOverflow and elsewhere about getting rid of these decorators backing this assertion.



Now for the record you can override these decorators in your form models using the setDecorators() method, and you can even create custom decorators, however given my very questionable design skills I’d rather leave all layout decisions to the designer (whether it be choice of markup or CSS stylings). So what’s the solution?



I had previously been using the removeDecorator() method to rip out all of the default decorators and then using the setDecorators() method to identify a custom view script (the latter of which is demonstrated below), however during a Zend Framework workshop I was running in Milwaukee a few months ago Joel Clermont identified a far more succinct method. This method is described below.


Have Your Cake And Eat It Too


As it turns out, there is a way to continue taking advantage of all of the great features Zend_Form has to offer while wielding total control over your form layout! Returning to the aforementioned contact form, I’ll begin the task of overriding all of the decorator defaults by creating a custom form layout file, calling it something like _form_contact.phtml, and placing it within the project path. This file looks like this:



&amp;lt;form id="contact" action="&amp;lt;?= $this-&amp;gt;element-&amp;gt;getAction(); ?&amp;gt;" 
      method="&amp;lt;?= $this-&amp;gt;element-&amp;gt;getMethod(); ?&amp;gt;"&amp;gt;

&amp;lt;p&amp;gt;
Your Name&amp;lt;br /&amp;gt;
&amp;lt;?= $this-&amp;gt;element-&amp;gt;name; ?&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
Your E-mail Address&amp;lt;br /&amp;gt;
&amp;lt;?= $this-&amp;gt;element-&amp;gt;email; ?&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
Your Message&amp;lt;br /&amp;gt;
&amp;lt;?= $this-&amp;gt;element-&amp;gt;message; ?&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
&amp;lt;?= $this-&amp;gt;element-&amp;gt;submit ?&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;/form&amp;gt;



Now for the magic. Open your contact form model, and add just two lines to the init() method, both of which are bolded below:



&amp;lt;?php

class Application_Form_Contact extends Zend_Form
{

  public function init()
  {
    $this-&amp;gt;setName('contact');
    $this-&amp;gt;setMethod('post');
    $this-&amp;gt;setAction('/about/contact');

    $name = new Zend_Form_Element_Text('name');
    $name-&amp;gt;setAttrib('size', 35);
    $name-&amp;gt;setLabel('Your Name:');
    $name-&amp;gt;setRequired(true);
    $name-&amp;gt;addErrorMessage('Please provide your name');

    $email = new Zend_Form_Element_Text('email');
    $email-&amp;gt;setAttrib('size', 35);
    $email-&amp;gt;setLabel('Your E-mail Address:');
    $email-&amp;gt;setRequired(true);
    $email-&amp;gt;addErrorMessage('Please provide a valid e-mail address');

    $message = new Zend_Form_Element_Textarea('message');
    $message-&amp;gt;setLabel('Your Message:');
    $message-&amp;gt;setRequired(true);
    $message-&amp;gt;setAttrib('rows', '10');
    $message-&amp;gt;setAttrib('cols', '55');
    $message-&amp;gt;addErrorMessage('Please specify a message');

    $submit = new Zend_Form_Element_Submit('submit');
    $submit-&amp;gt;setLabel('Send Your Message!');

    $this-&amp;gt;setDecorators( array( 
    array('ViewScript', array('viewScript' =&amp;gt; '_form_contact.phtml'))));

    $this-&amp;gt;addElements(array($name, $email, $message, $submit));

    $this-&amp;gt;setElementDecorators(array('ViewHelper'));
  }

}



The setDecorators() call will tell the Zend Framework to use the _form_contact.phtml script as the form’s render template, and the setElementDecorators() method will strip all of the default layout decorators which are otherwise rendered. There are numerous variations in terms of exactly what defaults you can override, but I’m trying to stay on topic and so won’t get into them here. What is clear is that you must set setDecorators() before calling addElements(), and you must all setElementDecorators() after calling addElements(). With the updated model in place, the rendered form looks like this:



&amp;lt;form id="contact" action="/about/contact" method="post"&amp;gt;

&amp;lt;p&amp;gt;
Your Name&amp;lt;br /&amp;gt;
&amp;lt;input type="text" name="name" id="name" value="" size="35"&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
Your E-mail Address&amp;lt;br /&amp;gt;
&amp;lt;input type="text" name="email" id="email" value="" size="35"&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
Your Message&amp;lt;br /&amp;gt;
&amp;lt;textarea name="message" id="message" rows="10" cols="55"&amp;gt;&amp;lt;/textarea&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
&amp;lt;input type="submit" name="submit" id="submit" value="Send Your Message!"&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;/form&amp;gt;



And that’s how I learned to stop worrying and love Zend_Form.



Disclaimer: I cover a close variant of this approach in the second edition of Easy PHP Websites with the Zend Framework, however the specific approach described above is in my opinion preferable to all others. I’ll update the book to reflect this approach in a forthcoming version.</description>
      <dc:subject>Best Practices, PHP, Zend Framework</dc:subject>
      <dc:date>2011-08-19T15:19:34+00:00</dc:date>
    </item>

    <item>
      <title>Thirteen Zend Framework Tutorials</title>
      <link>http://www.wjgilmore.com/index.php/site/thirteen_zend_framework_tutorials/</link>
      <guid>http://www.wjgilmore.com/index.php/site/thirteen_zend_framework_tutorials/#When:18:06:35Z</guid>
      <description>A few weeks ago I posted what turned out to be a rather popular compendium of productivity- and best practices-related PHP tutorials which I’ve published in recent years on Developer.com and PHPBuilder.com. As it happens I write about the Zend Framework with equal vigor, and figured readers might like to check out the list of Zend Framework tutorials I’ve written over the past two years for the aforementioned sites.






A few weeks ago I posted what turned out to be a rather popular compendium of productivity- and best practices-related PHP tutorials which I’ve published in recent years on Developer.com and PHPBuilder.com. As it happens I write about the Zend Framework with equal vigor, and figured readers might like to check out the list of Zend Framework tutorials I’ve written over the past two years for the aforementioned sites. With no further ado, here’s the list.









Boost PHP Site Performance with Zend Framework Data Caching
Zend’s data caching component is pretty darned useful, although for newcomers the terminology used in the documentation can be rather confusing. This tutorial helps to shed some light on the topic.



Testing with the Zend Framework: How to Get Started
Unit testing is without a doubt the most important development strategy I’ve added to my toolbox in recent years, and after working through a few nasty configuration issues it’s possible to incorporate PHPUnit into your Zend Framework applications via Zend_Test, and it is in a word, awesome. This tutorial introduces you to the topic.



Video: Testing Your Web Forms with Zend_Test and PHPUnit
This video furthers the testing theme, showing you how to test web forms using the Zend_Test component and PHPUnit.



Managing Zend Framework Layouts
PHP developers love to talk about templating engines. As it happens, I hate to talk about them in preference of a solution which just works, allowing me to focus on implementing cool features. The Zend Framework’s layout solution is such a solution.



Search Google Books with the Zend Framework’s Zend_Gdata Component
The Zend Framework sports a significant number of web services API components, including several which plug into the various Google services, Google Books included. This tutorial shows you how to get started mining book data using the Zend_Gdata component.



Taking Advantage of Simple Cloud with the Zend Cloud Component
Simple Cloud is a unified cloud API capable of plugging into several different popular cloud solutions (Microsoft’s and Amazon’s among them). The Zend_Cloud component offers an easy way to talk to this API via the Zend Framework.



Integrating Twitter Into the Zend Framework
Continuing with the web services theme, this tutorial shows you how to talk to Twitter via the Zend Framework using the Zend_Service_Twitter component.



Create a Unit Conversion Application with the Zend_Measure Component
The Zend Framework supports almost 100 components capable of performing practically any task under the sun. As proof of such wide-ranging capabilities, this article introduces you to the Zend_Measure component, which can convert between a significant number of different measurement standards.



Use Zend Framework Action Helpers to Reduce PHP Code Redundancy
Two great ways to stay DRY within your Zend Framework applications is by taking full advantage of action helpers and view helpers. This tutorial tackles the latter.



Video: Developing Custom Zend Framework View Helpers
This video introduces you to the second of the aforementioned helper types, showing you how to take advantage of view helpers within your Zend Framework applications.



Running PHP and Zend Framework Scripts from the Command Line
Although seemingly unconventional, I regularly run Zend Framework applications from the command-line, using various components in conjunction with a PHP script which executes on a regular basis via CRON. In fact, my book Easy PHP Websites with the Zend Framework‘s companion project GameNomad relies upon numerous such scripts to update the video games’ sales ranks. This tutorial shows you how to incorporate such capabilities into your repertoire.



Managing User Accounts with the Zend Framework
The ability to create and log into user accounts is an indispensable part of any website, yet many web development novices have a hard time figuring out how all of the different pieces work together. This tutorial clarifies nicely by showing you how to use the Zend Framework’s Zend_Auth component to build a simple user registration solution.



Creating RSS Feeds with the Zend Framework for Fun and Profit
Although in the Twitter age it certainly seems as if RSS feeds are losing their lustre, millions of users remain devoted to daily perusal of their feed readers. This tutorial shows you how to create RSS feeds using the Zend Framework’s Zend_Feed component.</description>
      <dc:subject>PHP, Zend Framework</dc:subject>
      <dc:date>2011-05-26T18:06:35+00:00</dc:date>
    </item>

    <item>
      <title>Sixteen Best Practices- and Productivity-Related PHP Tutorials</title>
      <link>http://www.wjgilmore.com/index.php/site/sixteen_best_practices-_and_productivity-related_php_tutorials/</link>
      <guid>http://www.wjgilmore.com/index.php/site/sixteen_best_practices-_and_productivity-related_php_tutorials/#When:20:04:02Z</guid>
      <description>This compendium of sixteen recently published tutorials touches upon all manner of topics related to PHP-oriented best practices and productivity. In this list you’ll find tutorials introducing testing, debugging, advanced object-oriented features, code profiling, security, enforcing coding standards, and more.






I spend a great deal of time writing about Web development, either working on books or writing for online publications such as Developer.com, PHPBuilder.com, JSMag, and TechTarget. So much time in fact that in 2010 I penned more than 130 articles. Many of these articles focused on PHP-specific best practices and productivity, two topics which should resonate closely with anybody involved in building websites for a living.



So I thought it would be useful to compile a list of the sixteen tutorials which touch upon these topics. In this list you’ll find tutorials introducing testing, debugging, advanced object-oriented features, code profiling, security, enforcing coding standards, and more.





Testing Forms in PHP with SimpleTest
Although not as well known as PHPUnit, SimpleTest is an immensely capable framework, having been adopted by popular PHP projects including CakePHP and Drupal. In this tutorial, I’ll show you how to use SimpleTest to automate forms testing.



10 Productive PHP Tools for Testing and Debugging
Despite the general notion that programming is a profession steeped in discipline and rigor, members of the programming community tend to be rather finicky folks who can be very particular when it comes to tooling. Thankfully PHP developers have a great deal to choose from when it comes to testing and debugging tools, and in this article I’ll highlight 10 of my favorites.



Five Popular PHP Templating Engines Worth Checking Out
If you’ve fallen into the trap of mixing your website presentation and logic and are looking for a way out, there are actually quite a few solutions at your disposal. Known as templating engines, these solutions offer the ability to cleanly separate your PHP code from the HTML and other presentational languages (e.g. CSS and JavaScript), improving maintainability and testability. In this article I’ll introduce five of PHP’s most popular templating engines, providing you with a basis for continuing your own investigations.



Three Advanced Object-Oriented PHP Features You Need to Know
In this article I’ll introduce you to three of PHP’s advanced object-oriented features which seem to not have garnered the attention they deserve. The topics discussed here should be useful whether you’re a relative newcomer to object-oriented development and are looking to expand your knowledge, or have a background using languages such as Java or C# and are trying to learn more about what PHP has to offer.



Profiling PHP Code with Xdebug and KCacheGrind
How can one go about determining which parts of an application could be optimized? One common approach involves using a profiler such as Xdebug, which can analyze your code and produce performance reports. These reports can then be reviewed within a profiling visualization tool such as KCacheGrind. In this article I’ll show you how to use Xdebug and KCacheGrind to begin profiling and analyzing your PHP-driven Web applications.



Four Sane Solutions for PHP Debugging
PHP developers have a number of powerful debugging solutions at their disposal. Whether you’re merely inspecting array contents or attempting to determine the status of an Ajax-driven POST response, the four solutions introduced in this article are guaranteed to have an immediate impact on your productivity.



Use the PHP Filter Extension to Validate User Data
With so much potential for distraction, it’s no wonder that developers continue to fall victim to the very same security gaffes that have afflicted the community for well over a decade. Notably, failure to properly validate user input remains the single most serious security issue, with several of the Open Web Application Security Project’s top ten security risks originating directly from this oversight. Fortunately, with PHP 5.2 came an incredibly easy way to ensure that user input fits expectations! Read on to learn how.



Mitigate the Security Risks of PHP System Command Execution
In this tutorial, I’ll show you how to securely execute a variety of system-based commands via a PHP script, demonstrating how to build web applications that can tightly integrate with both the operating system and third-party software.



Enforcing Coding Standards with PHP_CodeSniffer
In light of PHP’s considerable expressive flexibility, how can you actively enforce a coding standard and prevent both yourself and your team members from reverting to bad habits? One great solution called PHP_CodeSniffer is (coincidentally) found in a PEAR package. PHP_CodeSniffer can not only parse PHP code to ensure it meets a particular coding standard but it can also examine your JavaScript and CSS files for potential standards violations.



10 PHP Tricks for Associative Array Manipulation
The associative array—an indispensable data type used to describe a collection of unique keys and associated values—is a mainstay of all programming languages, PHP included. In fact, associative arrays are so central to the task of Web development that PHP supports dozens of functions and other features capable of manipulating array data in every conceivable manner. Such extensive support can be a bit overwhelming to developers seeking the most effective way to manipulate arrays within their applications. In this article, I’ll offer 10 tips that can help you shred, slice and dice your data in countless ways.



Using SPL Iterators in PHP to Interact with Different Data Types
One great way to incorporate more PHP-based object-oriented programming into your applications is through the Standard PHP Library (SPL), a powerful yet largely unknown extension made part of the official PHP language with the PHP 5.0 release. The SPL provides a series of classes which extend the PHP language in numerous ways, offering object-oriented advanced data structures, iterators, and file handlers, among other features. In this tutorial I’ll introduce you to several of my favorite SPL iterators, providing you with the basis from which you can continue your own exploration. Following several examples, I’ll conclude with a brief introduction to other key SPL features.



A Sanity-saving Debugging Solution for Your PHP Development
XDebug is a PHP extension created by longtime PHP core contributor Derick Rethans. Because it is a PHP extension, XDebug can (and does) directly affect certain PHP behaviors in ways that greatly improves the developer’s ability to identify and resolve code errors. After installing XDebug, we’ll work through a few examples that clearly denote these improvements.



Use PHPUnit to Implement Unit Testing in Your PHP Development
If you create web applications that talk to databases, process user input, integrate Ajax functionality, and perform other mission-critical tasks, then it’s crucial that you institute a rigorous testing program—alongside other procedures that may already be in place, such as coding standards and documentation. The PHP community has long had a great testing utility at their disposal known as PHPUnit, and in this tutorial I offer a brief introduction to its benefits.



Using the PEAR Pager Package to Paginate MySQL Results
The PEAR Pager package will not only handle all of the gory details of paginating database results for you, but it can also create a linked navigation list which you can embed into the page as a navigational aide for the user. In this article I’ll show you how to use Pager to easily paginate your database results in a structured and coherent way.



Top 10 phpMyAdmin Tips and Tricks You May Not Know
Despite approaching its 12th birthday, phpMyAdmin is still under active development, with at least one significant version released every year since the project’s inception. In fact even after almost a decade of use I still marvel over discovering features which I had no idea existed. In this article I thought I’d highlight 10 useful phpMyAdmin features which may have escaped you during your daily interaction with this fantastic utility.



Running PHP and Zend Framework Scripts from the Command Line
Did you know it’s possible to run PHP scripts from the command line using its command line interpreter (CLI)? Even though it’s been possible since the PHP 4.3.0 release, you may be completely unaware of this CLI usage unless you employ great tools such as PHPDoc, Phing, or PHPUnit. Running PHP scripts with CLI allows you to leverage your PHP language skills whenever you need to run scripts from the shell.</description>
      <dc:subject>Best Practices, PHP</dc:subject>
      <dc:date>2011-05-10T20:04:02+00:00</dc:date>
    </item>

    <item>
      <title>Deploying PHP Websites with Capistrano</title>
      <link>http://www.wjgilmore.com/index.php/site/deploying_php_websites_with_capistrano/</link>
      <guid>http://www.wjgilmore.com/index.php/site/deploying_php_websites_with_capistrano/#When:13:18:24Z</guid>
      <description>Love creating websites but hate deploying and updating them? If so I’d imagine you’re still using FTP to transfer files, because Capistrano makes deployment dead simple. Read on to learn how you can start using Capistrano to deploy your PHP-powered websites.
[Parts of this blog entry are excerpted from Easy PHP Websites with the Zend Framework.]







Have you ever had hugely ambitious plans for a website project, only to let it fall by the wayside soon after deployment because pushing incremental improvements was a total pain in the behind? If so, I’ll venture a guess that you were using FTP to update the website files. FTP is like the bag of sand Indiana Jones used to try and swap for the monkey statue at the beginning of “Raiders of the Lost Ark”. The bag feels so good and familiar in your hands, and with just a little tweaking you’re absolutely convinced it’s going to do the job. But things didn’t go as expected and now the giant but incredibly smooth boulder is rolling directly towards you.


FTP is an unacceptable solution because ongoing, incremental improvements to a website will only occur if the deployment barrier is sufficiently low. Because FTP is slow, stupid, and lacking an undo feature, I can guarantee your updates will be occasional, tentative, and painful. Deploying framework-based websites is even more tenuous because many solutions require additional tweaking after the files have been updated. For instance, a Zend Framework-driven website will run in development mode on your laptop but in production mode on your server. The mode is typically set in an .htaccess file via a variable named APPLICATION_ENV. If you’re using FTP to blindly transfer the files over, then you’ll need to SSH in following deployment and update that variable. Every single time. 

Fortunately, an alternative deployment solution exists called Capistrano (https://github.com/capistrano/) which resolves all of FTP’s issues quite nicely. Not only can you use Capistrano to securely and efficiently deploy changes to your Zend Framework website, but it’s also possible to rollback your changes should a problem arise. I’ll show you how to configure your development environment to use Capistrano, freeing you from ever having to worry again about a botched website deployment.

Installing Capistrano

Capistrano is an open source automation tool originally written for and primarily used by the Rails community. However it is perfectly suitable for use with other languages, PHP included. But because Capistrano is written in Ruby, you’ll need to install Ruby on your development machine. If you’re running OS X or most versions of Linux, then Ruby is likely already installed. If you’re running Windows, the easiest way to install Ruby is via the Ruby Installer for Windows.

Once installed, you’ll use the RubyGems package manager to install Capistrano and another application called Railsless Deploy which will hide many of the Rails-specific features otherwise bundled into Capistrano. Although Railsless Deploy is not strictly necessary, installing it will dramatically streamline the number of Capistrano menu options otherwise presented, all of which would be useless to you anyway because they are intended for use in conjunction with Rails projects. 

RubyGems is bundled with Ruby, meaning if you’ve installed Ruby then RubyGems is also available. Open up a terminal window and execute the following command to install Capistrano:


$ gem install capistrano


Next, install Railsless Deploy using the following command:


$ gem install railsless-deploy


Once installed you should be able to display a list of available Capistrano commands:


$ cap -T
cap deploy               # Deploys your project.
cap deploy:check         # Test deployment dependencies.
cap deploy:cleanup       # Clean up old releases.
cap deploy:cold          # Deploys and starts a `cold' application.
cap deploy:pending       # Displays the commits since your last…
cap deploy:pending:diff  # Displays the `diff' since your last…
cap deploy:rollback      # Rolls back to a previous version and…
cap deploy:rollback:code # Rolls back to the previously deployed…
cap deploy:setup         # Prepares one or more servers for depl…
cap deploy:symlink       # Updates the symlink to the most recen…
cap deploy:update        # Copies your project and updates the s…
cap deploy:update_code   # Copies your project to the remote ser…
cap deploy:upload        # Copy files to the currently deployed…
cap invoke               # Invoke a single command on the remote…
cap shell                # Begin an interactive Capistrano sessi…


Configuring Public Key Authentication

The final general configuration step you’ll need to take is configuring key-based authentication. Key-based authentication allows a client to securely connect to a remote server without requiring the client to provide a password, by instead relying on public-key authentication to verify the client’s identity.

Public-key cryptography works by generating a pair of keys, one public and another private, and then transferring a copy of the public key to the remote server. When the client attempts to connect to the remote server, the server will challenge the client by asking the client to generate a unique signature using the private key. This signature can only be verified by the public key, meaning the server can use this technique to verify that the client is allowed to connect. As you might imagine, some fairly heady mathematics are involved in this process, and I’m not even going to attempt an explanation; the bottom line is that configuring public-key authentication is quite useful because it means you don’t have to be bothered with supplying a password every time you want to SSH into a remote server.

Configuring public-key authentication is also important when setting up Capistrano to automate the deployment process, because otherwise you’ll have to configure Capistrano to provide a password every time you want to deploy the latest changes to your website.

If you’re running a Linux/Unix-based system, creating a public key pair is a pretty simple process. Although I won’t be covering the configuration process for Windows or OSX-based systems, I nonetheless suggest carefully reading this section as it likely won’t stray too far from the steps you’ll need to follow. Start by executing the following command to generate your public and private key:


$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/wjgilmore/.ssh/id_rsa):


Unless you have good reasons for overriding the default key name and location, go ahead and accept the default. Next you’ll be greeted with the following prompt:


Enter passphrase (empty for no passphrase):


Some tutorials promote entering an empty passphrase (password), however I discourage this because should your private key ever be stolen, the thief could use the private key to connect to any server possessing your public key. Instead, you can have your cake and eat it to by defining a passphrase and then using a service called ssh-agent to cache your passphrase, meaning you won’t have to provide it each time you login to the remote server. Therefore choose a passphrase which is difficult to guess but one you won’t forget.

Once you’ve defined and confirmed a passphrase, your public and private keys will be created. You’ll next want to securely copy your public key to the remote server. This is probably easiest done using the scp utility:


$ scp ~/.ssh/id_rsa.pub username@remote:publickey.txt


You’ll need to replace username and remote with the remote server’s username and address, respectively. Next SSH into the server and add the key to the authorized_keys file:


$ ssh username@remote
...
$ mkdir ~/.ssh
$ chmod 700 .ssh
$ cat publickey.txt &gt;&gt; ~/.ssh/authorized_keys
$ rm ~/publickey.txt
$ chmod 600 ~/.ssh/*


You should now be able to login to the remote server, however rather than provide your account password you’ll provide the passphrase defined when you created the key pair:


$ ssh username@remote
Enter passphrase for key '/home/wjgilmore/.ssh/id_rsa':


Of course, entering a passphrase each time you login defeats the purpose of using public-key authentication to forego entering a password, doesn’t it? Thankfully, you can securely store this passphrase using a program called ssh-agent, which will store your passphrase and automatically supply it when the client connects to the server. Cache your passphrase by executing the following commands:


$ ssh-agent bash
$ ssh-add
Enter passphrase for /home/wjgilmore/.ssh/id_rsa:
Identity added: /home/wjgilmore/.ssh/id_rsa (home/wjgilmore/.ssh/id_rsa)


Try logging into your remote server again and this time you’ll be whisked right to the remote terminal, with no need to enter your passphrase! However, in order to forego having to manually start ssh-agent every time your client boots you’ll want to configure it so that it starts up automatically. If you happen to be running Ubuntu, then ssh-agent is already configured to automatically start. This may not be the case on other operating systems, however in my experience configuring ssh-agent to automatically start is a very easy process. A quick search should turn up all of the information you require.

Creating the Deployment File

With these general configuration steps out of the way, it’s time to ready your website for deployment. You’ll only need to carry out these steps once per project, all of which are thankfully quite straightforward.

The first step involves creating a file called Capfile (no extension) which resides in your project’s home directory. The Capfile is essentially Capistrano’s bootstrap, responsible for loading needed resources and defining any custom deployment-related tasks. This file will also retrieve any project-specific settings, such as the location of the project repository and the name of the remote server which hosts the production website. I’ll explain how to define these project-specific settings in a moment.

Capistrano will by default look for the Capfile in the directory where the previously discussed cap command is executed, and if not found will begin searching up the directory tree for the file. This is because if you are using Capistrano to deploy multiple websites, then it will make sense to define a single Capfile in your projects’ root directory. Just to keep things simple, I suggest placing this file in your project home directory for now. Also, because we’re using the Railsless Deploy gem to streamline Capistrano, our Capfile looks a tad different than those you’ll find for the typical Rails project:


require 'rubygems'
require 'railsless-deploy'
load    'config/deploy.rb'


Notice the third line of the Capfile refers to a file called deploy.rb which resides in a directory named config. This file contains the aforementioned project-specific settings, including which version control solution (if any) is used to manage the project, the remote server domain, and the remote server directory to which the project will be deployed, among others. The deploy.rb file I use to deploy my projects is presented next. I’ve commented the code, however if you’re looking for a thorough explanation consider picking up a copy of Easy PHP Websites with the Zend Framework.


01 # What is the name of the local application?
02 set :application, "gamenomad.wjgilmore.com"
03 
04 # What user is connecting to the remote server?
05 set :user, "wjgilmore"
06 
07 # Where is the local repository?
08 set :repository,  "file:///var/www/dev.wjgames.com"
09 
10 # What is the production server domain?
11 role :web, "gamenomad.wjgilmore.com"
12 
13 # What remote directory hosts the production website?
14 set :deploy_to,   "/home/wjgilmorecom/gamenomad.wjgilmore.com"
15 
16 # Is sudo required to manipulate files on the remote server?
17 set :use_sudo, false
18  
19 # What version control solution does the project use?
20 set :scm,        :git
21 set :branch,     'master'
22 
23 # How are the project files being transferred?
24 set :deploy_via, :copy
25 
26 # Maintain a local repository cache. Speeds up the copy process.
27 set :copy_cache, true
28 
29 # Ignore any local files?
30 set :copy_exclude, %w(.git)
31  
32 # This task symlinks the proper .htaccess file to ensure the 
33 # production server's APPLICATION_ENV var is set to production
34 task :create_symlinks, :roles =&amp;gt; :web do
35   run "rm #{current_release}/public/.htaccess"
36   run "ln -s #{current_release}/production/.htaccess 
37              #{current_release}/public/.htaccess"
38 end
39  
40 # After deployment has successfully completed
41 # create the .htaccess symlink
42 after "deploy:finalize_update", :create_symlinks


Readying Your Remote Server

As I mentioned at the beginning of this chapter, one of the great aspects of Capistrano is the ability to rollback your deployment to the previous version should something go wrong. This is possible because (when using the copy strategy) Capistrano will store multiple versions of your website on the remote server, and link to the latest version via a symbolic link named current which resides in the the directory defined by the :deploy_to setting found in your deploy.rb file. These versions are stored in a directory called releases, also located in the :deploy_to directory. Each version is stored in a directory with a name reflecting the date and time at the time the release was deployed. For instance, a deployment which occurred on February 24, 2011 at 12:37:27 Eastern will be stored in a directory named 20110224183727 (these timestamps are stored using Greenwich Mean Time).

Additionally, Capistrano will create a directory called shared which also resides in the :deploy_to directory. This directory is useful for storing custom user avatars, cache data, and anything else you don’t want overwritten when a new version of the website is deployed. You can then use Capistrano’s deploy:finalize_update task to create symbolic links just as was done with the .htaccess.

Therefore given my :deploy_to directory is set to /home/wjgilmore/gamenomad.wjgilmore.com, the directory contents will look similar to this:


current -&amp;gt; /home/wjgilmore/gamenomad.wjgilmore.com/
releases/20110224184826
releases
  20110224181647/  
  20110224183727/
  20110224184826/
shared


Capistrano can create the releases and shared directories for you, something you’ll want to do when you’re ready to deploy your website for the first time. Create these directories using the deploy:setup command, as demonstrated here:


$ cap deploy:setup


Deploying Your Project

Now comes the fun part. To deploy your project, execute the following command:


$ cap deploy


If you’ve followed the instructions I’ve provided so far verbatim, remember that Capistrano will be deploying your latest committed changes. Whether you’ve saved the files is irrelevant, as Capistrano only cares about committed files.

Presuming everything is properly configured, the changes should be immediately available via your production server. If something went wrong, Capistrano will complain in the fairly verbose status messages which appear when you execute the deploy command. Notably you’ll probably see something about rolling back the changes made during the current deployment attempt, which Capistrano will automatically do should it detect that something has gone wrong.

Rolling Back Your Project
&amp;nbsp; 
One of Capistrano’s greatest features is its ability to revert, or rollback, a deployment to the previous version should you notice something just isn’t working as you expected. This is possible because as I mentioned earlier in the chapter, Capistrano stores multiple versions of the website on the production server, meaning returning to an earlier version is as simple as removing the symbolic link to the most recently deployed version and then creating a new symbolic link which points to the previous version.

To rollback your website to the previously deployed version, just use the deploy:rollback command:


$ cap deploy:rollback


Conclusion

If this is your first encounter with Capistrano, I’d imagine reading this blog post is akin to finding a pot of gold at the rainbow (or perhaps a monkey statue). Putting all of the pieces in place can be a bit confusing at first, however once they are I guarantee you’ll never let a project fall to the wayside again (at least because of deployment hindrances). If you have any questions, I’m happy to help! E-mail me at wj AT wjgilmore.com.</description>
      <dc:subject>Best Practices, PHP</dc:subject>
      <dc:date>2011-04-19T13:18:24+00:00</dc:date>
    </item>

    <item>
      <title>The Power of Doctrine 2’s Custom Repositories and Native Queries</title>
      <link>http://www.wjgilmore.com/index.php/site/the_power_of_doctrine_2s_custom_repositories_and_native_queries/</link>
      <guid>http://www.wjgilmore.com/index.php/site/the_power_of_doctrine_2s_custom_repositories_and_native_queries/#When:21:01:12Z</guid>
      <description>Doctrine 2 sports numerous amazing new features, several of which have already become an indispensable part of my approach to building websites. In this article I’ll show you how I used a custom repository and the new native queries feature to create a feature which retrieves a list of registered users residing within a 10-mile radius of another user.






Many novice developers tend to view object-relational mappers (ORMs) as a panacea to all of their database woes, marveling over features such as the convenient object-oriented syntax and magic finders. While there’s no doubt these are pretty cool features, any project of even moderate complexity will quickly exhaust such conveniences, requiring the developer to rely upon more sophisticated approaches to data access. For instance, what if you wanted to use the Haversine formula to calculate the number of registered users which reside within a 15-mile radius of the currently-logged in user? Certainly this isn’t a feature built into the typical ORM, meaning you’ll need to write a custom query to do the job.



Which brings us to the point of this article: where should this query be managed? Because Doctrine 2 treats models as POPOs (plain old PHP objects), it is easy to presume the query should be made available as a method within the model. Don’t make this mistake! Doing so would pollute your application models with database-specific functionality, which is precisely what Doctrine (and most other ORMs) are attempting to avoid altogether. Instead, you can associate a custom repository for each entity, and place the custom query code in the custom repository.



Remember that in Doctrine 2 all interaction with the database flows through the entity manager. The beauty of creating a custom repository is that you will continue to interact with the entity manager, using the custom query as if it were part of Doctrine’s native capabilities. For instance, the typical Doctrine database interaction sequence (when using Doctrine 2 within the Zend Framework) looks like this:



$this-&amp;gt;em = $this-&amp;gt;_helper-&amp;gt;EntityManager();

$account = $this-&amp;gt;em-&amp;gt;getRepository('EntitiesAccount')
                    -&amp;gt;findOneByEmail($form-&amp;gt;getValue('email'));



Now, suppose you extend the Account entity with a custom repository, and within the custom repository create a finder called getNearbyAccounts(). Once defined, you’ll be able to use that custom finder in exactly the same manner as Doctrine’s other finders:



// Retrieve the nearby accounts
$this-&amp;gt;view-&amp;gt;accounts = $this-&amp;gt;em-&amp;gt;getRepository('EntitiesAccount')
                         -&amp;gt;getNearbyAccounts($account, 10);



Once executed, the $this-&amp;gt;view-&amp;gt;accounts variable will contain an array of Account entities which represent users residing within a 10-mile radius of the user represented by the entity stored in $account.


Creating a Custom Repository


While Doctrine 2 supports several ways (three to be exact) to define the object-relational map, I’m an advocate of the Docblock annotations approach. Docblock annotations define the map using the same metadata syntax embraced by PHPDocumentor, allowing you to define the map right alongside the entity definition. For instance, here’s a snippet of the Account entity used in the Easy PHP Websites with the Zend Framework‘s companion project GameNomad:



&amp;lt;?php

namespace Entities;
use DoctrineCommonCollectionsArrayCollection;

/** 
 * @Entity
 * @Table(name="accounts") 
 * @HasLifecycleCallbacks
 */
class Account
{
  /**
   * @Id @Column(type="integer")
   * @GeneratedValue(strategy="AUTO")
   */
  private $id;

  /** @Column(type="string", length=255) */
  private $username;

  /** @Column(type="string", length=255) */
  private $email;

  /** @Column(type="string", length=32) */
  private $password;

  /** @Column(type="decimal", scale=6, precision=10) */
  private $latitude;

  /** @Column(type="decimal", scale=6, precision=10) */
  private $longitude;

  ...

?&amp;gt;



To associate a custom repository with the Account entity, all you have to do is modify the @Entity definition to look like this:
 


@Entity (repositoryClass="RepositoriesAccount") 



Next, create the custom repository and add the custom finder, which is presented below. Incidentally, the getNearbyAccounts() method defined in this custom repository uses another fantastic Doctrine 2 feature known as a native query, which allows you to map native SQL queries to Doctrine entities.



&amp;lt;?php

namespace Repositories;

use DoctrineORMEntityRepository;
use DoctrineORMQueryResultSetMapping;
use DoctrineDBALTypesType;

class Account extends EntityRepository
{
    
  public function getNearbyAccounts($account, $distance)
  {
    
    $rsm = new ResultSetMapping;
    
    $rsm-&amp;gt;addEntityResult('EntitiesAccount', 'a');
    $rsm-&amp;gt;addFieldResult('a', 'id', 'id');
    $rsm-&amp;gt;addFieldResult('a', 'username', 'username');
    $rsm-&amp;gt;addFieldResult('a', 'zip', 'zip');
    $rsm-&amp;gt;addFieldResult('a', 'latitude', 'latitude');
    $rsm-&amp;gt;addFieldResult('a', 'longitude', 'longitude');
    $rsm-&amp;gt;addFieldResult('a', 'confirmed', 'confirmed');    
    
    $query = $this-&amp;gt;_em-&amp;gt;createNativeQuery(
      "SELECT a.id, a.username, a.zip, a.latitude, a.longitude, a.confirmed, 
        ( 3959 * acos( cos( radians(?) ) * cos( radians( a.latitude ) ) * 
        cos( radians( a.longitude ) - radians(?) ) + sin( radians(?) ) * 
        sin( radians( a.latitude ) ) ) ) AS distance 
        FROM accounts a
        WHERE a.confirmed = 1
        GROUP BY a.id HAVING distance &amp;lt; ? 
        ORDER BY distance", $rsm
    );   
    
    $query-&amp;gt;setParameter(1, $account-&amp;gt;getLatitude());
    $query-&amp;gt;setParameter(2, $account-&amp;gt;getLongitude());
    $query-&amp;gt;setParameter(3, $account-&amp;gt;getLatitude());
    $query-&amp;gt;setParameter(4, $distance, Type::INTEGER);
    
    return $query-&amp;gt;getResult();
    
  }
  
}



With the custom repository and custom getNearbyAccounts() finder in place, you can begin calling this finder just like you would any other!



Want to learn a whole bunch more about Doctrine 2 and how to integrate it into the Zend Framework? Check out my book (DRM-free PDF), Easy PHP Websites with the Zend Framework (also available in Kindle and Nook formats)!</description>
      <dc:subject>Best Practices, Zend Framework</dc:subject>
      <dc:date>2011-04-09T21:01:12+00:00</dc:date>
    </item>

    <item>
      <title>Why I Published “Easy PHP Websites with the Zend Framework” Using Docbook and Open Source Tools</title>
      <link>http://www.wjgilmore.com/index.php/site/why_i_published_easy_php_websites_with_the_zend_framework_using_docboo/</link>
      <guid>http://www.wjgilmore.com/index.php/site/why_i_published_easy_php_websites_with_the_zend_framework_using_docboo/#When:15:45:59Z</guid>
      <description>After several months of rather hard work, on March 11 I published the long-awaited update to Easy PHP Websites with the Zend Framework. “Easy PHP Websites with the Zend Framework” is the first book of three I’ve self-published in the past two years, after having written four books for Apress (who I happen to still have a great relationship with thanks to the longetivity of Beginning PHP and MySQL, now in its fourth edition).
 



This was a particularly stressful project in that not only did I have pretty ambitious aspirations in terms of the content found in the update (including PHPUnit tests found at the conclusion of almost every chapter, a new chapter covering Capistrano-based deployment, and a huge companion project complete with all source code), but also because I was determined to write and produce the book using open source tools.



If you’ve ever worked with a traditional book publisher, it’s practically a certainty you’ll be asked to write the book using Microsoft Word (OpenOffice is also commonly supported). There’s good reason for the requirement; publishers have spent an enormous amount of time and money creating processes which allow camera-ready PDF documents to be created from stylized Word documents in a fairly straightforward way. All the author has to do is use Word to write each chapter, mark up the paragraphs, code and other elements using the provided styles, and everybody is happy.



Well, not quite everybody. While Word, OpenOffice, and similar products may be perfectly suitable for writing the next great American novel, they are horrifically maladapted for writing programming books. For starters, repeatedly copying code out of an IDE and into Word quickly becomes a tiresome and error-prone process, particularly after your technical reviewer has pointed out problems which require you to modify and test the code anew. For that matter, asking a technical reviewer to test code by repeatedly copying it from a Word document and into their development environment is completely unreasonable and will result in the reviewer not properly testing any of it, instead quietly opting for the “eyeball test”. Finally, most developers spend the majority of their day operating within a highly customized IDE, one which will undoubtedly play an integral part in the book writing process. So why should the developer be forced to suddenly spend evenings working within an unfamiliar writing environment? I could go on and on.



Yet familiarity is a funny thing, and so even after having decided to self-publish “Easy PHP Websites with the Zend Framework” the first time around, I stuck it out with Word. And all of the aforementioned problems made the entire process a fairly miserable one. In the end however the book wound up being a pretty successful first self-publishing effort, so when I set out to start work on the update there was little doubt I had to take a different route.


The Project Requirements


Having the advantage of working with a clean slate, I spent some time idealizing the perfect writing environment requirements:




I must be able to write the book in text format, preferably my IDE (which happens to be Eclipse running on Ubuntu) but at the very least in a lightweight text editor such as gedit.



I must be able to manage the book in version control (Git), allowing me to easily push changes to a private GitHub repository.



I must be able to easily convert the book from the source format into PDF, ePub, and HTML formats. By easily, I mean avoiding having to use a layout program such as Adobe InDesign.



I must be able to externally manage book assets, including notably code examples and images, and then integrate those examples into the book source code at build time (“build” defined as the point in which I create the PDF, ePub, and HTML formats).



I would prefer to manage many of the build-related tools via a unified build system such as Phing.




The Solution


Because I’m acting as both author and publisher, meeting the above requirements involves quite a few moving parts, all of which I’m happy to report were pretty easily handled after some investigation.


The Format


I quickly settled upon using one of three candidates: Docbook, HTML, or Markdown. Docbook was my immediate choice, because I had read that a pretty mature set of XSL tools and transformation recipes were available. HTML was a consideration because I’m a huge fan of Mark Pilgrim‘s work, and if it’s good enough for Mark, then it’s good enough for me. Markdown was also a consideration because I had the honor of editing the first edition of The Definitive Guide to Django: Web Development Done Right (Apress, 2007), authored by Adrian Holovaty and Jacob Kaplan-Moss, and marveled over how effectively they used it throughout the writing process.



I wound up going with Docbook based on the aforementioned toolset and considerable amount of online resources. While the XML tags are easy enough to use, in hindsight it turned out that transforming the Docbook files to a PDF which suited my stylistic desires was far more difficult than I imagined. Again in hindsight though, the difficulties were all related to the fact that I was a newbie. The trouble was well worth it, if for any other reason because I can build a camera-ready PDF and Kindle-ready ePub document from these source Docbook files in literally minutes.



Incidentally, after quickly tiring of simultaneously writing and marking up chapters using the Docbook styles, I stuck with exclusively writing and revising each chapter, and then marking it up afterwards. This allowed me to focus on writing the best possible book rather than constantly tweaking formatting directives, and resulted in a much better book.


Git


If you follow my Developer.com contributions, then you already know I’m a huge Git fan. It is by far the easiest and most natural way to manage source code that I’ve ever encountered (and I’ve tried all of them). I use it for managing practically everything, all of my writing included (I’ve even written about using Git to streamline writing projects, you can read the article here).



Given the above, it’s not a surprise I have been using Git to manage my book throughout the course of the entire project. From the version control standpoint, writing is quite different from coding in the sense that you probably won’t be reverting changes or anything like that, however Git has proven to be extremely useful for stashing changes, and branching in order to start work on a new chapter that I’m considering for a future update.



Due to a long history of laptop abuse I try to vigilantly backup material on a regular basis but hate dealing with DVDs and USB keys, so I use GitHub to regularly backup all of the chapters, code and images.


Building the ePub


Although I’ve historically sold a fair amount of books through WJGilmore.com, it would be foolhardy to ignore the industry 800LB gorilla, and so making a version available for the Amazon Kindle was an immediate priority. Amazon supports a proprietary book packaging format known as AZW, however you can upload books into their system http://kdp.amazon.com) in a variety of formats, ePub and MOBI included, and Amazon will convert the book for you.



To convert the Docbook-formatted book into ePub, I used the standard ePub stylesheet bundled with the Docbook distribution. Converting the book was as simple as executing the following command:



$ xsltproc /usr/share/xml/docbook/stylesheet/docbook-xsl/epub/docbook.xsl docbook.docbook



Executing this command creates two directories, OEBPS and META-INF, which form part of the ePub book. I stress part because you’re not done quite yet. Notably at a minimum you also need to create a mimetype file and also copy your images into the OEBPS directory. To my knowledge, ePub only supports GIF, JPEG, and PNG formats, which caused a bit of a problem for me because all of my screenshots were saved in TIFF format, however some ImageMagick magic converted all of my images in no time flat. Maybe in a future post I’ll talk more about this process, but for the moment if you are interested I suggest reading this excellent IBM developerWorks tutorial, authored by Liza Daly.



Because Amazon’s KDP service keeps spitting out into cryptic conversion errors when I try to upload ePub documents, I use Calibre to convert the ePub to MOBI format. For whatever reason Amazon is able to process the MOBI version without problems. Within 24 hours after uploading the book the book was available for sale. Using Barnes &amp;amp; Noble’s PubIT service is similarly easy, the only difference being it was able to process the original ePub document without problem. Like Amazon, the Nook version was available for sale within 24 hours.


Other Useful Tools


I’ve also taken advantage of a number of other useful tools throughout this process, including:



Aspell: Aspell is an open source spell checker. All you have to do is point Aspell to the document you want to spell check, and a streamlined interface appears which allows you to buzz through and correct potentially misspelled words in a very convenient fashion.
ImageMagick: I use ImageMagick to convert and resize screenshots.
pdftk: I use pdftk to merge my book cover and PDF.
GIMP: I use GIMP to touch up screenshots, including notably placing borders around them when applicable.


The Unified Build System


This is the most recent, and I think coolest addition to the process. I’ve lately been promoting the importance of setting up an automated website deployment process, having given several talks on the topic at various user groups. If you’re interested you can download the slides from GitHub Automating Deployments and Other Annoying Tasks with Phing, Capistrano and Liquibase). I wanted to create a similarly effective solution for building books, and so created a Phing build file which unifies the various commonly used commands. While not strictly necessary, it’s a very simple and convenient way to manage the various tasks. I’ve included a screenshot below:




Figure 1. Using Phing to manage book builds


Lessons Learned


I learned so many lessons throughout this process that it’s hard to distill them down into a few concluding paragraphs. It wasn’t as easy as I originally thought it would be, but the hard work has definitely paid off, and the system will allow me to write books at a speed never before imaginable. Writing has become a much more natural part of my daily operational workflow rather than something which requires special effort to settle into. Getting to this point wasn’t anywhere near as easy as I had expected, and there were no shortage of frustrating days throughout, however with one under my belt I really think the sky is the limit.



But the most enjoyable part of this process has come in recent days. In the days following the release, several readers e-mailed me pointing out various formatted-related issues. Each time I would fix the issue, rebuild the PDF and ePub versions, and deploy those versions to WJGilmore.com, Amazon.com, and BN.com in literally minutes. This ability to respond to reader feedback in mere minutes is extraordinary, and something which doesn’t happen in days nor weeks, and often not at all at traditional publishing houses.


Questions?


I love talking about this stuff. E-mail me at wjATwjgilmore.com with your questions.</description>
      <dc:subject />
      <dc:date>2011-03-17T15:45:59+00:00</dc:date>
    </item>

    <item>
      <title>Easy PayPal with PHP Now Available on the Nook!</title>
      <link>http://www.wjgilmore.com/index.php/site/easy_paypal_with_php_now_available_on_the_nook/</link>
      <guid>http://www.wjgilmore.com/index.php/site/easy_paypal_with_php_now_available_on_the_nook/#When:15:00:05Z</guid>
      <description>Easy PayPal with PHP is now available on the Nook!
Own the Barnes &amp;amp; Noble Nook and want to read Easy PayPal with PHP? Wait no more! Head on over to the Barnes &amp;amp; Noble website and purchase a copy now.

Kindle owners can also purchase a copy over at Amazon.com.</description>
      <dc:subject />
      <dc:date>2010-12-31T15:00:05+00:00</dc:date>
    </item>

    <item>
      <title>Route Optimization with the Google Maps API</title>
      <link>http://www.wjgilmore.com/index.php/site/route_optimization_with_the_google_maps_api/</link>
      <guid>http://www.wjgilmore.com/index.php/site/route_optimization_with_the_google_maps_api/#When:13:49:05Z</guid>
      <description>Have you ever wanted to know the shortest possible route travelled between multiple locations? So does the U.S. Postal Service, UPS, and thousands of other logistics and shipping companies around the world. In fact, known as the “travelling salesman problem”, it has been a problem under close scrutiny for more than a century. In the latest issue of JSMag, I show you how to incorporate the Google Maps API’s traveling salesman algorithm implementation into your location-based services!
Have you ever wanted to know the shortest possible route travelled between multiple locations? So does the U.S. Postal Service, UPS, and thousands of other logistics and shipping companies around the world. In fact, known as the “travelling salesman problem”, it has been a problem under close scrutiny for more than a century. In the latest issue of JSMag, I show you how to incorporate the Google Maps API’s traveling salesman algorithm implementation into your location-based services!

Learn more about JSMag</description>
      <dc:subject>Google Maps API</dc:subject>
      <dc:date>2010-11-03T13:49:05+00:00</dc:date>
    </item>

    <item>
      <title>Ten Tips and Tricks for mysql Client Users</title>
      <link>http://www.wjgilmore.com/index.php/site/ten_tips_and_tricks_for_mysql_client_users/</link>
      <guid>http://www.wjgilmore.com/index.php/site/ten_tips_and_tricks_for_mysql_client_users/#When:15:38:55Z</guid>
      <description>Although several great GUI-based MySQL clients exist, among them phpMyAdmin and SQLYog, I’ve always preferred to use the native mysql command-line client. It does take some time to get acquainted with using a command-line interface (CLI), particularly if you don’t regularly work with an operating system offering a robust CLI environment. However, after some practice you’ll be able to manage users, navigate your databases, and perform other tasks with incredible ease.
Although several great GUI-based MySQL clients exist, among them phpMyAdmin and SQLYog, I’ve always preferred to use the native mysql command-line client. It does take some time to get acquainted with using a command-line interface (CLI), particularly if you don’t regularly work with an operating system offering a robust CLI environment. However, after some practice you’ll be able to manage users, navigate your databases, and perform other tasks with incredible ease.

In this article I’ll introduce you to 10 mysql client tips and tricks that I’ve accumulated over the years. Whether you adopt one or all I guarantee you’ll save a considerable amount of time and effort when using this powerful MySQL interface.

Read the tutorial</description>
      <dc:subject>Best Practices, MySQL</dc:subject>
      <dc:date>2010-10-29T15:38:55+00:00</dc:date>
    </item>

    <item>
      <title>Enforcing PHP Coding Standards with PHP_CodeSniffer</title>
      <link>http://www.wjgilmore.com/index.php/site/enforcing_php_coding_standards_with_php_codesniffer/</link>
      <guid>http://www.wjgilmore.com/index.php/site/enforcing_php_coding_standards_with_php_codesniffer/#When:16:52:40Z</guid>
      <description>In light of PHP’s considerable expressive flexibility, how can you actively enforce a coding standard and prevent both yourself and your team members from reverting to bad habits? One great solution called PHP_CodeSniffer is (coincidentally) found in a PEAR package. PHP_CodeSniffer can not only parse PHP code to ensure it meets a particular coding standard but it can also examine your JavaScript and CSS files for potential standards violations. Read on to learn how to use PHP_CodeSniffer!
In light of PHP’s considerable expressive flexibility, how can you actively enforce a coding standard and prevent both yourself and your team members from reverting to bad habits? One great solution called PHP_CodeSniffer is (coincidentally) found in a PEAR package. PHP_CodeSniffer can not only parse PHP code to ensure it meets a particular coding standard but it can also examine your JavaScript and CSS files for potential standards violations.

Read on to learn how to use PHP_CodeSniffer!

&amp;raquo; Read the tutorial</description>
      <dc:subject>Best Practices, PHP</dc:subject>
      <dc:date>2010-10-22T16:52:40+00:00</dc:date>
    </item>

    
    </channel>
</rss>
