<?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>Brit Gardner &#187; cakephp</title>
	<atom:link href="http://britg.com/tags/cakephp/feed/" rel="self" type="application/rss+xml" />
	<link>http://britg.com</link>
	<description>The big yellow one&#039;s the sun.</description>
	<lastBuildDate>Fri, 03 Feb 2012 05:08:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Love the new CakePHP API browser!</title>
		<link>http://britg.com/2009/01/30/love-the-new-cakephp-api-browser/</link>
		<comments>http://britg.com/2009/01/30/love-the-new-cakephp-api-browser/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 15:09:18 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://britg.com/?p=765</guid>
		<description><![CDATA[I&#8217;ll let the app itself do the talking, but just let me say that I love what the Cake team has done with the new API browser. The best part is the API generator is released as a plugin so we can all enjoy sexy APIs with our cake apps!]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll let the <a href="http://api.cakephp.org">app itself</a> do the talking, but just let me say that I love what the Cake team has done with the new API browser.  The best part is the <a href="http://thechaw.com/api_generator">API generator</a> is released as a plugin so we can all enjoy sexy APIs with our cake apps!</p>
<p><a href="http://api.cakephp.org"><img class="aligncenter size-full wp-image-766" title="cakeapi" src="http://britg.com/wordpress/wp-content/uploads/2009/01/cakeapi.png" alt="cakeapi" width="600" height="430" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2009/01/30/love-the-new-cakephp-api-browser/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Three Cheers for CakePHP Backwards Compatibility</title>
		<link>http://britg.com/2009/01/27/three-cheers-for-cakephp-backwards-compatibility/</link>
		<comments>http://britg.com/2009/01/27/three-cheers-for-cakephp-backwards-compatibility/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 14:22:50 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://britg.com/?p=746</guid>
		<description><![CDATA[I would make a horrible framework developer.  Why?  Because I don&#8217;t have the patience to put the effort into making my code backwards compatible (unless I really, really have to).  Thankfully, the developers of CakePHP are not like me. I just had cause to take an old client site that was built on CakePHP 1.0.x [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-752" href="http://britg.com/2009/01/27/three-cheers-for-cakephp-backwards-compatibility/cake-logo/"><img class="alignright size-full wp-image-752" title="cake-logo" src="http://britg.com/wordpress/wp-content/uploads/2009/01/cake-logo.png" alt="cake-logo" width="180" height="180" /></a>I would make a horrible framework developer.  Why?  Because I don&#8217;t have the patience to put the effort into making my code backwards compatible (unless I really, really have to).  Thankfully, the developers of <a href="http://cakephp.org">CakePHP</a> are not like me.</p>
<p>I just had cause to take an old client site that was built on CakePHP 1.0.x and move it over to a new platform with some upgrades in functionality.  Since we are most likely going to be developing a bunch of new features on the site I felt it was important to go ahead and upgrade the cake core libraries to the <a href="http://bakery.cakephp.org/articles/view/the-gift-of-1-2-final">recently-released 1.2</a> &#8212; a task I was dreading from the moment I thought it.</p>
<p>But, surprise surprise, the whole ordeal wasn&#8217;t an ordeal at all.  In fact was incredibly easy because the Cake devs made it a point to include backwards compatibility.  As a result a lot of my legacy code could remain in place to be upgraded gradually.</p>
<p>Take for instance the following gem.  I was a rough and tumble Cake developer back when I first wrote this and this format was actually never really acceptable in the first place, but it worked in 1.0.x:</p>
<pre lang="php">
$this->Order_frame-&gt;findAll();
// correct way to access the order_frames table: $this-&gt;OrderFrame-&gt;findAll();

// in view
echo $orderFrames['Order_frame']['type'];
// correct way to access the data: $orderFrames['OrderFrame']['type'];
</pre>
<p>Now, having used Cake for a couple of years I know the error of my ways.  But, to my surprise, when I ran this legacy code locally on a fresh 1.2 core it worked.  Huh?  There was no way they would still support this ancient syntax!  Heck, I dont think they ever supported it, really.</p>
<p>Anyways, this is a long way of showing my appreciation to the CakePHP devs for building the framework with all the legacy code out there in mind.</p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2009/01/27/three-cheers-for-cakephp-backwards-compatibility/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>GeoCouch in CakePHP</title>
		<link>http://britg.com/2008/08/26/geocouch-in-cakephp/</link>
		<comments>http://britg.com/2008/08/26/geocouch-in-cakephp/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 18:44:46 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[couchdb]]></category>

		<guid isPermaLink="false">http://britg.com/?p=403</guid>
		<description><![CDATA[I released a small php script for easily handling geodata in couchdb via php a while ago, check it out here.  I also put together a short tutorial on how to integrate this script in your CakePHP application.  The article is available here on the CakePHP Bakery.]]></description>
			<content:encoded><![CDATA[<p>I released a small php script for easily handling geodata in couchdb via php a while ago, <a href="http://britg.com/2008/08/15/using-couchdb-for-storing-google-geocoded-json-data/">check it out here</a>.  I also put together a short tutorial on how to integrate this script in your CakePHP application.  The article is available <a href="http://bakery.cakephp.org/articles/view/geocouch-plugin-storing-geocoded-data-in-couchdb">here on the CakePHP Bakery</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2008/08/26/geocouch-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating CakePHP with bbPress &#8211; Part 2</title>
		<link>http://britg.com/2008/08/25/integrating-cakephp-with-bbpress-part-2/</link>
		<comments>http://britg.com/2008/08/25/integrating-cakephp-with-bbpress-part-2/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 12:50:33 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[bbpress]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://britg.com/?p=392</guid>
		<description><![CDATA[This is the second of a 3 part tutorial on how to integrate bbPress with CakePHP 1.2.x. When complete, these 3 tutorials will accomplish: Integrating bbPress in a sub-folder (not a subdomain) of your cake install (part 1 here) Integrating user registration &#8211; when a user registers through your cake application they are automatically registered [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the second of a 3 part tutorial on how to integrate bbPress with CakePHP 1.2.x.  When complete, these 3 tutorials will accomplish:</em></p>
<ol>
<li><em>Integrating bbPress in a sub-folder (not a subdomain) of your cake install (<a href="http://britg.com/2008/08/23/integrating-cakephp-with-bbpress-part-1/">part 1 here</a>)<br />
</em></li>
<li><em>Integrating user registration &#8211; when a user registers through your cake application they are automatically registered in bbPress.</em></li>
<li><em>Integrating the login &#8211; when a user is logged in via the cake application they are automatically logged in in bbPress.</em></li>
</ol>
<h3>Part 2 &#8211; Integrating User Registration</h3>
<p>This part is a little more tricky, but not unmanageable.   The challenge here is that your Cake application probably uses the Auth component, or a custom user setup.  So you probably have a prebuilt users table and chances are it does not conform to what bbPress is looking for in it&#8217;s users table.  Also, the encryption scheme between the two is probably different.</p>
<p>With that in mind, I&#8217;ve made the following design decisions</p>
<ol>
<li>My Cake users schema will remain intact <em>AND</em> the bbPress users schema will remain intact.</li>
<li>Users must register through my Cake application only</li>
<li>CakePHP is using the built-in Auth component.</li>
<li>When a user registers through my Cake application &#8211; I run the necessary logic from the Cake <code>User</code> model to update the bbPress users table.</li>
<li>The bbPress tables are in the same database as my CakePHP tables</li>
<li>I change the encryption scheme of bbPress to conform to my Cake app.</li>
</ol>
<h4>Step 1: changing the bbPress password encryption.</h4>
<p>If you&#8217;ve followed <a href="http://britg.com/2008/08/23/integrating-cakephp-with-bbpress-part-1/">Part 1</a> of this tutorial, you&#8217;ve successfully installed and ran bbPress in a subfolder of your cakephp install.  Navigate to that subfolder, then open following file: <code>bb-includes/backpress/code.wp-pass.php</code></p>
<p>Notice two functions, <code>hash_password(...)</code> and <code>check_password(...)</code>.  We will overwrite these two functions to match the hashing that takes place in our CakePHP install.  If, as I denoted above, you are using the built-in CakePHP Auth component, this is very simple &#8211; just comment out the existing functions and replace them with the following:</p>
<pre lang="php">	function hash_password($string) {
		$string = 'YOUR CONFIGURE::SALT VALUE'.$string;
		return sha1($string);
	}

	function check_password($password, $hash, $user_id = '') {
		$string = 'YOUR CONFIGURE::SALT VALUE'.$password;
		if(sha1($string) != $hash) {
			return false;
		} else {
			return true;
		}
	}</pre>
<p>Replace the <code>YOUR CONFIGURE::SALT VALUE</code> with the appropriate value from your CakePHP application.  This can be found in <code>app/config/core.php</code>.</p>
<p>With these two functions in place, your bbPress user system should be hashing and checking the passwords the same way.</p>
<h4>Step 2: Saving a bbPress user from the CakePHP install.</h4>
<p>Fortunately, CakePHP provides an easy hook into the ORM saving process with the <code>afterSave()</code> model callback.</p>
<p>To get your User model to save a new bbPress user when a new Cake user is created, add the following functions to your User model script:</p>
<pre lang="php">	function afterSave($created)
	{
		if($created)
		{
			$sql = "INSERT INTO `bb_users`
			(`user_login`, `user_pass`, `user_nicename`,
			`user_email`, `user_url`, `user_registered`,
			`user_status`, `display_name`)
			VALUES(
			'".$this-&gt;data['User']['username']."',
			'".$this-&gt;data['User']['password']."',
			'".$this-&gt;data['User']['username']."',
			'".$this-&gt;data['User']['email']."',
			'',
			NOW(),
			0, '".$user['User']['username']."')";
			$this-&gt;query($sql);
		}
	}</pre>
<p>Notice that we are just creating an SQL statement with all the necessary fields required to successfully insert the user into the bbPress system, and then executing that SQL.  Also, if you are using the default functionality of the Auth component, <code>$this->data['User']['password'];</code> should automatically be hashed with the same scheme as Step 1.</p>
<h4>Step 3 &#8211; Preventing registration from bbPress</h4>
<p>This is the easy part.  Simply add the following line to the top of your <code>register.php</code> script in you bbPress install and replace the path with the correct path to your cake registration page.</p>
<pre lang="php">die(header('Location: /path/to/your/cake/registration/page'));</pre>
<p>So, that&#8217;s it!  Now, when you register a user through your Cake application, they should also appear in the bbPress users table, and you should be able to successfully log into both with the exact same credentials.</p>
<p>But, the plot thickens &#8211; we don&#8217;t want our users to have to log in to both the cake app and bbpress.  We want them to be logged into both automatigically.  Stay tuned for part 3 of this tutorial and I&#8217;ll attempt to tackle this very conundrum. </p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2008/08/25/integrating-cakephp-with-bbpress-part-2/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Integrating CakePHP with bbPress &#8211; Part 1</title>
		<link>http://britg.com/2008/08/23/integrating-cakephp-with-bbpress-part-1/</link>
		<comments>http://britg.com/2008/08/23/integrating-cakephp-with-bbpress-part-1/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 22:13:57 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[bbpress]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://britg.com/?p=384</guid>
		<description><![CDATA[I&#8217;ve been working on StatForge.com for the past few days and one of the community features I want to integrate is a forum.  Rather than go for something bloated like phpbb or vanilla, I decided to go with bbPress from the makers of WordPress. This is the first of a 3 part tutorial on how [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on <a href="http://statforge.com">StatForge.com</a> for the past few days and one of the community features I want to integrate is a forum.  Rather than go for something bloated like phpbb or vanilla, I decided to go with <a href="http://bbpress.org">bbPress</a> from the makers of <a href="http://wordpress.org">WordPress</a>.</p>
<p>This is the first of a 3 part tutorial on how to integrate bbPress with CakePHP 1.2.x.  When complete, these 3 tutorials will accomplish:</p>
<ol>
<li>Integrating bbPress in a sub-folder (not a subdomain) of your cake install</li>
<li>Integrating user registration &#8211; when a user registers through your cake application they are automatically registered in bbPress. (UPDATE: <a href="http://britg.com/2008/08/25/integrating-cakephp-with-bbpress-part-2/">part 2 here</a>)</li>
<li>Integrating the login &#8211; when a user is logged in via the cake application they are automatically logged in in bbPress.</li>
</ol>
<h3>Part 1 &#8211; Integrating bbPress in a sub-folder (not a subdomain)</h3>
<p>It may be personal preference, but I&#8217;m not a big fan of subdomaining parts of an application.  There are definitely legitamite technical reasons to do so, but when I can get away with it, I try to use subfolders, i.e. <code><a href="http://statforge.com" rel="nofollow">http://statforge.com</a></code> and <code><a href="http://statforge.com/forum/" rel="nofollow">http://statforge.com/forum/</a></code>.</p>
<p>There&#8217;s a small hurdle here since CakePHP wants to ReWrite all your paths (if you&#8217;ve installed it in your domain root), but it&#8217;s easy to overcome.  Find the <code>.htaccess</code> file in the root of your cake install.  It should look like this:</p>
<pre lang="bash">   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]</pre>
<p>This is rewriting all of your requests to the webroot folder.  Assuming you want to install bbPress into a subfolder called <code>forum</code> (i.e. <code><a href="http://statforge.com/forum/" rel="nofollow">http://statforge.com/forum/</a></code>) the change this <code>.htaccess</code> file to the following:</p>
<pre lang="bash">   RewriteEngine on

   RewriteCond %{REQUEST_URI} ^/forum/(.*)$
   RewriteRule ^.*$ - [L]

   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]</pre>
<p>This simply reads &#8211; if the Request starts with <code>/forum/</code> pass it through normally.  If not, let Cake handle it.  The only limitation here is that you cannot have a controller named &#8216;forum&#8217; in your cake application.</p>
<p>That&#8217;s it &#8211; you should be able to drop a fresh bbPress install into the /forum subfolder and access it normally without Cake interfering.</p>
<p>I&#8217;ve already integrated the user registration between my CakePHP install and my bbPress install, but I&#8217;ve gotta run for the time being.  Hopefully tomorrow I&#8217;ll throw up part 2 &#8211; it&#8217;s a bit more complicated. (UPDATE: <a href="http://britg.com/2008/08/25/integrating-cakephp-with-bbpress-part-2/">part 2 here</a>)</p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2008/08/23/integrating-cakephp-with-bbpress-part-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Code Drive-By: Edit Anywhere Component for CakePHP</title>
		<link>http://britg.com/2008/08/08/code-drive-by-edit-anywhere-component/</link>
		<comments>http://britg.com/2008/08/08/code-drive-by-edit-anywhere-component/#comments</comments>
		<pubDate>Fri, 08 Aug 2008 14:49:46 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[edit anywhere]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[thickbox]]></category>

		<guid isPermaLink="false">http://britg.com/?p=304</guid>
		<description><![CDATA[I call this a code drive-by because I&#8217;m just going to dump the code without much explanation.  When I have time I&#8217;ll come back and walk through it and turn it into a useful article on the CakePHP bakery. This component allows you to manage content (primarily text blocks) on a site if you&#8217;re logged [...]]]></description>
			<content:encoded><![CDATA[<p>I call this a code drive-by because I&#8217;m just going to dump the code without much explanation.  When I have time I&#8217;ll come back and walk through it and turn it into a useful article on the <a href="http://bakery.cakephp.org">CakePHP bakery</a>.</p>
<p>This component allows you to manage content (primarily text blocks) on a site if you&#8217;re logged in.  The editor pops up in a <a href="http://jquery.com/demo/thickbox/">thickbox</a>.</p>
<p>Some requirements off the top of my head:</p>
<ul>
<li>CakePHP, duh.</li>
<li>jquery</li>
<li>thickbox</li>
<li>Auth Component</li>
</ul>
<p>Again, sorry for the drive-by but hopefully someone will get use out of this.</p>
<pre lang="php">
<?php

	class ContentComponent extends Object
	{
		var $controller;
		var $Setting;

		function initialize(&#038;$controller)
		{
			$this->controller =&#038; $controller;
			App::import('Model', 'Setting');
			$this->Setting = new Setting();
		}

		function read($field = null) {
			return $this->render($field);
		}

		function render($field = null)
		{
			$content = $this->Setting->findByField($field);

			if(!empty($content)) {
				return $this->output($field, $content['Setting']['value']);
			} else {
				return $this->output($field, '');
			}
		}

		function output($field, $str)
		{
			$output = $str;
			if($this->controller->u['User']['role'] == 'admin') {
				$output .= $this->editButton($field);
			}
			return nl2br($output);
		}

		function editButton($field) {
			return '<a href="/settings/edit/'.$field.'/?r='.$_SERVER['REQUEST_URI'].'" class="thickbox edit-button"><img src="/img/edit.png" width="10" height="10" /></a>';
		}
	}
?>
</pre>
<p>And my Settings Controller looks like:</p>
<pre lang="php">
<?php

	class SettingsController extends AppController
	{
		var $name = 'Settings';

		function edit($field)
		{
			$content = $this->Setting->findByField($field);

			if(!empty($content)) {
				$this->Setting->id = $content['Setting']['id'];
			}

			if(!empty($this->data))
			{
				$content['Setting'] = array(
					'field' => $field,
					'value' => $this->data['Setting']['value'],
				);

				$this->Setting->save($content);
				die($this->redirect($_REQUEST['r']));
			}

			$this->set(compact('field', 'content'));
		}
	}
?>
</pre>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2008/08/08/code-drive-by-edit-anywhere-component/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using the Zend Framework in CakePHP</title>
		<link>http://britg.com/2008/07/07/using-the-zend-framework-in-cakephp/</link>
		<comments>http://britg.com/2008/07/07/using-the-zend-framework-in-cakephp/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 22:58:35 +0000</pubDate>
		<dc:creator>britg</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[google data api]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://britg.com/?p=247</guid>
		<description><![CDATA[What do you get when you combine the powers of CakePHP 1.2.x and the Zend Framework? No, not Captain Planet&#8230; something much more powerful &#8211; the ability to use the Google Data API PHP library! This is useful if you want to use Google Calendar or any of the other services supported by the data [...]]]></description>
			<content:encoded><![CDATA[<p>What do you get when you combine the powers of CakePHP 1.2.x and the <a href="http://framework.zend.com/">Zend Framework</a>?</p>
<p><a href="http://britg.com/wp-content/uploads/2008/07/captain-planet-tom-cruise-ted-turner.jpg"><img class="alignleft size-thumbnail wp-image-248" title="captain-planet-tom-cruise-ted-turner" src="http://britg.com/wp-content/uploads/2008/07/captain-planet-tom-cruise-ted-turner-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>No, not Captain Planet&#8230; something much more powerful &#8211; the ability to use the <a href="http://code.google.com/apis/gdata/">Google Data API</a> <a href="http://code.google.com/support/bin/answer.py?answer=76585">PHP library</a>!  This is useful if you want to use Google Calendar or any of the other services supported by the data API.</p>
<p>Loading the Zend Framework isn&#8217;t as straightforward as App::Import(&#8230;), since Zend&#8217;s libraries assume that the Zend Framework folder is in your include path.  To get around this simply:</p>
<ol>
<li>Drop the Zend Framework Library folder into your vendors folder</li>
<li>Create a script in your Vendors folder called something like <code>zend_include_path.php</code> with the following statement:
<pre lang="php">
ini_set('include_path', ini_get('include_path').dirname(__FILE__));
</pre>
</li>
<li>In your action, just do the following, replacing Gdata.php with whatever library you wish to load (i.e. Loader.php):
<pre lang="php">function myAction() {
     App::import('Vendor', 'zend_include_path');
     App::import('Vendor', 'Zend_Gdata', true, false, 'Zend/Gdata.php');

     ...
}
</pre>
</li>
</ol>
<p>Voila!  You should now be able to instantiate your loaded Zend Library Class and work with it normally.</p>]]></content:encoded>
			<wfw:commentRss>http://britg.com/2008/07/07/using-the-zend-framework-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

