<?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>Chris Morrell &#187; PHP</title>
	<atom:link href="http://cmorrell.com/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://cmorrell.com</link>
	<description>The personal home page of Chris Morrell</description>
	<lastBuildDate>Thu, 02 Feb 2012 16:34:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>PHP Modeling (in Zend Framework)</title>
		<link>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360</link>
		<comments>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360#comments</comments>
		<pubDate>Thu, 05 Nov 2009 05:52:15 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[modeling]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wishlist]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=360</guid>
		<description><![CDATA[I&#8217;ve been thinking a lot about Modeling in a MVC application, particularly in the Zend Framework. Obviously each application is different, and any Model is going to be fairly unique to your application. That&#8217;s why ZF doesn&#8217;t provide a base &#8230; <a href="http://cmorrell.com/webdev/php-modeling-in-zend-framework-360">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking a lot about Modeling in a MVC application, particularly in the <a href="http://cmorrell.com/category/web-development/zf">Zend Framework</a>.  Obviously each application is different, and any Model is going to be fairly unique to your application.  That&#8217;s why ZF doesn&#8217;t provide a base <code>Model</code> class.  That said, there are some design patterns that a lot of people are using nowadays, and applications could use some base functionality to facilitate those patterns.</p>
<p>Zend Framework&#8217;s project lead, <a href="http://weierophinney.net/matthew/">Matthew Weier O&#8217;Phinney</a>, has a lot of <a href="http://www.slideshare.net/weierophinney/architecting-your-models">great thoughts about Modeling</a> that I&#8217;ve been trying to stick to.  In implementing those ideas, I&#8217;ve started thinking out some base classes to build my Models on top of.  Obviously these classes won&#8217;t work for everyone.  But they should work for a lot of &#8220;typical&#8221; web applications.</p>
<p><span id="more-360"></span></p>
<p>That said, here are some notes that I&#8217;ve been putting together.  I&#8217;m posting them now (very early) in hopes that I get some feedback.</p>
<h3>The 6 Classes</h3>
<h4>Galahad_Model</h4>
<p>This is the base class that all my others extend.  It is there mostly to provide some helper functionality that all my other classes use (mostly for guessing class names based on a naming convention—more on that later).</p>
<h4>Galahad_Model_Entity</h4>
<p>The Entity is the base for all <em>things</em>.  For example, a <code>User</code> would extend the Entity class.  The <code>Galahad_Model_Entity</code> class has some basic methods for getting other objects.  I haven&#8217;t thought this entirely through yet, but an example would be the Entity&#8217;s &#8220;Parent&#8221; Service (see below) or maybe a <code>Form</code> associated with that model or something similar.</p>
<h4>Galahad_Model_Collection</h4>
<p>The Collection class is just a wrapper for an array of Entities.  I like this because it allows for type hinting/etc.  This is pretty much a generic wrapper for an array that implements Iterator and Countable.  I can&#8217;t think of much more that it needs.</p>
<h4>Galahad_Model_Service</h4>
<p>This probably doesn&#8217;t belong as part of the &#8220;Model&#8221;—I need to think that out.  The Service Layer is where your application logic happens that&#8217;s not strictly part of a particular Model (for example, an interaction between two Models).  An example might be authentication.  The service layer will often map pretty closely to a public API (although obviously there will be things that your application can do that shouldn&#8217;t be exposed to the public).</p>
<h4>Galahad_Model_DataMapper</h4>
<p>The <code>DataMapper</code> maps your <code>Entity</code> to the appropriate <code>DAO</code> (see below) and makes sure the <code>DAO</code> gets the data it&#8217;s expecting.  The way I think about this is that the Data Mapper expects an <code>Entity</code> as its input, but passes an array to the DAO.</p>
<h4>Galahad_Model_Dao</h4>
<p>The <em>Data Access Object</em> (DAO) is what takes the actual data in your entity and persists it.  The most common DAO is going to be a database, but a web service could be a DAO as could a filesystem or any other method of persisting data.  The DAO is going to have similar methods as the DataMapper, but it expects <em>just the data</em>—nothing else (that&#8217;s why you need the DataMapper to fetch and process the data in your Entity).  An easy way to show this is in code:</p>
<pre class="brush: php; title: ; notranslate">
class Default_Model_DataMapper_User
  extends Galahad_Model_DataMapper
{
    public function save(User $user)
    {
        $dao = $this-&gt;_getDao();
        $dao-&gt;save(array(
            'name' =&gt; $user-&gt;getName(),
            'email' =&gt; $user-&gt;getEmail(),
            'date_modified' =&gt; time(),
        ));
    }
}
class Default_Model_Dao_DbTable_User
  extends Zend_Db_Table_Abstract
  implements Galahad_Model_Dao_Interface
{
    protected $_name = 'user';

    public function save(Array $data)
    {
        $this-&gt;insert($data);
    }
}
</pre>
<h3>Notes</h3>
<p>I&#8217;m going to reiterate one more time that this is a very early concept and that I&#8217;m looking for feedback.  It could be that I&#8217;m thinking about things completely backwards and it all needs to be thrown away.  At this point I certainly don&#8217;t recommend people running too far with these ideas until they&#8217;ve been discussed/thought out a little more.</p>
<p><strong>About the Galahad_Model base class</strong>—since all the different pieces of your model will likely follow the same naming conventions, the <code>Galahad_Model</code> class provides some helper functionality to guess the name of classes.  For example, inside of  <code>Default_Model_DataMapper_User</code> you&#8217;ll probably need to get an instance of <code>Default_Model_Dao_DbTable_User</code>.  So <code>Galahad_Model_DataMapper</code> provides a nice <code>getDao()</code> method to do this for you.  If you&#8217;ve set the DAO, it uses that, but if you didn&#8217;t, it assumes you want a DbTable, guesses the name for you based on the DataMapper&#8217;s class name (so that if you choose <code>My_Model_DataMapper_Person</code> it&#8217;ll know to return a <code>My_Model_Dao_DbTable_Person</code>) and instantiates it for you.</p>
<h3>Thoughts?</h3>
<p>What do you think?  Does this make any sense?  Or am I trying to make a simple thing more complicated than it needs to be?  I think a lot of this would make more sense in code, so maybe I&#8217;ll try to get what I have started cleaned up a little and attach it to this post.  In the meantime, I&#8217;d love feedback (in the comments below, or to <a href="http://www.twitter.com/inxilpro">@inxilpro</a>.</p>
<div class="su-linkbox" id="post-360-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/php-modeling-in-zend-framework-360&quot;&gt;PHP Modeling (in Zend Framework)&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/php-modeling-in-zend-framework-360/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>E-Mail Address Obfuscator Class</title>
		<link>http://cmorrell.com/webdev/email-address-obfuscator-87</link>
		<comments>http://cmorrell.com/webdev/email-address-obfuscator-87#comments</comments>
		<pubDate>Thu, 02 Oct 2008 21:05:40 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=87</guid>
		<description><![CDATA[A project I&#8217;m working on needs to output text that may have e-mail addresses in it to the Web. Because we don&#8217;t want people&#8217;s e-mail addresses exposed to spammers, I had to write an obfuscation class to make sure those &#8230; <a href="http://cmorrell.com/webdev/email-address-obfuscator-87">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;m working on needs to output text that may have e-mail addresses in it to the Web.  Because we don&#8217;t want people&#8217;s e-mail addresses exposed to spammers, I had to write an obfuscation class to make sure those e-mail addresses are hidden somehow.  I haven&#8217;t decided what method to hide those addresses with yet (I&#8217;m leaning towards <a href="http://mailhide.recaptcha.net/">Mailhide</a>), but I thought I&#8217;d post the base code now.  The class is written so that you can extend it to hide the addresses however you like.  Here&#8217;s the class (PHP 5 only, but would be easy to convert to PHP 4).<br />
<span id="more-87"></span></p>
<pre class="brush: php; title: ; notranslate">
/**
 * Simple Obfuscation Class
 *
 * The beginning of an obfuscation class, made primarily to obfuscate
 * email addresses within a block of text or HTML.  Used in conjunction
 * with reCAPTCHA's Mailhide service  or
 * a database-driven e-mail address hider.
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details .
 *
 * @author     Chris Morrell
 * @copyright  Copyright 2008 Chris Morrell
 * @version    0.1
 * @license    GPL
 *
 */
class Galahad_Obfuscator
{
	const EMAIL_ANCHOR = 101;
	const EMAIL_URL = 102;
	const EMAIL_DISPLAY = 103;

	protected $mailtoRegexp = '/((.*?)&lt;\/a&gt;/is';
	protected $emailRegexp = '/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i';

	/**
	 * Public method to obfuscate all e-mail addresses in a string
	 *
	 * @param string $string
	 * @return string
	 */
	public function emailAddresses($string)
	{
		$string = $this-&gt;replaceMailto($string);
		$string = $this-&gt;replaceEmail($string);
		return $string;
	}

	/**
	 * Private function to replace all e-mail addresses with
	 * obfuscated string (most often links)
	 *
	 * @param string $string
	 * @return string
	 */
	private function replaceEmail($string)
	{
		$string = preg_replace_callback($this-&gt;emailRegexp, array($this, 'processEmail'), $string);
		return $string;
	}

	/**
	 * Private function to handle all found e-mail addresses in string
	 *
	 * @param array $matches
	 * @return string
	 */
	private function processEmail($matches)
	{
		return $this-&gt;obfuscateEmail($matches[0], self::EMAIL_ANCHOR);
	}

	/**
	 * Private function to replace all mailto: anchors with
	 * obfuscated anchors
	 *
	 * @param string $string
	 * @return string
	 */
	private function replaceMailto($string)
	{
		$string = preg_replace_callback($this-&gt;mailtoRegexp, array($this, 'processMailto'), $string);
		return $string;
	}

	/**
	 * Private function to handle all found mailto: anchors
	 *
	 * @param array $matches
	 * @return string
	 */
	private function processMailto($matches)
	{
		$newUrl = $this-&gt;obfuscateEmail($matches[2], self::EMAIL_URL);
		$inner = $matches[4];

		if (preg_match($this-&gt;emailRegexp, $inner)) {
			$inner = $this-&gt;obfuscateEmail($inner, self::EMAIL_DISPLAY);
		}

		return &quot;{$matches[1]}{$newUrl}{$matches[3]}&gt;{$inner}&quot;;
	}

	/**
	 * Subclass this method to obfuscate the address however you see
	 * fit (whether with Mailhide or some other system).  Right now
	 * this function isn't very helpful, as it obfuscates all e-mail
	 * addresses and links them to #
	 *
	 * @param string $email
	 * @param int $type
	 * @return string
	 */
	protected function obfuscateEmail($email, $type = self::EMAIL_ANCHOR)
	{
		$email = substr($email, 0, strpos($email, '@') + 1) . '...';

		if ($type == self::EMAIL_ANCHOR) {
			return &quot;&lt;a href=&quot;\&quot;&gt;{$email}&lt;/a&gt;&quot;;
		} else if ($type == self::EMAIL_URL) {
			return &quot;#&quot;;
		}

		return $email;
	}
}
</pre>
<p>Here&#8217;s some sample usage:</p>
<pre class="brush: php; title: ; notranslate">
class My_Obfuscator extends Galahad_Obfuscator
{
	protected function obfuscateEmail($email, $type = self::EMAIL_ANCHOR)
	{
		$id = $this-&gt;emailToId($email);
		$email = substr($email, 0, strpos($email, '@') + 1) . '...';

		if ($type == self::EMAIL_ANCHOR) {
			return &quot;&lt;a href=&quot;\&quot;&gt;{$email}&lt;/a&gt;&quot;;
		} else if ($type == self::EMAIL_URL) {
			return &quot;http://yoursite.com/get-email.php?id={$id}&quot;;
		}

		return $email;
	}

	private function emailToId($email)
	{
		// Implement this by adding the email to a database
		// and returning the row's ID, for example
		return rand(1,500);
	}
}

$html = 'some string with e-mail addresses in it.';
$obfuscator = new My_Obfuscator();
echo $obfuscator-&gt;emailAddresses($html);
</pre>
<p>So far the class has worked well with limited testing.  Obviously it handles both e-mail addresses in plain text and mailto: links.  Please let me know if you find any bugs in it, or have a suggestion about how to make it better.</p>
<div class="su-linkbox" id="post-87-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/webdev/email-address-obfuscator-87&quot;&gt;E-Mail Address Obfuscator Class&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/webdev/email-address-obfuscator-87/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP CSS Sprite Generator</title>
		<link>http://cmorrell.com/misc/php-css-sprite-generator-66</link>
		<comments>http://cmorrell.com/misc/php-css-sprite-generator-66#comments</comments>
		<pubDate>Fri, 22 Aug 2008 16:17:47 +0000</pubDate>
		<dc:creator>Chris M.</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS Sprites]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://cmorrell.com/?p=66</guid>
		<description><![CDATA[A couple of days ago Saul Rosenbaum asked for a little help with a PHP utility he was writing.  I took a crack at it, and we ended up with a nice little class that generates CSS sprites from pairs &#8230; <a href="http://cmorrell.com/misc/php-css-sprite-generator-66">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago <a href="http://visualchutzpah.com" target="_blank">Saul Rosenbaum</a> asked for a little help with a PHP utility he was writing.  I took a crack at it, and we ended up with a nice little class that generates CSS sprites from pairs of images. Saul wrote a great little README for it, but the general gist is that it takes a00.gif and a00_over.gif and creates a new a00.gif that has both images vertically stacked within it (it can do this with large batches of images).</p>
<p>We submitted the files to <a href="http://labs.indyhall.org/open-source/" target="_blank">IndyHall Labs</a> if anyone is interested in using them.  If I have time I&#8217;ll be adding some new functionality (Saul added a wishlist in the README file, and I&#8217;d definitely love to tackle some of those issues).</p>
<p>You can download the files from GitHub: <a href="https://github.com/IndyHallLabs/css-sprite-generator/" target="_blank">https://github.com/IndyHallLabs/css-sprite-generator/</a></p>
<div class="su-linkbox" id="post-66-linkbox"><div class="su-linkbox-label">Link to this post!</div><div class="su-linkbox-field"><input type="text" value="&lt;a href=&quot;http://cmorrell.com/misc/php-css-sprite-generator-66&quot;&gt;PHP CSS Sprite Generator&lt;/a&gt;" onclick="javascript:this.select()" readonly="readonly" style="width: 100%;" /></div></div>]]></content:encoded>
			<wfw:commentRss>http://cmorrell.com/misc/php-css-sprite-generator-66/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/44 queries in 1.608 seconds using disk: basic
Object Caching 588/686 objects using disk: basic
Content Delivery Network via cdn1.cmorrell.com

Served from: cmorrell.com @ 2012-02-05 05:46:08 -->
