<?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>cakebaker &#187; cakephp</title>
	<atom:link href="http://cakebaker.42dh.com/tags/cakephp/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Mon, 19 Jul 2010 14:23:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Bugfix release for the OpenID component &amp; an example application</title>
		<link>http://cakebaker.42dh.com/2010/07/19/bugfix-release-for-the-openid-component-an-example-application/</link>
		<comments>http://cakebaker.42dh.com/2010/07/19/bugfix-release-for-the-openid-component-an-example-application/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 14:23:38 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1435</guid>
		<description><![CDATA[Last week I received a mail from a user of the OpenID component in which he described that it wasn&#8217;t possible to login with OpenIDs from claimID and Blogger. After some debugging I found the reason for this problem: a bug in the isOpenIDResponse() method. The method only recognized responses from providers using OpenID 2.0, [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I received a mail from a user of the <a href="http://code.42dh.com/openid/">OpenID component</a> in which he described that it wasn&#8217;t possible to login with OpenIDs from <a href="http://claimid.com/">claimID</a> and <a href="http://blogger.com">Blogger</a>. After some debugging I found the reason for this problem: a bug in the isOpenIDResponse() method. The method only recognized responses from providers using OpenID 2.0, but not from providers still using the older OpenID 1.x&#8230; So, if you are using this method in your code, please <a href="http://github.com/cakebaker/openid-component/downloads">upgrade</a> to the latest version (v2010-07-17).</p>
<p>I also got asked whether there is an example application that shows the usage of the OpenID component. As I already use a very simple application to test the component manually, I pushed this application to <a href="http://github.com/cakebaker/openid-component-example">GitHub</a> (you can see the application in action on <a href="http://openid-example.42dh.com/">http://openid-example.42dh.com/</a>). I hope this will make it easier for some of you to get started with the OpenID component.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/07/19/bugfix-release-for-the-openid-component-an-example-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenID component v2010-05-19 released</title>
		<link>http://cakebaker.42dh.com/2010/05/19/openid-component-v2010-05-19-released/</link>
		<comments>http://cakebaker.42dh.com/2010/05/19/openid-component-v2010-05-19-released/#comments</comments>
		<pubDate>Wed, 19 May 2010 07:51:25 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1412</guid>
		<description><![CDATA[As mentioned in the title, I released a new version of the OpenID component today. It&#8217;s a maintenance release: the only change is an update of the bundled PHP OpenID library from version 2.1.2 to 2.2.2. With this change you no longer have to patch the OpenID library if you are working with PHP 5.3. [...]]]></description>
			<content:encoded><![CDATA[<p>As mentioned in the title, I released a new version of the OpenID component today. It&#8217;s a maintenance release: the only change is an update of the bundled <a href="http://github.com/openid/php-openid/">PHP OpenID library</a> from version 2.1.2 to 2.2.2. With this change you no longer have to patch the OpenID library if you are working with PHP 5.3.</p>
<p>To update, simply replace the OpenID component and the content of the &#8220;vendors/Auth&#8221; folder (and its subfolders) with the files from the zip archive.</p>
<p>You can <a href="http://github.com/cakebaker/openid-component/downloads">download</a> the new version from Github.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/05/19/openid-component-v2010-05-19-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Support for Google Apps OpenIDs</title>
		<link>http://cakebaker.42dh.com/2010/04/13/support-for-google-apps-openids/</link>
		<comments>http://cakebaker.42dh.com/2010/04/13/support-for-google-apps-openids/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 15:13:06 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1356</guid>
		<description><![CDATA[In a recent comment John mentioned that the OpenID component doesn&#8217;t work with Google Apps OpenIDs. And he was right. The reason it didn&#8217;t work is that Google introduced it&#8217;s own OpenID discovery protocol as they faced challenges not addressed by the current version (2.0) of the OpenID standard. And this means such OpenIDs are [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://cakebaker.42dh.com/2008/02/06/new-version-of-the-openid-component/#comment-156388">recent comment</a> John mentioned that the <a href="http://code.42dh.com/openid">OpenID component</a> doesn&#8217;t work with <a href="http://www.google.com/apps/">Google Apps</a> OpenIDs. And he was right.</p>
<p>The reason it didn&#8217;t work is that Google introduced it&#8217;s own <a href="http://groups.google.com/group/google-federated-login-api/web/openid-discovery-for-hosted-domains">OpenID discovery protocol</a> as they faced challenges not addressed by the current version (2.0) of the OpenID standard. And this means such OpenIDs are not recognized by current OpenID libraries. For this reason, Google provides with <a href="http://code.google.com/p/php-openid-apps-discovery/">php-openid-apps-discovery</a> an add-on to the <a href="http://openidenabled.com/php-openid/">PHP OpenID</a> library.</p>
<p>I integrated this add-on into the OpenID component as an optional feature. You have to enable it with:</p>
<pre>
<code>public $components = array('Openid' =&gt; array('accept_google_apps' =&gt; true));</code>
</pre>
<p>I made it an optional feature because it introduces an additional step to the authentication process: the provided OpenID url is sent to Google to figure out whether it is a Google Apps OpenID. And this makes the authentication process a bit slower. Hence I think you should have a choice whether you want to use this feature.</p>
<p>The new version of the <a href="http://code.42dh.com/openid">OpenID component</a> doesn&#8217;t contain any other new features/bugfixes. </p>
<p>You can download the component from <a href="http://github.com/cakebaker/openid-component/downloads">Github</a>.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/04/13/support-for-google-apps-openids/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Attribute Exchange support for the OpenID component</title>
		<link>http://cakebaker.42dh.com/2009/12/12/attribute-exchange-support-for-the-openid-component/</link>
		<comments>http://cakebaker.42dh.com/2009/12/12/attribute-exchange-support-for-the-openid-component/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 17:30:11 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1314</guid>
		<description><![CDATA[The OpenID Attribute Exchange specification (or AX for short) has been around for quite a while, though I ignored it so far because at the time it was introduced (almost) no OpenID provider supported it. However, after Yahoo! announced they support Attribute Exchange, and someone recently mentioned it in a mail, it was time for [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://openid.net/specs/openid-attribute-exchange-1_0.html">OpenID Attribute Exchange specification</a> (or AX for short) has been around for quite a while, though I ignored it so far because at the time it was introduced (almost) no OpenID provider supported it. However, after Yahoo! <a href="http://developer.yahoo.net/blog/archives/2009/12/yahoo_openid_now_with_attribute_exchange.html">announced</a> they support Attribute Exchange, and someone recently mentioned it in a mail, it was time for me to have a look at it.</p>
<p>AX is in principle the &#8220;big brother&#8221; of the <a href="http://openid.net/specs/openid-simple-registration-extension-1_0.html">Simple Registration Extension</a> (or SReg for short). Whereas SReg only allows you to retrieve nine commonly requested pieces of information, AX allows you to retrieve any identity information. And theoretically it also allows you to store/update your identity information at your OpenID provider. But it seems like no OpenID provider supports this feature&#8230;</p>
<p>Let&#8217;s have a look at an example.</p>
<p>First the login method:</p>
<pre>
<code>// app/controllers/users_controller.php
class UsersController extends AppController {
    public $components = array('Openid', 'RequestHandler');

    public function login() {
        $realm = 'http://'.$_SERVER['SERVER_NAME'];
        $returnTo = $realm . '/users/login';

        if ($this-&gt;RequestHandler-&gt;isPost()) {
            $this-&gt;makeOpenIDRequest($this-&gt;data['User']['openid_identifier'], $returnTo, $realm);
        } elseif ($this-&gt;Openid-&gt;isOpenIDResponse()) {
            $this-&gt;handleOpenIDResponse($returnTo);
        }
    }
}</code>
</pre>
<p>The next step is to implement the makeOpenIDRequest() method. For each attribute we want to retrieve, we have to create an Auth_OpenID_AX_AttrInfo object with the respective attribute type. A list of possible types is available on <a href="http://www.axschema.org/types/">http://www.axschema.org/types/</a>. Though there are many types defined, OpenID providers usually only support a small subset of those types.</p>
<p>The &#8220;1&#8243; we pass to the make() method specifies the number of values we want for this type. In this example it doesn&#8217;t make much sense to specify a value other than &#8220;1&#8243;, but for other types it is theoretically possible to have multiple values (for example you could have defined multiple email addresses). It is an optional parameter and by default it is &#8220;1&#8243;.</p>
<p>The last parameter specifies whether the value of the attribute is required for our application. This is simply a hint for the OpenID provider so it could display this attribute differently, but it doesn&#8217;t guarantee a value is returned. By default this parameter is &#8220;false&#8221;. </p>
<p>(Update 2010-04-19: Google requires that you set the fourth parameter of the make() method: a string with an alias for the attribute.)</p>
<pre>
<code>private function makeOpenIDRequest($openid, $returnTo, $realm) {
    $attributes[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson', 1, true);
    $this-&gt;Openid-&gt;authenticate($openid, $returnTo, $realm, array('ax' =&gt; $attributes));
}</code>
</pre>
<p>Finally, we have to implement the handleOpenIDResponse() method. As we expect only one value for the attribute we specified, we can use either get() or getSingle() to retrieve its value. getSingle() returns the value whereas get() returns an array. </p>
<pre>
<code>private function handleOpenIDResponse($returnTo) {
    $response = $this-&gt;Openid-&gt;getResponse($returnTo);

    if ($response-&gt;status == Auth_OpenID_SUCCESS) {
        $axResponse = Auth_OpenID_AX_FetchResponse::fromSuccessResponse($response);

        if ($axResponse) {
            debug($axResponse-&gt;get('http://axschema.org/namePerson'));
            debug($axResponse-&gt;getSingle('http://axschema.org/namePerson'));
        }
    }
}</code>
</pre>
<p>That&#8217;s it. </p>
<p>You can get the new version of the OpenID component from <a href="http://github.com/cakebaker/openid-component">GitHub</a>. If you use SReg in your code and you want to update to this version, please make sure to adapt your code in the following way:</p>
<pre>
<code>// old
$this-&gt;Openid-&gt;authenticate($openid, $returnTo, $realm, array('email'), array('nickname'));

// new
$this-&gt;Openid-&gt;authenticate($openid, $returnTo, $realm, array('sreg_required' =&gt; array('email'), 'sreg_optional' =&gt; array('nickname')));</code>
</pre>
<p>Feedback is welcome :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/12/12/attribute-exchange-support-for-the-openid-component/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The end of CakePHP?</title>
		<link>http://cakebaker.42dh.com/2009/10/23/the-end-of-cakephp/</link>
		<comments>http://cakebaker.42dh.com/2009/10/23/the-end-of-cakephp/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 14:49:33 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1279</guid>
		<description><![CDATA[Today, Nate Abele, lead developer of CakePHP, announced in a cryptic tweet that he leaves the project. This comes shortly after Gwoo, the project manager, left the project, too. It seems like they started to work on a fork of Cake3 called &#8220;Lithium&#8221;. On Twitter people are a bit puzzled about those events, some even [...]]]></description>
			<content:encoded><![CDATA[<p>Today, Nate Abele, lead developer of CakePHP, announced in a cryptic <a href="http://twitter.com/nateabele/status/5087443139">tweet</a> that he leaves the project. This comes shortly after Gwoo, the project manager, left the project, too. It seems like they started to work on a fork of Cake3 called <a href="http://irc.cakephp.org/logs/link/1110092#message1110102">&#8220;Lithium&#8221;</a>. On Twitter people are a bit puzzled about those events, some even think it is the end of CakePHP&#8230;</p>
<p>I don&#8217;t know whether this will be the case, it is too early to say. But I doubt it. The project is still backed by the <a href="http://cakedc.com">Cake Development Company</a>, which employs some of the core <a href="http://code.cakephp.org/wiki/about/contributors">contributors</a> (Larry Masters aka PhpNut, Mark Story). That&#8217;s some guarantee that the show will go on. And of course there is a large community. </p>
<p>On the other hand I don&#8217;t know how many of the other contributors will remain. And the lack of (official) communication is also not that good for the confidence into the project. What happened? What will be the next steps? Who will take over those vacant roles? See also Matt Curry&#8217;s <a href="http://www.pseudocoder.com/archives/2009/10/23/cakephp-digest-21-–-whose-left/">post</a> on this matter.</p>
<p>Anyway, probably the best thing to do now is to drink tea and to wait until the dust settles&#8230;</p>
<p>Update (2009-10-23): an <a href="http://bakery.cakephp.org/articles/view/the-cake-is-still-rising">official statement</a> has been published in the meantime.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/10/23/the-end-of-cakephp/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Extending CakePHP&#8217;s core components</title>
		<link>http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/</link>
		<comments>http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 06:12:52 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1248</guid>
		<description><![CDATA[In a recent comment David Cournoyer shared a tip about extending CakePHP&#8217;s core components and I think it could also be useful for others. Let&#8217;s say we want to add a method to the request handler component. And so we create a new class which inherits from the request handler component: // app/controllers/components/my_request_handler.php App::import('Component', 'RequestHandler'); [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://cakebaker.42dh.com/2008/11/07/an-idea-for-hacking-core-helpers/#comment-135701">recent comment</a> <a href="http://www.quatral.com/">David Cournoyer</a> shared a tip about extending CakePHP&#8217;s core components and I think it could also be useful for others. </p>
<p>Let&#8217;s say we want to add a method to the request handler component. And so we create a new class which inherits from the request handler component:</p>
<pre>
<code>// app/controllers/components/my_request_handler.php
App::import('Component', 'RequestHandler');
class MyRequestHandlerComponent extends RequestHandlerComponent {
    public function example() {
        // do something
    }
}</code>
</pre>
<p>To use this component, we have to add it to the $components array of our controller:</p>
<pre>
<code>// app/app_controller.php
class AppController extends Controller {
    public $components = array('MyRequestHandler');	
}</code>
</pre>
<p>Nothing new so far. However, a disadvantage of this approach is that you have to use the component in the following way:</p>
<pre>
<code>$this-&gt;MyRequestHandler-&gt;isAjax();
$this-&gt;MyRequestHandler-&gt;example();</code>
</pre>
<p>Wouldn&#8217;t it be nice if we could use it in the usual way?</p>
<pre>
<code>$this-&gt;RequestHandler-&gt;isAjax();
$this-&gt;RequestHandler-&gt;example();</code>
</pre>
<p>And yes, it is possible. For this purpose we have to override Controller::constructClasses():</p>
<pre>
<code>// app/app_controller.php
class AppController extends Controller {
    public $components = array('MyRequestHandler');
	
    public function constructClasses() {
        parent::constructClasses();
        $this-&gt;RequestHandler = $this-&gt;MyRequestHandler;
    }
}</code>
</pre>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Reusable code and the import of vendors files</title>
		<link>http://cakebaker.42dh.com/2009/08/25/reusable-code-and-the-import-of-vendors-files/</link>
		<comments>http://cakebaker.42dh.com/2009/08/25/reusable-code-and-the-import-of-vendors-files/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 15:23:23 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[vendor]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1239</guid>
		<description><![CDATA[If you write reusable code with CakePHP (e.g. a component) you often forget (or at least I do) that the code could be used either in applications or in plugins. In most cases though, this doesn&#8217;t really matter, as your code will work fine in both &#8220;environments&#8221;. However, consider the following snippet: public function example() [...]]]></description>
			<content:encoded><![CDATA[<p>If you write reusable code with CakePHP (e.g. a component) you often forget (or at least I do) that the code could be used either in applications or in plugins. In most cases though, this doesn&#8217;t really matter, as your code will work fine in both &#8220;environments&#8221;. However, consider the following snippet:</p>
<pre>
<code>public function example() {
    App::import('Vendor', 'example', array('file' =&gt; 'Example.php'));
    $example = new Example();
    ...
}</code>
</pre>
<p>This snippet works fine if it is used in an application, but it will fail with a &#8220;Class not found&#8221; error if the snippet and the corresponding vendors file (&#8220;Example.php&#8221;) are put into a plugin. The reason for the failure is that you have to use the plugin name as a prefix when importing something from a plugin, even if you use App::import() from within the respective plugin:</p>
<pre>
<code>// test is the plugin name
App::import('Vendor', 'test.example', array('file' =&gt; 'Example.php'));</code>
</pre>
<p>The consequence of this behavior is that your code has to know in which &#8220;environment&#8221; it runs if you want to make it really reusable. An alternative is to &#8220;circumvent&#8221; the application &#8220;environment&#8221; and to distribute your code, and the required vendors files, as a plugin. </p>
<p>In the <a href="http://code.42dh.com/openid">OpenID component</a> I solved this problem by determining in which &#8220;vendors&#8221; directory the required library is. And if it is in the plugin&#8217;s &#8220;vendors&#8221; directory, I set an instance variable $importPrefix with the plugin name. This prefix is then used whenever a file is imported. </p>
<p>Here is the relevant code:</p>
<pre>
<code>class OpenidComponent extends Object {
    private $importPrefix = '';

    public function __construct() {
        parent::__construct();

        $pathToVendorsFolder = $this-&gt;getPathToVendorsFolderWithOpenIDLibrary();
		
        if ($pathToVendorsFolder == '') {
            exit('Unable to find the PHP OpenID library');
        }
		
        if ($this-&gt;isPathWithinPlugin($pathToVendorsFolder)) {
            $this-&gt;importPrefix = $this-&gt;getPluginName() . '.';
        }

        $this-&gt;importCoreFilesFromOpenIDLibrary();
    }

    private function getPathToVendorsFolderWithOpenIDLibrary() {
        $pathToVendorsFolder = '';
		
        if ($this-&gt;isPathWithinPlugin(__FILE__)) {
            $pluginName = $this-&gt;getPluginName();
			
            if (file_exists(APP.'plugins'.DS.$pluginName.DS.'vendors'.DS.'Auth')) {
                $pathToVendorsFolder = APP.'plugins'.DS.$pluginName.DS.'vendors'.DS;
            }
        }

        if ($pathToVendorsFolder == '') {
            if (file_exists(APP.'vendors'.DS.'Auth')) {
                $pathToVendorsFolder = APP.'vendors'.DS;
            } elseif (file_exists(VENDORS.'Auth')) {
                $pathToVendorsFolder = VENDORS;
            }
        }
		
        return $pathToVendorsFolder;
    }
	
    private function getPluginName() {
        $result = array();
        if (preg_match('#'.DS.'plugins'.DS.'(.*)'.DS.'controllers#', __FILE__, $result)) { 
            return $result[1];
        }

        return false;
    }

    private function importCoreFilesFromOpenIDLibrary() {
        App::import('Vendor', $this-&gt;importPrefix.'consumer', array('file' =&gt; 'Auth'.DS.'OpenID'.DS.'Consumer.php'));
        App::import('Vendor', $this-&gt;importPrefix.'sreg', array('file' =&gt; 'Auth'.DS.'OpenID'.DS.'SReg.php'));
    }

    private function isPathWithinPlugin($path) {
        return strpos($path, DS.'plugins'.DS) ? true : false;
    }
}</code>
</pre>
<p>This code is meant to give you an idea of how it could be solved in that specific situation, and not as a solution you can copy 1:1&#8230;</p>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/08/25/reusable-code-and-the-import-of-vendors-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New release of the OpenID component</title>
		<link>http://cakebaker.42dh.com/2009/08/18/new-release-of-the-openid-component/</link>
		<comments>http://cakebaker.42dh.com/2009/08/18/new-release-of-the-openid-component/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 15:24:05 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1235</guid>
		<description><![CDATA[Today I released a new version of the OpenID component. Three changes made it into this release: Almost all external libraries are now included in the package to make the installation a bit easier. Included are the required PHP OpenID library and PEAR DB (which is used if you want to store the OpenID data [...]]]></description>
			<content:encoded><![CDATA[<p>Today I released a new version of the OpenID component. Three changes made it into this release:</p>
<p>Almost all external libraries are now included in the package to make the installation a bit easier. Included are the required <a href="http://www.openidenabled.com/php-openid/">PHP OpenID</a> library and <a href="http://pear.php.net/package/DB">PEAR DB</a> (which is used if you want to store the OpenID data in the database). Not included is the <a href="http://eaut.org">EAUT library</a> as I think this standard is dead (i.e. nobody is using it).</p>
<p>The configuration settings are now set when you add the OpenID component to the $components array of your controller(s):</p>
<pre>
<code>public $components = array('Openid' =&gt; array('use_database' =&gt; true));

or

public $components = array('Openid' =&gt; array('database_config' =&gt; 'name_of_database_config));</code>
</pre>
<p>The old way, using Configure::write(), is no longer supported:</p>
<pre>
<code>Configure::write('Openid.use_database', true);
Configure::write('Openid.database_config', 'name_of_database_config');</code>
</pre>
<p>So, if you upgrade and you use those configuration settings, make sure to adapt your code accordingly.</p>
<p>Last, but not least, I fixed a bug which caused a &#8220;class not found&#8221; error if you used the component in a plugin. </p>
<p>That&#8217;s it. You can get the component from <a href="http://code.42dh.com/openid">http://code.42dh.com/openid</a> or directly from <a href="http://github.com/cakebaker/openid-component">GitHub</a>.</p>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/08/18/new-release-of-the-openid-component/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Default views for extensions</title>
		<link>http://cakebaker.42dh.com/2009/07/02/default-views-for-extensions/</link>
		<comments>http://cakebaker.42dh.com/2009/07/02/default-views-for-extensions/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 15:41:54 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1218</guid>
		<description><![CDATA[I&#8217;m currently revamping the API of NoseRub to use CakePHP&#8217;s Router::parseExtensions() magic, i.e. if you append an extension like &#8220;.json&#8221; to the action you request, then CakePHP automagically sets the correct content type, and uses extension-specific layouts and views to render the result (e.g. if you request /example/action.json then the layout app/views/layouts/json/default.ctp and the view [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently revamping the API of <a href="http://noserub.com">NoseRub</a> to use CakePHP&#8217;s <a href="http://api.cakephp.org/class/router#method-RouterparseExtensions">Router::parseExtensions()</a> magic, i.e. if you append an extension like &#8220;.json&#8221; to the action you request, then CakePHP automagically sets the correct content type, and uses extension-specific layouts and views to render the result (e.g. if you request /example/action.json then the layout app/views/layouts/json/default.ctp and the view app/views/example/json/action.ctp are used by default). </p>
<p>That&#8217;s nice, however, in our case all JSON views are identical (the same applies for the XML views):</p>
<pre>
<code>// requires the JSON part from the Zend framework
App::import('Vendor', 'json', array('file' =&gt; 'Zend'.DS.'Json.php'));
echo Zend_Json::encode(array('data' =&gt; $data));</code>
</pre>
<p>And so following the default approach would lead to a lot of duplication and many unnecessary folders and view files. And that&#8217;s not that cool ;-)</p>
<p>After some experimentation I found a better way. </p>
<p>For each extension I created a folder with a default view:</p>
<pre>
<code>app
  views
    json
      default.ctp
    xml
      default.ctp</code>
</pre>
<p>json/default.ctp contains the code I have shown above, and xml/default.ctp would look like:</p>
<pre>
<code>echo $xml-&gt;serialize(array('data' =&gt; $data), array('format' =&gt; 'tags'));</code>
</pre>
<p>To tell CakePHP it should render those default views when there is not a more specific view, I added the following beforeRender() callback method to the AppController:</p>
<pre>
<code>// app/app_controller.php
class AppController extends Controller {
    public function beforeRender() {
        $pathToViewFile = dirname(__FILE__).DS.'views'.DS.$this-&gt;viewPath.DS.$this-&gt;action.'.ctp';
		
        if (!file_exists($pathToViewFile)) {
            $this-&gt;viewPath = $this-&gt;layoutPath;
            $this-&gt;action = 'default';
        }
    }
}</code>
</pre>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/07/02/default-views-for-extensions/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Specifying helpers for static pages</title>
		<link>http://cakebaker.42dh.com/2009/06/01/specifying-helpers-for-static-pages/</link>
		<comments>http://cakebaker.42dh.com/2009/06/01/specifying-helpers-for-static-pages/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 07:19:10 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[helper]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1201</guid>
		<description><![CDATA[In a recent comment I got asked how you can reference Javascript files from static pages (i.e. from files in app/views/pages) as &#8220;you can&#8217;t add the JavaScript helper, because there isn&#8217;t a controller&#8221;. Well, the assumption that there is no controller is wrong. There is one, the PagesController, though by default it is &#8220;hidden&#8221; in [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent <a href="http://cakebaker.42dh.com/2007/02/21/referencing-javascript-files/#comment-129496">comment</a> I got asked how you can reference Javascript files from static pages (i.e. from files in app/views/pages) as &#8220;you can&#8217;t add the JavaScript helper, because there isn&#8217;t a controller&#8221;.</p>
<p>Well, the assumption that there is no controller is wrong. There is one, the PagesController, though by default it is &#8220;hidden&#8221; in cake/libs/controller (unless you baked your project with the bake script, then you will also find a PagesController in app/controllers).</p>
<p>And this means you can specify the helpers you want to use in your static pages in the usual way: by adding them to the $helpers array of the PagesController resp. the AppController (app/app_controller.php), if you want to use the helpers in the views of more than one controller. Please do not edit the PagesController in the cake/libs/controller directory, but copy it to app/controllers and make the changes there.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/06/01/specifying-helpers-for-static-pages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
