<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Raymond Kolbe &#187; PHP/MySQL</title>
	<atom:link href="http://www.raymondkolbe.com/category/computer-related/phpmysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.raymondkolbe.com</link>
	<description>Code, cars, and beer...</description>
	<lastBuildDate>Sun, 07 Feb 2010 17:14:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Zend, Twitter, and OAuth Made Easy</title>
		<link>http://www.raymondkolbe.com/2009/10/03/zend-twitter-and-oauth-made-easy/</link>
		<comments>http://www.raymondkolbe.com/2009/10/03/zend-twitter-and-oauth-made-easy/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 23:24:50 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Computer Related]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=398</guid>
		<description><![CDATA[I have been working on a Twitter service as of late and ran into a problem that I am sure others have as well and ended up solving it in their own way.  However, after searching high and low on the Internet for an elegant solution, I came up with nothing and found I [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working on a Twitter service as of late and ran into a problem that I am sure others have as well and ended up solving it in their own way.  However, after searching high and low on the Internet for an elegant solution, I came up with nothing and found I was on my own.  This post is for those of you who are, or will be, using Zend_Service_Twitter and need Twitter users to grant your application access to their account information in a secure way.</p>
<p>The project I am working on requires that users allow my Twitter service to access their account information.  The only reason I require this is because this service makes several API requests over the course of time, and instead of having users use up all of my allotted API service requests, I use their&#8217;s instead,  It&#8217;s a little more complicated than that, and a full explanation falls outside the scope of this post.  All you need to keep in mind for this post is that I need to have access to their account so API calls are counted on their behalf and not my server&#8217;s.</p>
<p>Currently, Zend Framework 1.9 only supports basic authentication for the Twitter API, which works well, but leaves, or should leave, a bad taste in the end-user&#8217;s and developer&#8217;s mouth.  I say this because a developer who wants access to a user&#8217;s account at a later time (e.g. if you are running scheduled API calls) will have to store the user&#8217;s credentials on the server.  This means A) the user may be iffy about using your service since they may not trust your site and/or want their password stored on your server, and B) this creates more overhead for you because you now have to keep track of user information, keep it secure, etc.  The way we get rid of this bad taste is to implement a system such as OAuth.</p>
<p>OAuth is an authentication protocol that allows secure API authorization for applications.  What this means is that a user can grant you, the 3rd party developer, access to their information without providing you with their username and password.  User login takes place at the source, in this case at Twitter.com.  For more information about OAuth, please see the <a href="http://apiwiki.twitter.com/OAuth-FAQ">Twitter API Wiki / OAuth FAQ</a></p>
<p>If you are currently using the Twitter API, it is probably better to change over to using OAuth sooner than later since support for basic authentication will be going away in the future.</p>
<p>In order to get Zend_Service_Twitter working with OAuth, you will need to obtain OAuth via subversion since it is not in the currently released version of Zend Framework.  It can be obtained <a href="http://framework.zend.com/svn/framework/standard/incubator/library/Zend/Oauth/">here</a>.</p>
<p>The code you are about the see takes place in my IndexController, meaning I am using Zend&#8217;s MVC setup.  I have also put configuration information inline so you can see exactly what is passed into each object.</p>
<pre class="brush: php;">
&lt;?php
/**
 * Default Index Controller using Zend's MVC implementation.
 *
 * @author Raymond J. Kolbe &lt;rkolbe@white-box.us&gt;
 */
class IndexController extends Zend_Controller_Action
{
    /**
     * Login Action
     *
     * Performs user login through Twitter using OAuth.  If user's have not
     * granted our application access to their account, they will be sent to
     * Twitter to do so.  Once done, they will return to this page again so
     * that we can handle them (e.g. run our application for them).
     *
     * @param void
     * @return void
     */
    public function loginAction()
    {
        // Check to see if the user already has an OAuth access token
        if ($this-&gt;_session-&gt;access_token) {
            // You would redirect the user to the main part of your
            // application that they needed to be authenticated for.
        }
        // Configuration for OAuth. @see Zend_Oauth_Consumer
        $config = array(
            'signatureMethod' =&gt; 'HMAC-SHA1',
            'callbackUrl' =&gt; 'http://localhost/login',
            'requestTokenUrl' =&gt; 'http://twitter.com/oauth/request_token',
            'authorizeUrl' =&gt; 'http://twitter.com/oauth/authorize',
            'accessTokenUrl' =&gt; 'http://twitter.com/oauth/access_token',
            'consumerKey' =&gt; 'jDrJud90Jhg66whddj876',
            'consumerSecret' =&gt; 'UdjneHdyGsj90Bsg2UdjneHdyGsj90Bsg2'
        );
        $consumer = new Zend_Oauth_Consumer($config);
        // If we do not have a request token, generate one now
        if (!$this-&gt;_session-&gt;request_token) {
            $request_token = $consumer-&gt;getRequestToken();
            // Save the token for when the user returns to this page.
            // This will be used to get the user's access token.
            $this-&gt;_session-&gt;request_token = serialize($request_token);
            // Send the user off to Twitter to grant our application access
            $consumer-&gt;redirect();
            return;
        }
        // If we made it here, the user has been to Twitter to grant our
        // application access and now we must get an access token that
        // will allow us to make API calls on behalf of the user.
        $access_token = $consumer-&gt;getAccessToken($this-&gt;_request-&gt;getQuery(), unserialize($this-&gt;_session-&gt;request_token));
        // We no longer need the request token so remove it
        unset($this-&gt;_session-&gt;request_token);
        // Save to session so that reloading of this page will send the user
        // to your application main page or wherever you want them to go.
        $this-&gt;_session-&gt;access_token = serialize($access_token);
        // This line is very important. Since Zend_Service_Twitter does
        // not have support for OAuth (yet), this is how we get it to work.
        // All we are doing is making Zend_Service_Twitter use OAuth's
        // HTTP Client instance, which will automatically append the proper
        // OAuth query info to any Twitter service call we make from here
        // on out.
        Zend_Service_Twitter::setHttpClient($access_token-&gt;getHttpClient($config));
        // Username and password are passed in as null because we will not be
        // authenticating using a user/pass combo (which uses basic
        // authentication).
        $twitter = new Zend_Service_Twitter(null, null);
        // This is not required but shows you as an example that OAuth did
        // in fact work.
        $response = $twitter-&gt;account-&gt;verifyCredentials();
        // Your code goes here.  This would be the point you want to save
        // the access token to the database for later use and/or save a cookie
        // on the user's system.
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/10/03/zend-twitter-and-oauth-made-easy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Solar e-mail helper that stops spammers</title>
		<link>http://www.raymondkolbe.com/2009/08/19/solar-e-mail-helper-that-stops-spammers/</link>
		<comments>http://www.raymondkolbe.com/2009/08/19/solar-e-mail-helper-that-stops-spammers/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 02:25:37 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Cookbook]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[Solar]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=393</guid>
		<description><![CDATA[Tonight I created a helper for Solar that encodes mailto href addresses so SPAMers that scrape HTML pages will never get your addresses.
To use this helper, just do the following in your views/layouts:
echo $this-&#62;email('someuser@somehost.com', 'Ray');
Here is the helper code:
&#60;?php
/**
 * Generates an encoded mailto href to stop spammers from scrapping email
 * addresses from your [...]]]></description>
			<content:encoded><![CDATA[<p>Tonight I created a helper for Solar that encodes mailto href addresses so SPAMers that scrape HTML pages will never get your addresses.</p>
<p>To use this helper, just do the following in your views/layouts:</p>
<pre class="brush: php;">
echo $this-&gt;email('someuser@somehost.com', 'Ray');
</pre>
<p>Here is the helper code:</p>
<pre class="brush: php;">
&lt;?php
/**
 * Generates an encoded mailto href to stop spammers from scrapping email
 * addresses from your web pages.  This code is based on the PHP example
 * from http://rumkin.com/tools/mailto_encoder/
 *
 * @category Whitebox
 * @package Whitebox_View
 * @author Raymond J. Kolbe &lt;rkolbe@gmail.com&gt;
 */
class Whitebox_View_Helper_Email extends Solar_View_Helper {
    /**
     * The encoded email address.
     *
     * @var string
     */
    protected $_encoded_string = '';
    /**
     * The encoded index used to decode $_encoded_string/
     *
     * @var string
     */
    protected $_encoded_indexes = '';
    /**
     * Generates an encoded mailto href to stop spammers from
     * scrapping email addresses off your web pages.  Returns
     * an inline javascript code block that allows web browser
     * to read the mailto href.
     *
     * If javascript is disabled in the web browser, only the
     * link text is shown to the user.
     *
     * @param string $spec The email address (e.g. rkolbe@gmail.com)
     * @param string $text Href
     * @param array $attribs An array of href attributes
     * @return string An inline string of javascript to handle the
     * encoded mailto href
     */
    public function email($spec, $text = null, $attribs = null) {
        // escape the email address
        $spec = $this-&gt;_view-&gt;escape($spec);
        // build attribs, after dropping any 'href' attrib
        $attribs = (array) $attribs;
        unset($attribs['href']);
        $attribs = $this-&gt;_view-&gt;attribs($attribs);
        $this-&gt;_obfuscate(&quot;&lt;a href=\&quot;mailto:$spec\&quot;$attribs&gt;$text&lt;/a&gt;&quot;);
        $script = $this-&gt;_getScript();
        $script .= '&lt;noscript&gt;'.$text.'&lt;/noscript&gt;';
        return $script;
    }
    /**
     * Takes a given href and obfuscates it.
     *
     * @param string $link A full mailto href
     * @return void
     */
    protected function _obfuscate($link) {
        $scrambled_chars = str_shuffle($link);
        $this-&gt;_encoded_string = $this-&gt;_escapeString($scrambled_chars);
        $string_indexes = '';
        for ($i = 0; $i &lt; strlen($link); $i++) {
            $index = strpos($scrambled_chars, substr($link, $i, 1)) + 48;
            $string_indexes .= chr($index);
        }
        $this-&gt;_encoded_indexes = $this-&gt;_escapeString($string_indexes);
    }
    /**
     * Returns a block of javascript used to decode the mailto href.
     * This only allows web browsers to see the mailto address.
     *
     * @param void
     * @return string An inline block of javascript
     */
    protected function _getScript() {
        return $this-&gt;_view-&gt;scriptInline('&lt;!--
            chars = &quot;'.$this-&gt;_encoded_string.'&quot;;
            indexes = &quot;'.$this-&gt;_encoded_indexes.'&quot;;
            href = &quot;&quot;;
            for(j = 0; j &lt; indexes.length; j++){
                href += chars.charAt(indexes.charCodeAt(j) - 48);
            }
            document.write(href);
            // --&gt;');
    }
    /**
     * Prepares (escapes) a string for javascript.
     *
     * @param string $string The string to escape
     * @return string The escaped string
     */
    protected function _escapeString($string) {
        $string = str_replace(&quot;\\&quot;, &quot;\\\\&quot;, $string);
        $string = str_replace(&quot;\&quot;&quot;, &quot;\\\&quot;&quot;, $string);
        return $string;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/08/19/solar-e-mail-helper-that-stops-spammers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Table view helper it out!</title>
		<link>http://www.raymondkolbe.com/2009/07/25/table-view-helper-it-out/</link>
		<comments>http://www.raymondkolbe.com/2009/07/25/table-view-helper-it-out/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 17:00:15 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Cookbook]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[helper]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=390</guid>
		<description><![CDATA[Table view helper has been released!  Since my last post about writing a helper such as this, a lot has changed.  I hope to have API docs up soon. In the meantime you can download the code and check out the examples at its new project page.
]]></description>
			<content:encoded><![CDATA[<p>Table view helper has been released!  Since my last post about writing a helper such as this, a lot has changed.  I hope to have API docs up soon. In the meantime you can download the code and check out the examples at its new <a href="projects/table/">project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/07/25/table-view-helper-it-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Table helper</title>
		<link>http://www.raymondkolbe.com/2009/07/09/table-helper/</link>
		<comments>http://www.raymondkolbe.com/2009/07/09/table-helper/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 03:34:41 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[Solar]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=362</guid>
		<description><![CDATA[Thought I would give you all a sneak peek at the table helper class I am working on.  I&#8217;m not a big fan of table helper classes but I kind of found a use for a helper such as this for one of my projects&#8211;plus it&#8217;s neat.
$table = new Table();
$table-&#62;setCssId('my_table');
$table-&#62;addCssClasses('default big_text');
$thead = $table-&#62;addGroup('thead')-&#62;addCssClass('thead_tag_css_class');
$row1 = [...]]]></description>
			<content:encoded><![CDATA[<p>Thought I would give you all a sneak peek at the table helper class I am working on.  I&#8217;m not a big fan of table helper classes but I kind of found a use for a helper such as this for one of my projects&#8211;plus it&#8217;s neat.</p>
<pre class="brush: php;">
$table = new Table();
$table-&gt;setCssId('my_table');
$table-&gt;addCssClasses('default big_text');
$thead = $table-&gt;addGroup('thead')-&gt;addCssClass('thead_tag_css_class');
$row1 = $thead-&gt;addRow()-&gt;addCssClass('sample_css_heading');
$row1-&gt;addHeadingCell('Name');
$row1-&gt;addHeadingCell('Sex');
$row1-&gt;addHeadingCell('Position');
$row1-&gt;addHeadingCell('Top 2 favorite colors')-&gt;colSpan(2);
// rows that are not instantiated from addGroup() are added to tbody
$row2 = $table-&gt;addRow();
$row2-&gt;addDataCell('Adam Smith');
$row2-&gt;addDataCell('Male');
$row2-&gt;addDataCell('Economist');
$row2-&gt;addDataCell('Black');
$row2-&gt;addDataCell('White');
$tfoot = $table-&gt;addGroup('tfoot');
// empty data cells make sure we are compliant
// empty cells default to &amp;nbsp;
$row3 = $tfoot-&gt;addRow();
$row3-&gt;addDataCell('example footer data');
$row3-&gt;addDataCell();
$row3-&gt;addDataCell();
$row3-&gt;addDataCell();
$row3-&gt;addDataCell();
// we can also just call print $table;
print $table-&gt;display()
</pre>
<p>Produces&#8230;</p>
<pre class="brush: xml;">
&lt;table id=&quot;my_table&quot; class=&quot;default big_text&quot;&gt;
    &lt;thead class=&quot;thead_tag_css_class&quot;&gt;
            &lt;tr class=&quot;sample_css_heading&quot;&gt;
        &lt;th&gt;
            Name
        &lt;/th&gt;
        &lt;th&gt;
            Sex
        &lt;/th&gt;
        &lt;th&gt;
            Position
        &lt;/th&gt;
        &lt;th colspan=&quot;2&quot;&gt;
            Top 2 favorite colors
        &lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tfoot&gt;
            &lt;tr&gt;
        &lt;td&gt;
            example footer data
        &lt;/td&gt;
        &lt;td&gt;
            &amp;nbsp;
        &lt;/td&gt;
        &lt;td&gt;
            &amp;nbsp;
        &lt;/td&gt;
        &lt;td&gt;
            &amp;nbsp;
        &lt;/td&gt;
        &lt;td&gt;
            &amp;nbsp;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tfoot&gt;
    &lt;tbody&gt;
            &lt;tr&gt;
        &lt;td&gt;
            Adam Smith
        &lt;/td&gt;
        &lt;td&gt;
            Male
        &lt;/td&gt;
        &lt;td&gt;
            Economist
        &lt;/td&gt;
        &lt;td&gt;
            Black
        &lt;/td&gt;
        &lt;td&gt;
            White
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
</pre>
<p>I still have some refactoring/testing/fixing to do but I hope to release this package soon under the GPLv3.  I have also been throwing the idea around of being able to have this class generate CSS tables&#8211;e.g. fetchCssTable() and displayCssTable() (something like that) that would return both a CSS stylesheet and the proper div tags for the table itself.</p>
<p>Once I&#8217;m happy with this package I will also convert it over to <a href="http://solarphp.com">Solar </a>since it lacks this type of helper.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/07/09/table-helper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Savant3 URI Plugin</title>
		<link>http://www.raymondkolbe.com/2009/06/14/savant3-uri-plugin/</link>
		<comments>http://www.raymondkolbe.com/2009/06/14/savant3-uri-plugin/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 16:24:35 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[Solar]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[savant3]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=274</guid>
		<description><![CDATA[I started working on a small project last weekend for a [H]ard&#124;Forum member that would allow viewing maillog log info from a web site.  I wanted to make an app that would have a small footprint and would be easy to manage (code base wise as well as UI).  My first instinct was [...]]]></description>
			<content:encoded><![CDATA[<p>I started working on a small project last weekend for a <a href="http://hardforum.com">[H]ard|Forum</a> member that would allow viewing maillog log info from a web site.  I wanted to make an app that would have a small footprint and would be easy to manage (code base wise as well as UI).  My first instinct was to use a MVC framework like <a href="http://solarphp.com">Solar</a> or <a href="http://framework.zend.com">Zend</a> but those two have more features than what I needed for this project.  Remember, I wanted a small footprint.</p>
<p>I decided to give <a href="http://phpsavant.com/">Savant3</a> a shot.  This at least allows me to separate my controller logic from my view logic.  I only had one controller and one template so code overhead wasn&#8217;t an issue.</p>
<p>One of the things missing from this system was a way to easily handle URIs/URLs.  Since Savant3 is a template engine, I wouldn&#8217;t necessarily expect a URI handler.  However, I felt that having a plugin that handles URIs was worth the effort, even with a project of this size.</p>
<p>Since the plugin code is still a bit messy (missing inline docs, needs a little bit of refactoring, etc) I can only show you usage examples for now.  I plan on cleaning up the code and releasing the plugin on this site shortly.</p>
<p>Here is how one might use this URI plugin in a Savant3 template:</p>
<pre class="brush: php;">
// builds the URI based off of the current URL
$uri = $this-&gt;uri()-&gt;fromCurrentUrl();
// allows setting query info
$uri-&gt;query = 'order=name_asc';
// this adds to the query, it does not overwrite it
$uri-&gt;query = 'page=2';
// returns only the query portion: '?order=name&amp;page=2'
$uri-&gt;get();
// this will update page to 'page=3'
$uri-&gt;query = 'page=3';
// again we only return the query portion: '?order=name&amp;page=3'
$uri-&gt;get();
// we can also set a full query as well and we can provide keys without values
$uri-&gt;query = 'order=name_desc&amp;page=3&amp;submitted'
// currently there is not a way to remove a single piece of the query
// we have to reset the whole query and rebuild it
unset($uri-&gt;query);
// passing 'true' to get() gives us the whole URI
// for example: http://white-box.us/somedir/index.php
$uri-&gt;get(true);
</pre>
<p>The rest of the functionality works much like <a href="http://solarphp.com/class/Solar_Uri">Solar_Uri</a> (currently w/the exception of path and query behavior), being able to set each piece of the URI before returning a newly built URI.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/06/14/savant3-uri-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dropbox API</title>
		<link>http://www.raymondkolbe.com/2009/05/29/dropbox-api/</link>
		<comments>http://www.raymondkolbe.com/2009/05/29/dropbox-api/#comments</comments>
		<pubDate>Sat, 30 May 2009 02:37:01 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Computer Related]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=271</guid>
		<description><![CDATA[http://code.google.com/p/dropbox-api/
A while back (3 or 4 months) I emailed the guys over at Dropbox asking them about a public API.  The response I got was basically that in the near future they will have something.  I want it now!!  Guess I will have to keep tabs on that Google Group (link above).
]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/dropbox-api/">http://code.google.com/p/dropbox-api/</a></p>
<p>A while back (3 or 4 months) I emailed the guys over at Dropbox asking them about a public API.  The response I got was basically that in the near future they will have something.  I want it now!!  Guess I will have to keep tabs on that Google Group (link above).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/05/29/dropbox-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modifying Solar_View_Helper_Form</title>
		<link>http://www.raymondkolbe.com/2009/05/23/modifying-solar-view-helper-form/</link>
		<comments>http://www.raymondkolbe.com/2009/05/23/modifying-solar-view-helper-form/#comments</comments>
		<pubDate>Sat, 23 May 2009 18:34:57 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Cookbook]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[Solar]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=221</guid>
		<description><![CDATA[Solar comes packed with many different view helpers that will make your life easier, such as inserting images, creating links, and generating forms.  However, sometimes a generic helper doesn&#8217;t cut it for custom behavior in a project.  For example, I wanted to change the way form field hints (field descriptions) and error messages [...]]]></description>
			<content:encoded><![CDATA[<p>Solar comes packed with many different <a href="http://solarphp.com/package/Solar_View">view helpers</a> that will make your life easier, such as <a href="http://solarphp.com/class/Solar_View_Helper_Image">inserting images</a>, <a href="http://solarphp.com/class/Solar_View_Helper_Href">creating links</a>, and <a href="http://solarphp.com/package/Solar_View_Helper_Form">generating forms</a>.  However, sometimes a generic helper doesn&#8217;t cut it for custom behavior in a project.  For example, I wanted to change the way form field hints (field descriptions) and error messages were displayed for the registration form at <a href="http://fahwebmon.white-box.us">http://fahwebmon.white-box.us</a>.  <strong>Note</strong> that I am using Solar_View_Helper_Form::auto() to generate my form automagically.  The only downside to this is that you do not have control over where errors are displayed on a page.</p>
<p><span id="more-221"></span></p>
<p>The default behavior of Solar_View_Helper_Form will output error messages like this:</p>
<p><img class="aligncenter size-full wp-image-234" title="default_behavior" src="http://white-box.us/wp-content/uploads/2009/05/default_behavior.jpg" alt="default_behavior" width="400" height="235" /></p>
<p>However, I had two things I needed to accomplish, 1) create form field hints that are displayed only when a text field is clicked, and 2) move all error messages to the top of the page.</p>
<p>Displaying the field hints was the easy part.  The form helper automatically adds in a class named &#8216;descr&#8217; to each field.  I decided to use this class name with a little jQuery (<a href="http://docs.jquery.com/Events/focus">focus</a> and <a href="http://docs.jquery.com/Events/blur">blur</a>) to accomplish my form hint behavior.</p>
<p>The issue I ran into was when the form had errors and a field containing a hint was displayed.</p>
<p><img class="aligncenter size-full wp-image-238" title="default_behavior_hint" src="http://white-box.us/wp-content/uploads/2009/05/default_behavior_hint.jpg" alt="default_behavior_hint" width="400" height="211" /></p>
<p>You can see that the hint should be aligned with the first text field, Username.  A little bit of Javascript and CSS manipulation could solve this problem but I wanted to consolidate the error messages to an eye catching location anyway, which in turn would solve my alignment issue.</p>
<p>Before I provide you with my solution, let me show you what the finished product looks like:</p>
<p><img class="aligncenter size-full wp-image-240" title="modified_behavior_hint" src="http://white-box.us/wp-content/uploads/2009/05/modified_behavior_hint.jpg" alt="modified_behavior_hint" width="400" height="206" /></p>
<p>You can see I have an eye catching error div at the top followed by the hint box being properly aligned.  I still need to implement either a) a red asterisk next to each invalid field or b) change the label colors to red.  I also need to update my error messages so they read proper.  Both of these minor changes are not solve in this blog post.  I&#8217;ll save that for a rainy day <img src='http://www.raymondkolbe.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><img class="alignright size-full wp-image-244" title="netbeans_screenshot" src="http://white-box.us/wp-content/uploads/2009/05/netbeans_screenshot.jpg" alt="netbeans_screenshot" width="151" height="144" />So, how did I do this?  I simply copied down Solar_View_Helper_Form from the Solar project to my working directory (Fahwebmon/View/Helper/Form.php) and renamed the class to Fahwebmon_View_Helper_Form.  <strong>Note</strong> that you don&#8217;t have to copy down the whole file.  You can create your own class and extend Solar_View_Helper_Form since we are only modifying the fetch() method on this class.</p>
<p>Here is the modified code.  <strong>Note</strong> that I have only tested this with text fields.</p>
<pre class="brush: php;">
public function fetch($with_form_tag = true)
{
// stack of output elements
$form = array();
$feedback = array();
// the form tag itself?
if ($with_form_tag) {
$form[] = '&lt;form' . $this-&gt;_view-&gt;attribs($this-&gt;_attribs) . '&gt;';
}
// what status class should we use?
if ($this-&gt;_status === true) {
$class = $this-&gt;_css_class['success'];
$feedback = $this-&gt;_feedback;
} elseif ($this-&gt;_status === false) {
$class = $this-&gt;_css_class['failure'];
} else {
$feedback = null;
$class = null;
}
// the hidden elements
if ($this-&gt;_hidden) {
// wrap in a hidden fieldset for XHTML-Strict compliance
$form[] = '    &lt;fieldset style=&quot;display: none;&quot;&gt;';
foreach ($this-&gt;_hidden as $info) {
$form[] = '        ' . $this-&gt;_view-&gt;formHidden($info);
}
$form[] = '    &lt;/fieldset&gt;';
$form[] = '    ';
}
// loop through the stack
$in_dl       = false;
$in_fieldset = false;
$in_group    = false;
foreach ($this-&gt;_stack as $key =&gt; $val) {
$type = $val[0];
$info = $val[1];
if ($type == 'element') {
// be sure we're in a &lt;dl&gt; block
if (! $in_dl) {
$form[] = '        &lt;dl&gt;';
$in_dl = true;
}
// setup
$label    = $this-&gt;_view-&gt;getText($info['label']);
$id       = $this-&gt;_view-&gt;escape($info['attribs']['id']);
$method   = 'form' . ucfirst($info['type']);
try {
// look for the requested element helper
$helper = $this-&gt;_view-&gt;getHelper($method);
} catch (Solar_Class_Stack_Exception_ClassNotFound $e) {
// use 'text' helper as a fallback
$method = 'formText';
$helper = $this-&gt;_view-&gt;getHelper($method);
}
// SPECIAL CASE:
// checkboxes that are not in groups don't get an &quot;extra&quot; label.
if (strtolower($info['type']) == 'checkbox' &amp;&amp; ! $in_group) {
$info['label'] = null;
}
// get the element output
$element = $helper-&gt;$method($info);
// get the element description
$dt_descr = '';
$dd_descr = '';
// only build a description if it's non-empty, and isn't a
// DESCR_* &quot;empty&quot; locale value.
if ($info['descr'] &amp;&amp; substr($info['descr'], 0, 6) != 'DESCR_') {
// build the base description.
// open the tag ...
$descr = &quot;&lt;&quot; . $this-&gt;_view-&gt;escape($this-&gt;_descr_tag);
// ... add a CSS class ...
if ($this-&gt;_descr_class) {
$descr .= ' class=&quot;'
. $this-&gt;_view-&gt;escape($this-&gt;_descr_class)
. '&quot;';
}
// ... add the raw descr XHTML, and close the tag.
$descr .= '&gt;' . $info['descr']
. '&lt;/' . $this-&gt;_view-&gt;escape($this-&gt;_descr_tag) . '&gt;';
// build both the &lt;dt&gt; and &lt;dd&gt; forms so we can use
// them in the right place.
if ($this-&gt;_descr_elem == 'dt') {
// using &lt;dt&gt;
$dt_descr = $descr;
} else {
// using &lt;dd&gt;
$dd_descr = $descr;
}
}
// add the element;
// handle differently if we're in a group.
if ($in_group) {
// add the element itself
$form[] = &quot;                $element&quot;;
} else {
$require = '';
// is the element required?
if ($info['require']) {
$require = ' class=&quot;' . $this-&gt;_css_class['require'] . '&quot;';
}
// add the form element with all parts in place
$form[] = &quot;            &lt;dt$require&gt;&lt;label$require for=\&quot;$id\&quot;&gt;$label&lt;/label&gt;$dt_descr&lt;/dt&gt;&quot;;
$form[] = &quot;            &lt;dd$require&gt;$element$dd_descr&lt;/dd&gt;&quot;;
$form[] = '';
}
// handle element feedback
if (!empty($info['invalid'])) {
foreach ($info['invalid'] as $invalid) {
$feedback[] = $label . ' ' . strtolower(substr($invalid, 0, 1) . substr($invalid, 1));
}
}
} elseif ($type == 'group') {
// be sure we're in a &lt;dl&gt; block
if (! $in_dl) {
$form[] = '        &lt;dl&gt;';
$in_dl = true;
}
$flag = $info[0];
$label = $info[1];
if ($flag) {
$in_group = true;
$form[] = &quot;            &lt;dt&gt;&lt;label&gt;$label&lt;/label&gt;&lt;/dt&gt;&quot;;
$form[] = &quot;            &lt;dd&gt;&quot;;
} else {
$in_group = false;
$form[] = &quot;            &lt;/dd&gt;&quot;;
$form[] = '';
}
} elseif ($type == 'fieldset') {
$flag = $info[0];
$legend = $this-&gt;_view-&gt;getText($info[1]);
if ($flag) {
$form[] = &quot;    &lt;fieldset&gt;&lt;legend&gt;$legend&lt;/legend&gt;&quot;;
$form[] = &quot;        &lt;dl&gt;&quot;;
$in_fieldset = true;
$in_dl = true;
} else {
$form[] = &quot;        &lt;/dl&gt;&quot;;
$form[] = &quot;    &lt;/fieldset&gt;&quot;;
$form[] = '';
$in_dl = false;
$in_fieldset = false;
}
}
}
if ($in_group) {
$form[] = '            &lt;/dd&gt;';
}
if ($in_dl) {
$form[] = '        &lt;/dl&gt;';
}
if ($in_fieldset) {
$form[] = '    &lt;/fieldset&gt;';
}
// add a closing form tag? This also determins where feedback should be.
if ($with_form_tag) {
// temporarily grab the open form tag and remove it from the array
$openFormTag = array_shift($form);
// add the form open tag and feedback
array_unshift($form, $openFormTag, $this-&gt;listFeedback($feedback, $class));
// finally add the closing form tag
$form[] = '&lt;/form&gt;';
} else {
// inject feedback as first element
array_unshift($form, $this-&gt;listFeedback($feedback, $class));
}
// reset for the next pass
$this-&gt;reset();
// done, return the output!
return implode(&quot;\n&quot;, $form);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/05/23/modifying-solar-view-helper-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BBCode PHP Syntax Highlighting For Lazy People</title>
		<link>http://www.raymondkolbe.com/2009/04/26/bbcode-php-syntax-highlighting-for-lazy-people/</link>
		<comments>http://www.raymondkolbe.com/2009/04/26/bbcode-php-syntax-highlighting-for-lazy-people/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 00:28:18 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Cookbook]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=92</guid>
		<description><![CDATA[While working on one of my little side projects, I came across a problem where I wanted to highlight bbcode syle php tags in my text (e.g. [PHP] echo &#8220;code goes here&#8221;; [/PHP]).
Being lazy and using regex (I love it!), I came up with the following solution:
// test text w/embedded code
$text = &#34;This is a [...]]]></description>
			<content:encoded><![CDATA[<p>While working on one of my little side projects, I came across a problem where I wanted to highlight bbcode syle php tags in my text (e.g. [PHP] echo &#8220;code goes here&#8221;; [/PHP]).</p>
<p>Being lazy and using regex (I love it!), I came up with the following solution:</p>
<pre class="brush: php;">
// test text w/embedded code
$text = &quot;This is a sample text string with PHP style tags. [PHP] echo 'Hello'; [/PHP]
// and I made sure to make this case insensitive.
$pattern = &quot;/\[PHP\](.*)\[\/PHP\]/Uis&quot;;
// the magic!
$matchCount = preg_match_all($pattern, $text, $matches, PREG_SET_ORDER);
if ($matchCount !== false &amp;&amp; $matchCount &gt; 0) {
    foreach ($matches as $match) {
        // highlight_string forces us to start with at least the php opening tag
        $highlightedCode = highlight_string('&lt;?php'.$match[1].'?&gt;', true);
        // finally, replace the original non-highlighted text with the highlighted text
        $text = preg_replace($pattern, $highlightedCode, $text, 1);
    }
}
echo $text;
</pre>
<p>Just FYI, this was a quick one-off and wasn&#8217;t intended to scale with other bbcode style tags.  Also, in my real code, the [PHP] tags are lowercase.  The only reason they are uppercase is because the syntax highlighter in Wordpress isn&#8217;t smart enough to distinguish the tags in my code and tags to signify syntax highlighting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/04/26/bbcode-php-syntax-highlighting-for-lazy-people/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend PHP5 Certification Study Guide Annoyance</title>
		<link>http://www.raymondkolbe.com/2009/04/18/zend-php5-certification-study-guide-annoyance/</link>
		<comments>http://www.raymondkolbe.com/2009/04/18/zend-php5-certification-study-guide-annoyance/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 21:15:24 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Computer Related]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[The Bin]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rant]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=90</guid>
		<description><![CDATA[Zend PHP5 Certification Study Guide by Davey Shafik annoys me in many ways which include grammatical errors and erroneous coding examples.
Today&#8217;s rant will be on coding examples:
Page 133.
function __autoload($class)
{
//Require PEAR-compatible classes
require_once str_replace(&#34;_&#34;, &#34;/&#34;, $class);
}
$obj = new Some_Class();
At first glance this looks OK but the author goes on to state that the file, Some/Class.php will be [...]]]></description>
			<content:encoded><![CDATA[<p>Zend PHP5 Certification Study Guide by Davey Shafik annoys me in many ways which include grammatical errors and erroneous coding examples.</p>
<p>Today&#8217;s rant will be on coding examples:</p>
<p>Page 133.</p>
<pre class="brush: php;">
function __autoload($class)
{
//Require PEAR-compatible classes
require_once str_replace(&quot;_&quot;, &quot;/&quot;, $class);
}
$obj = new Some_Class();
</pre>
<p>At first glance this looks OK but the author goes on to state that the file, Some/Class.php will be included automagically.  WRONG!  Autoload passes in the name of the class, not the name of the class plus .php at the end (which is what he is thinking).  $class is really Some_Class, so the code above should read:</p>
<pre class="brush: php;">
function __autoload($class)
{
//Require PEAR-compatible classes
require_once str_replace(&quot;_&quot;, &quot;/&quot;, $class) . '.php';
}
$obj = new Some_Class();
</pre>
<p>I&#8217;m annoyed not just because the code is wrong, but because he says &#8220;When instantiating Some_Class, __autoload() is called and passed &#8220;Some_Class.php&#8221; as its argument.&#8221;  If Mr. Shafik took just a couple of minutes to read the <a href="http://us2.php.net/autoload">documentation</a>, he would have realized he was wrong, and I could avoid some frustration this book has (and still is) caused me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/04/18/zend-php5-certification-study-guide-annoyance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP Trickery</title>
		<link>http://www.raymondkolbe.com/2009/03/14/php-trickery/</link>
		<comments>http://www.raymondkolbe.com/2009/03/14/php-trickery/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 18:46:31 +0000</pubDate>
		<dc:creator>Ray</dc:creator>
				<category><![CDATA[Computer Related]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://white-box.us/?p=71</guid>
		<description><![CDATA[While studying for my Zend certification, I came across a practice test question that asks what the primary difference is between a static method and a normal method. I figured this would be an easy question but I was almost tricked with false promises of language structure consistency*!
I was able to narrow my choices down [...]]]></description>
			<content:encoded><![CDATA[<p>While studying for my Zend certification, I came across a practice test question that asks what the primary difference is between a static method and a normal method. I figured this would be an easy question but I was almost tricked with false promises of language structure consistency*!</p>
<p>I was able to narrow my choices down to two answers: 1) static methods can&#8217;t be called from an instance and can only be called using the :: syntax, or 2) $this is not provided by static methods. I decided to play around with PHP a bit to find the answer and it turns out that the correct answer is number 2, which I knew but number 1 was throwing me off.</p>
<p>It turns out that you <em>can</em> call a static method from an instance, why you would want to I&#8217;m not sure.</p>
<p>Here&#8217;s an example:</p>
<pre class="brush: php;">
class A {
    public static function foo() {
        return 'Hello';
    }
    public function bar() {
        return $this-&gt;foo();
    }
}
// normally I would just call:
echo A::foo();
// but this also works:
$instance = new A();
echo $instance-&gt;foo();
// and even this works!
$instance2 = new A();
echo $instance2-&gt;bar();
</pre>
<p>All of the examples above produce <code>Hello</code>.</p>
<p><strong>Update:</strong> I will point out that this functionality <em>is</em> documented under <a href="http://us2.php.net/language.oop5.static">Static Keyword</a> in the PHP manual. Also, yesmarklapointe has a <a href="http://us2.php.net/manual/en/language.oop5.static.php#88394">nice breakdown</a> on what is returned under certain scenarios.</p>
<p>* PHP and Java have a lot of similarities when it comes to language structure but I guess most modern day languages do. I believe Java treats static methods the way you would expect&#8211;the only way to access a static method from outside of a Java class is by using the class name followed by the static method (e.g. A.foo()). To access foo() from within the same class you would just call foo().</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raymondkolbe.com/2009/03/14/php-trickery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
