<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>cakebaker</title>
	
	<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>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Cakebaker" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="cakebaker" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://cakebaker.42dh.com</link><url>http://cakebaker.42dh.com/wp-content/uploads/2007/12/cakebaker_logo_small.png</url><title>cakebaker logo</title></image><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>Grouping “constants” with JavaScript</title>
		<link>http://cakebaker.42dh.com/2010/07/14/grouping-constants-with-javascript/</link>
		<comments>http://cakebaker.42dh.com/2010/07/14/grouping-constants-with-javascript/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 14:10:32 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1427</guid>
		<description><![CDATA[A while ago I wrote about how you can group related constants in PHP5 by using a constants class: class MyConstants { const AA = 'value'; const BB = 'another value'; } echo MyConstants::AA; // output: value Now, while experimenting with JavaScript (or more precisely with Node.js) I got some constants in my code I [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I wrote about how you can <a href="http://cakebaker.42dh.com/2008/10/09/grouping-of-constants/">group related constants</a> in PHP5 by using a constants class:</p>
<pre>
<code>class MyConstants {
    const AA = 'value';
    const BB = 'another value';
}

echo MyConstants::AA; // output: value</code>
</pre>
<p>Now, while experimenting with JavaScript (or more precisely with <a href="http://nodejs.org">Node.js</a>) I got some constants in my code I wanted to organize with such a constants class. My first, albeit naive, approach looked like:</p>
<pre>
<code>var sys = require('sys');

function MyConstants() {
    const AA = 'value';
    const BB = 'another value';
}

sys.puts(MyConstants.AA); // output: undefined</code>
</pre>
<p>However, as you can see, this doesn&#8217;t work. One reason is that <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/const">const</a> &#8220;[c]reates a constant that can be global or local to the function in which it is declared.&#8221;. So it isn&#8217;t possible to create a constants class like I imagined&#8230;</p>
<p>This means we have to emulate a constants class by using static properties and relying on the naming convention that names of constants are uppercased (i.e. the &#8220;constants&#8221; are technically not constants and their value can be changed):</p>
<pre>
<code>var sys = require('sys');

function MyConstants() {
}

MyConstants.AA = 'value';
MyConstants.BB = 'another value';

sys.puts(MyConstants.AA); // output: value</code>
</pre>
<p>If there is a better approach, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/07/14/grouping-constants-with-javascript/feed/</wfw:commentRss>
		<slash:comments>5</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>Sassy CSS</title>
		<link>http://cakebaker.42dh.com/2010/05/08/sassy-css/</link>
		<comments>http://cakebaker.42dh.com/2010/05/08/sassy-css/#comments</comments>
		<pubDate>Sat, 08 May 2010 13:13:11 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1398</guid>
		<description><![CDATA[Those who follow me on Twitter probably know about my love-hate relationship with CSS. To ease the pain of working with CSS I switched to Compass, a stylesheet authoring framework. With Compass, you write the stylesheets in Sass (Syntactically Awesome Stylesheets) instead of CSS. Sass is basically CSS without brackets and semicolons, as you can [...]]]></description>
			<content:encoded><![CDATA[<p>Those who follow me on Twitter probably know about my love-hate relationship with CSS. To ease the pain of working with CSS I switched to <a href="http://compass-style.org/">Compass</a>, a stylesheet authoring framework. With Compass, you write the stylesheets in <a href="http://sass-lang.com/">Sass</a> (Syntactically Awesome Stylesheets) instead of CSS. Sass is basically CSS without brackets and semicolons, as you can see in this example from the Sass website:</p>
<pre>
<code>h1
  height: 118px
  margin-top: 1em

.tagline
  font-size: 26px
  text-align: right</code>
</pre>
<p>However, with the upcoming Sass 3 (it is planned to be released on May 10, 2010) a new format gets introduced: SCSS (Sassy CSS). It is a superset of CSS, i.e. each CSS file is automatically a SCSS file (you simply have to change the file extension from &#8220;css&#8221; to &#8220;scss&#8221;). So the example from above in SCSS is just plain CSS:</p>
<pre>
<code>h1 {
  height: 118px;
  margin-top: 1em;
}

.tagline {
  font-size: 26px;
  text-align: right;
}</code>
</pre>
<p>Not that exciting, isn&#8217;t it? </p>
<p>Where SCSS shines is when it comes to the integration of the Sass features (nesting, variables, and mixins) into this format. The devs did a very good job to make it feel like those features are native CSS. </p>
<p>Let&#8217;s have a look at some examples.</p>
<p>Nesting:</p>
<pre>
<code>#header {
  background: gray;
  a {
    background: white;
    color: black;
  }
}</code>
</pre>
<p>Variables:</p>
<pre>
<code>$background_color: gray;

#header {
  background: $background_color;
}</code>
</pre>
<p>Mixins:</p>
<pre>
<code>@mixin red_border($border_width) {
  border: $border_width solid red;
}

#box_a {
  @include red_border(5px);
}

#box_b {
  @include red_border(10px);
}</code>
</pre>
<p>Personally I really like the new SCSS format, and I can only recommend to try it out for yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/05/08/sassy-css/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Speed up your tests with Hydra</title>
		<link>http://cakebaker.42dh.com/2010/04/20/speed-up-your-tests-with-hydra/</link>
		<comments>http://cakebaker.42dh.com/2010/04/20/speed-up-your-tests-with-hydra/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 14:52:46 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cucumber]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1364</guid>
		<description><![CDATA[Nowadays most computers come with more than one processor. And so it makes sense to use the additional processing power to speed up your tests by distributing them across the available processors. One tool that helps with this is Hydra. It allows you to distribute tests across multiple processors and machines, and currently supports the [...]]]></description>
			<content:encoded><![CDATA[<p>Nowadays most computers come with more than one processor. And so it makes sense to use the additional processing power to speed up your tests by distributing them across the available processors. </p>
<p>One tool that helps with this is <a href="http://github.com/ngauthier/hydra">Hydra</a>. It allows you to distribute tests across multiple processors and machines, and currently supports the <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html">Test::Unit</a>, <a href="http://cukes.info/">Cucumber</a>, and <a href="http://rspec.info/">RSpec</a> frameworks. In this article I will focus on running Cucumber tests on a single machine. </p>
<p>As Hydra is distributed as a Ruby Gem its installation is pretty simple:</p>
<pre>
<code>gem install hydra</code>
</pre>
<p>After that, you have to add Hydra to the Rakefile of the respective project. And you have to specify the Cucumber task and the files it should use.</p>
<pre>
<code># Rakefile
require 'hydra'
require 'hydra/tasks'

Hydra::TestTask.new('hydra:cucumber') do |t|
  t.add_files 'features/**/*.feature'
end</code>
</pre>
<p>As last step you have to create a &#8220;hydra.yml&#8221; file in the &#8220;config&#8221; folder of your project. Here you define whether the tests should run locally, and how many runners Hydra should start. Runners correspond to processors, and so the setting below is for a dual core machine.</p>
<pre>
<code># config/hydra.yml
workers:
  - type: local
    runners: 2</code>
</pre>
<p>With everything set up, you can now run the tests with the following command:</p>
<pre>
<code>$ RAILS_ENV=test rake hydra:cucumber</code>
</pre>
<p>To verify whether there is really a speed gain when running the tests in this way you have to do some kind of a benchmark (see the example below), because running something on multiple processors doesn&#8217;t necessarily mean it is faster&#8230;</p>
<p>Happy testing!<br />
&nbsp;<br />
<br />&#8212;<br />
For my (unscientific) benchmark I ran my test suite (consisting of 12 files with 43 scenarios and 193 steps) with the following commands five times and averaged the results:</p>
<pre>
<code>$ time cucumber features
$ time rake cucumber
$ time RAILS_ENV=test rake hydra:cucumber</code>
</pre>
<p>In the first scenario I ran the benchmark with no other user applications running, i.e. both processors were available for the task at hand. From the results you can see that using Hydra in such a scenario is the fastest solution. </p>
<pre>
<code>cucumber: 24.1s
cucumber with rake: 31.4s
hydra:cucumber: 22.4s</code>
</pre>
<p>In the second scenario I ran the benchmark in a typical development environment with many open applications, i.e. around 1.5 processors were available. This time, using Hydra is not the fastest solution, the overhead is bigger than the speed gain from having more than one processor .</p>
<pre>
<code>cucumber: 25.9s
cucumber with rake: 34.3s
hydra:cucumber: 30.6s</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/04/20/speed-up-your-tests-with-hydra/feed/</wfw:commentRss>
		<slash:comments>4</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>let()’s write slightly cleaner specs</title>
		<link>http://cakebaker.42dh.com/2010/04/02/lets-write-slightly-cleaner-specs/</link>
		<comments>http://cakebaker.42dh.com/2010/04/02/lets-write-slightly-cleaner-specs/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 09:08:23 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[bdd]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1345</guid>
		<description><![CDATA[When writing specs for your code, you often have to do some initialization. With RSpec I do this initialization in a &#8220;before&#8221; block as shown in the following example: describe BlogPost do before do @blog_post = BlogPost.create :title =&#62; 'Hello' end it "does something" do @blog_post.should ... end it "does something else" do @blog_post.should ... [...]]]></description>
			<content:encoded><![CDATA[<p>When writing specs for your code, you often have to do some initialization. With <a href="http://rspec.info">RSpec</a> I do this initialization in a &#8220;before&#8221; block as shown in the following example:</p>
<pre>
<code>describe BlogPost do
  before do
    @blog_post = BlogPost.create :title =&gt; 'Hello'
  end

  it "does something" do
    @blog_post.should ...
  end

  it "does something else" do
    @blog_post.should ...
  end
end</code>
</pre>
<p>However, recently I stumbled upon a cleaner approach in a <a href="http://pure-rspec-scotruby.heroku.com/">presentation</a> (from which I borrowed the examples in this article) by <a href="http://twitter.com/L4rk">Jon Larkowski</a> that makes use of RSpec&#8217;s let() method. With this approach, the example from above looks like:</p>
<pre>
<code>describe BlogPost do
  let(:blog_post) { BlogPost.create :title =&gt; 'Hello' }

  it "does something" do
    blog_post.should ...
  end

  it "does something else" do
    blog_post.should ...
  end
end</code>
</pre>
<p>At first this looked quite magic to me and I had no clue how it worked. Though a look at the source of the let() method reveals the magic (the code should be self-explanatory, or else please leave a comment):</p>
<pre>
<code>def let(name, &amp;block)
  define_method name do
    @assignments ||= {}
    @assignments[name] ||= instance_eval(&amp;block)
  end
end</code>
</pre>
<p>Happy RSpecing!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/04/02/lets-write-slightly-cleaner-specs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 3 and Passenger</title>
		<link>http://cakebaker.42dh.com/2010/01/17/rails-3-and-passenger/</link>
		<comments>http://cakebaker.42dh.com/2010/01/17/rails-3-and-passenger/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 09:46:06 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[configuration]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1333</guid>
		<description><![CDATA[This weekend the RailsBridge people have organized a bugmash with the motto &#8220;Do One Thing for Rails 3&#8243;, and so I took the opportunity to experiment a bit with the coming Rails 3. After following the instructions for creating a new Rails 3 app (using the &#8211;database=mysql parameter for the &#8220;rails&#8221; command) I noticed that [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend the <a href="http://railsbridge.org">RailsBridge</a> people have organized a <a href="http://bugmash.com">bugmash</a> with the motto &#8220;Do One Thing for Rails 3&#8243;, and so I took the opportunity to experiment a bit with the coming Rails 3.</p>
<p>After following the instructions for <a href="http://yehudakatz.com/2009/12/31/spinning-up-a-new-rails-app/">creating a new Rails 3 app</a> (using the &#8211;database=mysql parameter for the &#8220;rails&#8221; command) I noticed that the application tried to access the (not existing) production database. That was a bit strange, because I expected it to access the development database as I set the <a href="http://www.modrails.com/documentation/Users guide.html#rails_env">RailsEnv</a> option of <a href="http://www.modrails.com">Passenger</a> accordingly:</p>
<pre>
<code># for example in /etc/httpd/conf/httpd.conf
RailsEnv development</code>
</pre>
<p>The reason this doesn&#8217;t work is because the generated application contains a &#8220;config.ru&#8221; file. In this case, Passenger treats the application as a <a href="http://rack.rubyforge.org/">Rack</a> application and not as a Rails application. And so the RailsEnv setting is ignored as it is Rails-specific&#8230;</p>
<p>There are two ways to run the application in development mode: you can either remove the &#8220;config.ru&#8221; file (and keep the RailsEnv setting) or you can set the <a href="http://www.modrails.com/documentation/Users guide.html#rack_env">RackEnv</a> option:</p>
<pre>
<code># for example in /etc/httpd/conf/httpd.conf
RackEnv development</code>
</pre>
<p>Have fun with Rails 3 :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2010/01/17/rails-3-and-passenger/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Accepting the Google OpenID with PHP OpenID</title>
		<link>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/</link>
		<comments>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 16:45:04 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1322</guid>
		<description><![CDATA[If you are using the PHP OpenID library (which is also used by my OpenID component for CakePHP), it is possible that you get an &#8220;Invalid OpenID&#8221; error when you try to login with the Google OpenID (https://www.google.com/accounts/o8/id), or any other OpenID that uses &#8220;https&#8221;. In this case, the following steps might help to fix [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using the <a href="http://openidenabled.com/php-openid/">PHP OpenID library</a> (which is also used by my <a href="http://code.42dh.com/openid/">OpenID component</a> for CakePHP), it is possible that you get an &#8220;Invalid OpenID&#8221; error when you try to login with the Google OpenID (https://www.google.com/accounts/o8/id), or any other OpenID that uses &#8220;https&#8221;.</p>
<p>In this case, the following steps might help to fix this issue:</p>
<ul>
<li>Ensure you have Curl and OpenSSL installed</li>
<li>Enable the Curl and OpenSSL extensions in your php.ini (on Archlinux this file is found in /etc/php/):
<pre>
<code>extension=curl.so
extension=openssl.so</code>
</pre>
</li>
<li>Restart your web server</li>
</ul>
<p>Now the error message should disappear and you should be able to log in with the Google OpenID. </p>
<p>&#8212;-</p>
<p>That&#8217;s it for 2009. It was a rather lazy year on this blog from my side (I didn&#8217;t even manage to do a redesign&#8230;), and so I hope I will be a bit less lazy with writing on this blog in 2010.</p>
<p>Anyway, thank you for reading this blog, and for all your comments and emails. A Happy New Year everyone &#038; cu in 2010 :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/12/31/accepting-the-google-openid-with-php-openid/feed/</wfw:commentRss>
		<slash:comments>6</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>
	</channel>
</rss>
