<?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; component</title>
	<atom:link href="http://cakebaker.42dh.com/tags/component/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:29:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Bugfix release v2010-12-08 of the OpenID component</title>
		<link>http://cakebaker.42dh.com/2010/12/08/bugfix-release-v2010-12-08-of-the-openid-component/</link>
		<comments>http://cakebaker.42dh.com/2010/12/08/bugfix-release-v2010-12-08-of-the-openid-component/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 15:53:40 +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=1465</guid>
		<description><![CDATA[There is a new bugfix release of the OpenID component available: https://github.com/cakebaker/openid-component/downloads. This release fixes a bug in the isOpenIDResponse() method. So far this method only recognized OpenID responses from a GET request. But as I had to learn, there are OpenID providers (e.g. Hyves) responding with a POST request&#8230; So, if you use the [...]]]></description>
			<content:encoded><![CDATA[<p>There is a new bugfix release of the OpenID component available: <a href="https://github.com/cakebaker/openid-component/downloads">https://github.com/cakebaker/openid-component/downloads</a>. </p>
<p>This release fixes a bug in the isOpenIDResponse() method. So far this method only recognized OpenID responses from a GET request. But as I had to learn, there are OpenID providers (e.g. <a href="http://hyves.nl">Hyves</a>) responding with a POST request&#8230; So, if you use the isOpenIDResponse() method, please upgrade to the new version. </p>
<p>However, this bug not only affected the component itself but also the <a href="http://code.42dh.com/openid/">examples</a> and the <a href="https://github.com/cakebaker/openid-component-example">example application</a>. They contained code that looked like:</p>
<pre>
<code>if ($this-&gt;RequestHandler-&gt;isPost()) {
    // make OpenID request
} elseif ($this-&gt;Openid-&gt;isOpenIDResponse()) {
    // handle OpenID response
}</code>
</pre>
<p>This snippet will fail if the response from an OpenID provider is a POST request. Instead it should look like:</p>
<pre>
<code>if ($this-&gt;RequestHandler-&gt;isPost() &amp;&amp; !$this-&gt;Openid-&gt;isOpenIDResponse()) {
    // make OpenID request
} elseif ($this-&gt;Openid-&gt;isOpenIDResponse()) {
    // handle OpenID response
}</code>
</pre>
<p>Please fix this in your code if you followed the examples.</p>
<p>Thanks go to Sam Mousa for reporting this issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/12/08/bugfix-release-v2010-12-08-of-the-openid-component/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<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>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>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>How to use the OpenID component with the Auth component</title>
		<link>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/</link>
		<comments>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 16:02:39 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[authentication]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=994</guid>
		<description><![CDATA[Please note that the hack described in this article no longer works with CakePHP 1.2.3.8166! See Peter&#8217;s comment for a possible solution for the current CakePHP release (1.2.5.x). Some days ago I got asked how you can use the OpenID component together with the Auth component from CakePHP. As I didn&#8217;t knew the answer, I [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Please note that the hack described in this article no longer works with CakePHP 1.2.3.8166! See <a href="http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/#comment-133898">Peter&#8217;s comment</a> for a possible solution for the current CakePHP release (1.2.5.x).</strong></p>
<p>Some days ago I got asked how you can use the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">OpenID component</a> together with the Auth component from CakePHP.</p>
<p>As I didn&#8217;t knew the answer, I had to experiment a bit. Even though it was a quite frustrating experience (thanks to the strange design of the Auth component and too much automagic), I finally managed to find a &#8220;solution&#8221;. It is rather a hack, but it seems to work ;-)</p>
<p>Ok, here we go. </p>
<p>The first step is to create the login form. Because the Auth component expects the login credentials to consist of username and password, we have to add a (hidden) field for the password.</p>
<pre>
<code>&lt;?php
// app/views/users/login.ctp
$session-&gt;flash('auth');

echo $form-&gt;create('User', array('action' =&gt; 'login'));
echo $form-&gt;input('username', array('label' =&gt; 'OpenID:'));
echo $form-&gt;input('password', array('type' =&gt; 'hidden'));
echo $form-&gt;end('Login');
?&gt;</code>
</pre>
<p>The next step is to create the UsersController. The login() method is a bit special in this case, it is called three times: when you visit the login form, when you submit the login form, and when you come back from the OpenID provider. The rest of the code should be self-explanatory (if not, please leave a comment).</p>
<pre>
<code>// app/controllers/users_controller.php
class UsersController extends AppController {
    public $components = array('Auth', 'Openid', 'RequestHandler');
 
    public function beforeFilter() {
        $this-&gt;Auth-&gt;loginError = 'Login failed';
    }
    
    public function login() { 
        $returnTo = 'http://'.$_SERVER['SERVER_NAME'].'/users/login';
		
        if ($this-&gt;RequestHandler-&gt;isPost()) {   
    	    $this-&gt;makeOpenIDRequest($this-&gt;data['User']['username'], $returnTo);
        }
    	
        if ($this-&gt;isOpenIDResponse()) {
            $this-&gt;handleOpenIDResponse($returnTo);
        }
    }
    
    private function makeOpenIDRequest($openid, $returnTo) {
        try {
            $this-&gt;Openid-&gt;authenticate($openid, $returnTo, 'http://'.$_SERVER['SERVER_NAME']);
        } catch (Exception $e) {
            // empty
        }
    }
    
    private function isOpenIDResponse() {
        return (count($_GET) &gt; 1);
    }
    
    private function handleOpenIDResponse($returnTo) {
        $response = $this-&gt;Openid-&gt;getResponse($returnTo);
        $this-&gt;Auth-&gt;login($response);
        $this-&gt;redirect($this-&gt;Auth-&gt;redirect());
    }
    
    public function logout() {
        $this-&gt;redirect($this-&gt;Auth-&gt;logout());
    }
}</code>
</pre>
<p>As you can see in the handleOpenIDResponse() method, we pass the OpenID response object to the login method of the Auth component. As the Auth component cannot know how to deal with that object, we have to write some functionality to deal with the response object. For this purpose we have to override the find() method of the User model, as it is the method which is eventually called by the Auth component if you call its login() method. The response object is passed to the find() method in the $conditions array and is available via the strange &#8220;`User`.`id`&#8221; key. The implementation itself is quite simple: you have to return an array with user data if the login was successful, or an empty array if the login was not successful. </p>
<pre>
<code>// app/models/user.php
class User extends AppModel {
    public function find($conditions = null, $fields = array(), $order = null, $recursive = null) {	
        if (is_array($conditions) &amp;&amp; isset($conditions['`User`.`id`'])) {
            $response = $conditions['`User`.`id`'];
			
            if ($response-&gt;status == Auth_OpenID_SUCCESS) {
                return array('User' =&gt; array('openid' =&gt; $response-&gt;identity_url));
            }
			
            return array();
        }

        if (is_array($conditions) &amp;&amp; isset($conditions['User.username']) &amp;&amp; isset($conditions['User.password'])) {
            return array();
        }
		
        return parent::find($conditions, $fields, $order, $recursive);
    }
}</code>
</pre>
<p>Especially if you have only an OpenID column in your table you have to hinder the Auth component from performing a find() operation using the non-existing columns &#8220;username&#8221; and &#8220;password&#8221;, hence the check in the example whether those conditions are set.</p>
<p>With that, it should now be possible to login with your OpenID into your application protected by the Auth component.</p>
<p>I hope this is useful for some of you!</p>
<p>Update (2008-12-24): Fixing some small issues mentioned by <a href="http://lboy.wordpress.com/">lboy</a> in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/12/09/how-to-use-the-openid-component-with-the-auth-component/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Using OAuth-enabled APIs with CakePHP</title>
		<link>http://cakebaker.42dh.com/2008/09/01/using-oauth-enabled-apis-with-cakephp/</link>
		<comments>http://cakebaker.42dh.com/2008/09/01/using-oauth-enabled-apis-with-cakephp/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 14:44:32 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[oauth]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=769</guid>
		<description><![CDATA[A growing number of APIs support OAuth, i.e. it is possible to give service A access to service B without giving B&#8217;s username/password to A. In this article I&#8217;m going to show you how to use OAuth-enabled APIs with CakePHP (and the OAuth consumer component I have written). First, there are some preparations necessary, namely [...]]]></description>
			<content:encoded><![CDATA[<p>A growing number of APIs support <a href="http://oauth.net">OAuth</a>, i.e. it is possible to give service A access to service B without giving B&#8217;s username/password to A. In this article I&#8217;m going to show you how to use OAuth-enabled APIs with CakePHP (and the OAuth consumer component I have written).</p>
<p>First, there are some preparations necessary, namely the download of the required files:</p>
<ul>
<li>Get the <a href="http://cakebaker.42dh.com/downloads/oauth-component-for-cakephp/">OAuth component</a> and place its content in &#8220;app/controllers/components&#8221;</li>
<li>Get the <a href="http://oauth.googlecode.com/svn/code/php/OAuth.php">OAuth library</a> and put it in &#8220;vendors/OAuth&#8221;</li>
<li>Set the security level in app/config/core.php to &#8220;low&#8221; (thanks to <a href="http://www.intertwinesys.com/">Bryan Young</a> for mentioning in the comments)</li>
</ul>
<p>The next step is to register your application at the service provider (e.g. <a href="http://fireeagle.yahoo.net/developer">Yahoo&#8217;s Fire Eagle</a>) to get consumer key and consumer secret. Those values are then stored in a class called FireEagleConsumer if we go on using Fire Eagle as example service provider in this article:</p>
<pre>
<code>// app/controllers/components/oauth_consumers/fire_eagle_consumer.php
class FireEagleConsumer extends AbstractConsumer {
    public function __construct() {
        parent::__construct('THE KEY', 'THE SECRET');
    }
}</code>
</pre>
<p>This class is then used by the component to access consumer key and secret.</p>
<p>Using an OAuth-enabled API consists of four steps:</p>
<ul>
<li>Get RequestToken</li>
<li>Authorize RequestToken</li>
<li>Exchange RequestToken for AccessToken</li>
<li>Access the API using the AccessToken</li>
</ul>
<p>In the ideal case the first three steps are performed once. But it is also possible that for example the service provider expires the AccessToken after some time, and so those steps have to be repeated.</p>
<p>Anyway, let&#8217;s have a look at how those steps look in code. We start with getting the RequestToken:</p>
<pre>
<code>// app/controller/oauth_consumer_example_controller.php
class OauthConsumerExampleController extends AppController {
    public $uses = array();
    public $components = array('OauthConsumer');
	
    public function index() {
        $requestToken = $this-&gt;OauthConsumer-&gt;getRequestToken('FireEagle', 'https://fireeagle.yahooapis.com/oauth/request_token');
        $this-&gt;Session-&gt;write('requestToken', $requestToken);
    }
}</code>
</pre>
<p>The code is probably self-explanatory, we have to add the component to the $components array, and then we get the RequestToken from the specified url (while writing this I just realized it would make sense to move the url to the FireEagleConsumer class&#8230;).</p>
<p>The next step is simple: we have to redirect the user to the authorize page of the service provider:</p>
<pre>
<code>// app/controller/oauth_consumer_example_controller.php
class OauthConsumerExampleController extends AppController {
    public $uses = array();
    public $components = array('OauthConsumer');
	
    public function index() {
        $requestToken = $this-&gt;OauthConsumer-&gt;getRequestToken('FireEagle', 'https://fireeagle.yahooapis.com/oauth/request_token');
        $this-&gt;Session-&gt;write('requestToken', $requestToken);
        $this-&gt;redirect('http://fireeagle.yahoo.net/oauth/authorize?oauth_token='.$requestToken-&gt;key);
    }
}</code>
</pre>
<p>After the RequestToken is authorized, we get redirected to a callback url we specified while registering the application. We can now exchange the authorized RequestToken for an AccessToken:</p>
<pre>
<code>// app/controller/oauth_consumer_example_controller.php
class OauthConsumerExampleController extends AppController {
    public $uses = array();
    public $components = array('OauthConsumer');

    ...

    public function callback() {
        $requestToken = $this-&gt;Session-&gt;read('requestToken');
        $accessToken = $this-&gt;OauthConsumer-&gt;getAccessToken('FireEagle', 'https://fireeagle.yahooapis.com/oauth/access_token', $requestToken);
    }
}</code>
</pre>
<p>In a real use case you would also save the data of the AccessToken (key and secret) to the database, so you don&#8217;t have to perform all those steps every time you want to call the API. </p>
<p>The last step is to call the API, in this example to get the latest location of the user:</p>
<pre>
<code>// app/controller/oauth_consumer_example_controller.php
class OauthConsumerExampleController extends AppController {
    public $uses = array();
    public $components = array('OauthConsumer');

    ...

    public function callback() {
        $requestToken = $this-&gt;Session-&gt;read('requestToken');
        $accessToken = $this-&gt;OauthConsumer-&gt;getAccessToken('FireEagle', 'https://fireeagle.yahooapis.com/oauth/access_token', $requestToken);
        $data = $this-&gt;OauthConsumer-&gt;get('FireEagle', $accessToken-&gt;key, $accessToken-&gt;secret, 'https://fireeagle.yahooapis.com/api/0.1/user');
        // do something with the data
    }
}</code>
</pre>
<p>That&#8217;s it. Feedback is welcome!</p>
<p>Update 2008-09-15: Slightly adapted for new version of the component.<br />
Update 2009-01-14: Adding hint about security level.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/09/01/using-oauth-enabled-apis-with-cakephp/feed/</wfw:commentRss>
		<slash:comments>67</slash:comments>
		</item>
		<item>
		<title>MySQL support for OpenID component</title>
		<link>http://cakebaker.42dh.com/2008/08/27/mysql-support-for-openid-component/</link>
		<comments>http://cakebaker.42dh.com/2008/08/27/mysql-support-for-openid-component/#comments</comments>
		<pubDate>Wed, 27 Aug 2008 15:53:37 +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=742</guid>
		<description><![CDATA[Up to now the OpenID component stored all data in the file system (in app/tmp/openid) even though the OpenID library provided by JanRain also supports databases. I wanted to provide support for MySQL for quite some time, but I wanted too much (i.e. the perfect CakePHP solution *g*), and so this feature never materialized&#8230; Anyway, [...]]]></description>
			<content:encoded><![CDATA[<p>Up to now the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">OpenID component</a> stored all data in the file system (in app/tmp/openid) even though the <a href="http://openidenabled.com/">OpenID library</a> provided by <a href="http://janrain.com/">JanRain</a> also supports databases. I wanted to provide support for MySQL for quite some time, but I wanted too much (i.e. the perfect CakePHP solution *g*), and so this feature never materialized&#8230;</p>
<p>Anyway, in the meantime I used a more pragmatic approach and used what&#8217;s already there. So, instead of using CakePHP for accessing the database, the superseded <a href="http://pear.php.net/package/DB">PEAR DB</a> package is used&#8230;</p>
<p>If you want to use the OpenID component with MySQL, you have to perform the following steps:</p>
<ul>
<li>Download the latest version of the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">OpenID component</a></li>
<li>If you already use the component, simply replace it with the new version. In the other case follow the installation instructions from the download page</li>
<li>Execute the SQL script included in the zip file to create the necessary tables</li>
<li>Download the <a href=http://pear.php.net/package/PEAR/"">PEAR base system</a> and place PEAR.php from the zip in vendors/pear</li>
<li>Download <a href="http://pear.php.net/package/DB/">PEAR DB</a> and place DB.php and the DB folder from the zip in vendors/pear</li>
<li>In the file which uses the OpenID component add: Configure::write(&#8216;Openid.use_database&#8217;, true);</li>
<li>If you want to use a database configuration other than &#8220;default&#8221; you can specify it with: Configure::write(&#8216;Openid.database_config&#8217;, &#8216;name_of_database_config&#8217;);</li>
</ul>
<p>With that, the data should now get stored in the database. If there are any questions/problems/whatever, please leave a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/08/27/mysql-support-for-openid-component/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New callback methods for components</title>
		<link>http://cakebaker.42dh.com/2008/06/02/new-callback-methods-for-components/</link>
		<comments>http://cakebaker.42dh.com/2008/06/02/new-callback-methods-for-components/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 14:32:19 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[feature]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=608</guid>
		<description><![CDATA[Recently, support for three new component callback methods has been added: beforeRender, beforeRedirect, and shutdown. (Correction: those callbacks have been around for quite a while, see Nate&#8217;s comment, but I noticed them only recently) As its name implies, the beforeRender() callback method is called before the view is rendered, but after the beforeRender() callback method [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, support for three new component callback methods has been added: beforeRender, beforeRedirect, and shutdown. (Correction: those callbacks have been around for quite a while, see Nate&#8217;s comment, but I noticed them only recently)</p>
<p>As its name implies, the <strong>beforeRender()</strong> callback method is called before the view is rendered, but after the beforeRender() callback method of the controller:</p>
<pre>
// in your component
public function beforeRender($controller) {
    // do something
}
</pre>
<p>The <strong>beforeRedirect()</strong> callback is also quite obvious, it gets called before a redirect is performed:</p>
<pre>
// in your component
public function beforeRedirect($controller, $url, $status = null, $exit = true) {
    // do something
}
</pre>
<p>By providing a return value, you can override the values with which the redirect method was originally called. For example:</p>
<pre>
public function beforeRedirect($controller, $url, $status = null, $exit = true) {
    // return '/redirect/target';  // a single value is treated as an URL
    return array('url' =&gt; '/redirect/target', 'status' =&gt; 307);
}
</pre>
<p>The last callback method, <strong>shutdown()</strong>, is called after Controller::render() and before Controller::afterFilter():</p>
<pre>
// in your component
public function shutdown($controller) {
    // do something
}
</pre>
<p>Those callback methods are probably a &#8220;nice to have&#8221; feature, at least I didn&#8217;t miss them up to now.</p>
<p>Anyway, happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/06/02/new-callback-methods-for-components/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>A missing concept: model &#8220;components&#8221;</title>
		<link>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/</link>
		<comments>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/#comments</comments>
		<pubDate>Thu, 15 May 2008 08:43:55 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[ideas]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=603</guid>
		<description><![CDATA[The fatter your models become, the more obvious it is (at least for me) that something is missing. Let&#8217;s say we have a bunch of models. Two of those models use internally the same functionality. To avoid code duplication, you want to share this functionality between the two models. But how could you accomplish that? [...]]]></description>
			<content:encoded><![CDATA[<p>The fatter your models become, the more obvious it is (at least for me) that something is missing. Let&#8217;s say we have a bunch of models. Two of those models use internally the same functionality. To avoid code duplication, you want to share this functionality between the two models. But how could you accomplish that? </p>
<p>One idea is to move the functionality to the AppModel. That works, but it is a dirty solution. The AppModel should contain generic functionality relevant for all models, and not functionality specific to only two models. </p>
<p>Another idea is to move the functionality into a class in the vendors folder and to load it with App::import(). That works fine, but if you compare this solution with elements and helpers for reusing view functionality, and with components for reusing controller functionality, it is a bit strange there is no &#8220;native&#8221; solution for models (sure, there are behaviors, but they are not designed for the kind of code reuse I described above).</p>
<p>Hence I think it would be useful to have model &#8220;components&#8221;, which could be realized in the same way as controller components are realized. For example:</p>
<pre>
class Example extends AppModel {
    public $components = array('X');

    public function doSomething() {
        ...
        $this-&gt;X-&gt;doSomethingElse(); // using model component
        ...
    }
}
</pre>
<p>In the longer term it would even make sense to have a unified &#8220;components&#8221; concept to replace the current concepts of components and helpers. But well, we will see what the future brings ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>New version of the OpenID component</title>
		<link>http://cakebaker.42dh.com/2008/02/06/new-version-of-the-openid-component/</link>
		<comments>http://cakebaker.42dh.com/2008/02/06/new-version-of-the-openid-component/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 15:46:43 +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/2008/02/06/new-version-of-the-openid-component/</guid>
		<description><![CDATA[Just uploaded a new version of the OpenID component I wrote sometime ago. It uses now version 2.0.0 of the PHP OpenID library, which supports the OpenID 2.0 specification. As the API has changed a bit, let me make a simple example to show you how the component is used. First we create the login [...]]]></description>
			<content:encoded><![CDATA[<p>Just uploaded a new version of the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">OpenID component</a> I wrote sometime ago. It uses now version 2.0.0 of the <a href="http://openidenabled.com/php-openid/">PHP OpenID library</a>, which supports the OpenID 2.0 specification. </p>
<p>As the API has changed a bit, let me make a simple example to show you how the component is used. </p>
<p>First we create the login form:</p>
<pre>
&lt;?php
// app/views/users/login.ctp
if (isset($message)) {
    echo '&lt;p class="error"&gt;'.$message.'&lt;/p&gt;';
}
echo $form-&gt;create('User', array('type' =&gt; 'post', 'action' =&gt; 'login'));
echo $form-&gt;input('OpenidUrl.openid', array('label' =&gt; false));
echo $form-&gt;end('Login');
?&gt;
</pre>
<p>As next step we have to implement the login action in our controller:</p>
<pre>
// app/controllers/users_controller.php
class UsersController extends AppController {
    var $components = array('Openid');
    var $uses = array();

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

        if (!empty($this-&gt;data)) {
            try {
                $this-&gt;Openid-&gt;authenticate($this-&gt;data['OpenidUrl']['openid'], $returnTo, 'http://'.$_SERVER['SERVER_NAME']);
            } catch (InvalidArgumentException $e) {
                $this-&gt;setMessage('Invalid OpenID');
            } catch (Exception $e) {
                $this-&gt;setMessage($e-&gt;getMessage());
            }
        } elseif (count($_GET) &gt; 1) {
            $response = $this-&gt;Openid-&gt;getResponse($returnTo);

            if ($response-&gt;status == Auth_OpenID_CANCEL) {
                $this-&gt;setMessage('Verification cancelled');
            } elseif ($response-&gt;status == Auth_OpenID_FAILURE) {
                $this-&gt;setMessage('OpenID verification failed: '.$response-&gt;message);
            } elseif ($response-&gt;status == Auth_OpenID_SUCCESS) {
                echo 'successfully authenticated!';
                exit;
            }
        }
    }

    private function setMessage($message) {
        $this-&gt;set('message', $message);
    }
}
</pre>
<p>The login action basically performs three things. If it is called with a GET request without any parameters, it simply shows the login form. If we submit the login form, then the OpenID authentication process is started and you will be redirected to your OpenID provider. And when you get redirected back from the OpenID provider, we process the response.</p>
<p>That&#8217;s it. You can download the component from the <a href="http://cakebaker.42dh.com/downloads/openid-component-for-cakephp/">download area</a> (and don&#8217;t forget to read the installation instructions).</p>
<p>Happy baking :)</p>
<p>See also: <a href="http://cakebaker.42dh.com/2008/02/12/using-the-openid-simple-registration-extension/">Using the OpenID Simple Registration Extension</a></p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/02/06/new-version-of-the-openid-component/feed/</wfw:commentRss>
		<slash:comments>79</slash:comments>
		</item>
	</channel>
</rss>

