<?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/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Will Norris &#187; wordpress</title>
	<atom:link href="http://willnorris.com/tag/wordpress/feed" rel="self" type="application/rss+xml" />
	<link>http://willnorris.com</link>
	<description>Thoughts on Identity, OpenID, WordPress, and Life</description>
	<lastBuildDate>Tue, 26 Jan 2010 16:25:05 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
		<item>
		<title>OpenID and WordPress Core</title>
		<link>http://willnorris.com/2009/09/openid-and-wordpress-core</link>
		<comments>http://willnorris.com/2009/09/openid-and-wordpress-core#comments</comments>
		<pubDate>Tue, 29 Sep 2009 20:17:19 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-openid]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=878</guid>
		<description><![CDATA[This was actually a comment I left on my last post about the v3.3 release of the OpenID plugin.  It is a topic that comes up relatively often, and one in which most people are surprised when they hear my stance on it.  It&#8217;s worthy of a separate discussion for those that are [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/09/wordpress-openid-v3-3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.3'>WordPress OpenID v3.3</a></li>
<li><a href='http://willnorris.com/2007/09/wordpress-openid-20-coming-soon' rel='bookmark' title='Permanent Link: WordPress OpenID 2.0 (coming soon?)'>WordPress OpenID 2.0 (coming soon?)</a></li>
<li><a href='http://willnorris.com/2008/05/changes-to-wp-openid' rel='bookmark' title='Permanent Link: Changes to wp-openid'>Changes to wp-openid</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p><em>This was actually <a href="http://willnorris.com/2009/09/wordpress-openid-v3-3#comment-35595">a comment</a> I left on my last post about the v3.3 release of the OpenID plugin.  It is a topic that comes up relatively often, and one in which most people are surprised when they hear my stance on it.  It&#8217;s worthy of a separate discussion for those that are interested, so I&#8217;ve pulled it out into a separate post.</em></p>

<p>I’ve talked with core team about this numerous times… in fact, I spoke at <a href="http://wordcampportland.org/">WordCamp Portland</a> and <a href="http://wordcampseattle.com/">Seattle</a> these last two weeks and talked with <a href="http://ma.tt/">Matt</a> about it. For the most part, I actually agree with him that OpenID doesn’t necessarily belong in core, at least not yet.</p>

<p>There’s a lot of thought being given to how WordPress can serve as your “digital hub” on the web. Right now, Automattic is playing in that space in the form of <a href="http://buddypress.org/">BuddyPress</a>. Now right now, BP allows you to create another social network silo. BP installations don’t talk to each other, and there’s no way to use your account on one BP network to login to a different BP network. I talked with <a href="http://markjaquith.com/">Mark Jaquith</a> this weekend about my desire to see this outward facing functionality. For that, I think OpenID becomes painfully obvious.</p>

<p>I would also like to see this OpenID plugin deployed on WordPress.com to replace the existing plugin. Currently, <a href="http://support.wordpress.com/settings/openid/">all WP.com blogs are OpenIDs</a>, but you can’t login or leave comments using an external OpenID. And currently, almost no one uses the existing OpenID provider. Of course, I would argue that this is because they haven’t done a good job of promoting it or adding any new features like SReg or AX. Using my OpenID plugin would greatly enhance the OpenID provider functionality on WP.com, and it would allow people to use OpenID when leaving comments. Some of the changes that are included in 3.3 are actually steps toward cleaning up the plugin so that it is more suitable for deploying on WordPress.com. There’s still more work to be done on this front, but it’s something I intend to continue pursuing.</p>

<p>As for inclusion in WordPress core, I just don’t think we’re there yet. The OpenID plugin is <a href="http://wordpress.org/extend/plugins/openid/stats/">pretty popular</a>, but it is far from having the critical mass that would justify inclusion in core. I am a firm believer that WordPress should by no means try and include every cool feature under the sun in core. It would quickly grow out of control. I do believe, however, that the appropriate hooks should be provided in core to allow any cool feature under the sun to be added as a plugin. The core dev team agrees with me on this, and they’ve been very good about making whatever changes were necessary to allow plugins to provide that functionality. In fact, I overhauled how the <a href="http://willnorris.com/2009/03/authentication-in-wordpress-28">authentication system</a> is extended in WordPress 2.8 simply to make things like OpenID and OAuth much easier to implement.</p>

<p>A few other things I’d want to see fixed before considering inclusion in core… the OpenID plugin weighs in at what? almost 900K? Remove the screenshots and readme.txt and you’ve got 700K left. Over 500K of that is the <a href="http://openidenabled.com/php-openid/">JanRain OpenID library</a>. So size is an issue. Also, the biggest problem that people have with getting the plugin to work is related to their environment. WordPress is known for having a very minimal set of requirements to get it running. I’d really want to track down and fix a lot of these weird environment issues that continue to plague the plugin. Finally, we need a <strong>really</strong> solid UI, both comment form integration and the admin side. I’m pretty happy with the new comment form integration, but the current admin screens need work. More than anything, there is just a lot of functionality in the plugin and it’s hard to boil it down. Especially when you consider both the OpenID consumer and provider options, both site-wide and per-user.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/09/wordpress-openid-v3-3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.3'>WordPress OpenID v3.3</a></li>
<li><a href='http://willnorris.com/2007/09/wordpress-openid-20-coming-soon' rel='bookmark' title='Permanent Link: WordPress OpenID 2.0 (coming soon?)'>WordPress OpenID 2.0 (coming soon?)</a></li>
<li><a href='http://willnorris.com/2008/05/changes-to-wp-openid' rel='bookmark' title='Permanent Link: Changes to wp-openid'>Changes to wp-openid</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/09/openid-and-wordpress-core/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>WordPress OpenID v3.3</title>
		<link>http://willnorris.com/2009/09/wordpress-openid-v3-3</link>
		<comments>http://willnorris.com/2009/09/wordpress-openid-v3-3#comments</comments>
		<pubDate>Mon, 28 Sep 2009 20:04:15 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-openid]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=876</guid>
		<description><![CDATA[I&#8217;ve finally gone ahead and released version 3.3 of the WordPress OpenID plugin.  This release includes three major sets of changes.  First, it drops support for older versions of WordPress&#8230; the minimum required version is now 2.8.  Trying to maintain backwards compatibility requires a non-trivial amount of effort, and I&#8217;d rather spend [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2008/10/wordpress-openid-v3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.0'>WordPress OpenID v3.0</a></li>
<li><a href='http://willnorris.com/2009/09/openid-and-wordpress-core' rel='bookmark' title='Permanent Link: OpenID and WordPress Core'>OpenID and WordPress Core</a></li>
<li><a href='http://willnorris.com/2007/09/wordpress-openid-20-coming-soon' rel='bookmark' title='Permanent Link: WordPress OpenID 2.0 (coming soon?)'>WordPress OpenID 2.0 (coming soon?)</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finally gone ahead and released version 3.3 of the <a href="http://wordpress.org/extend/plugins/openid">WordPress OpenID plugin</a>.  This release includes three major sets of changes.  First, it drops support for older versions of WordPress&#8230; the minimum required version is now 2.8.  Trying to maintain backwards compatibility requires a non-trivial amount of effort, and I&#8217;d rather spend that time working on new features.  It also cleans up the code a fair bit, which I always like.  It also drops support for two experimental OpenID extensions known as <a href="http://eaut.org/">EAUT</a> and <a href="http://code.google.com/p/idib/">IDIB</a>.  EAUT is effectively being replaced by <a href="http://code.google.com/p/webfinger/">WebFinger</a>, and IDIB never got too much traction.  Either could still be added pretty simply by another plugin if people still want them.</p>

<p>Second, this release features a new user interface for the integrating OpenID into the WordPress comment form.  Instead of simply advertising OpenID support on the &#8220;Website&#8221; field, and <strong>always</strong> attempting OpenID authentication, the plugin now detects OpenID support for a URL, and gives the user the option to authenticate the comment.  This provides a cleaner, less obtrusive interface that should work on most all themes.  It also gives the user the option to <strong>not</strong> authentication that particular comment if they don&#8217;t want (particularly useful if you&#8217;re on a mobile device or in a hurry and don&#8217;t want to mess with OpenID).  Feel free to try it out on this post if want.  You really don&#8217;t even have to submit the comment to see it in action&#8230; just enter a valid OpenID URL for the website field, and move focus somewhere else (ie, click in the comment box like you&#8217;re going to type a comment).  There is currently no option to revert to the old style of comment form integration, so hopefully folks will like this new UI.  If you really don&#8217;t like it, you always have the option of turning off comment form integration and modifying your theme to your heart&#8217;s content.</p>

<p>Finally, this release includes a lot of minor bug fixes that people have been complaining about (sorry it took so long).  I&#8217;m sure I didn&#8217;t get to all of them, so please let me know what I missed, and I&#8217;ll try to do more regular minor releases with these smaller fixes.</p>

<p>I&#8217;ll additionally note that working on WordPress plugins is no longer part of my day job, so I currently work on them rather sporadically as I have time.  The changes in this release have been developed a few hours at a time over the last couple of months.  I&#8217;ve been running trunk here on my site for quite some time and haven&#8217;t had problems, but you never know.  Please use the <a href="http://code.google.com/p/diso/issues">DiSo issue tracker</a> to report any new bugs, or to remind me of existing tickets that are still not fixed in this release.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2008/10/wordpress-openid-v3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.0'>WordPress OpenID v3.0</a></li>
<li><a href='http://willnorris.com/2009/09/openid-and-wordpress-core' rel='bookmark' title='Permanent Link: OpenID and WordPress Core'>OpenID and WordPress Core</a></li>
<li><a href='http://willnorris.com/2007/09/wordpress-openid-20-coming-soon' rel='bookmark' title='Permanent Link: WordPress OpenID 2.0 (coming soon?)'>WordPress OpenID 2.0 (coming soon?)</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/09/wordpress-openid-v3-3/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>WordPress Plugin Pet Peeve #3: Not being extensible</title>
		<link>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible</link>
		<comments>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible#comments</comments>
		<pubDate>Thu, 04 Jun 2009 15:53:25 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[pet-peeve]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=671</guid>
		<description><![CDATA[So this is one that is incredibly easy to implement, and yet goes a really long way in keeping people happy with your plugin.  The very reason that WordPress has a plugin API is because they know that different people want different things from their blog.  Some people are satisfied with just the [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files'>WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files</a></li>
<li><a href='http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #1: Hardcoding wp-content'>WordPress Plugin Pet Peeve #1: Hardcoding wp-content</a></li>
<li><a href='http://willnorris.com/2007/11/new-wordpress-plugin-fullfeed' rel='bookmark' title='Permanent Link: New WordPress plugin - FullFeed'>New WordPress plugin - FullFeed</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>So this is one that is incredibly easy to implement, and yet goes a <strong>really</strong> long way in keeping people happy with your plugin.  The very reason that WordPress has a <a href="http://codex.wordpress.org/Plugin_API">plugin API</a> is because they know that different people want different things from their blog.  Some people are satisfied with just the core functionality that WordPress provides, but most people want a little more.  Perhaps they are using WordPress as a photo blog, and need better support for handling that kind of data.  Perhaps they need WordPress to integrate with some other system, or pull in data from elsewhere.  Whatever their needs, there is no possible way WordPress could address them all in the core package.  And even if they were to try, people have different ideas on how the same feature should be implemented, so there would be no way to please everyone.  And unless your plugin is very simple, I can pretty well assure you that some of your users probably want it to do something more than it does today, or do it in a slightly different way.</p>

<p>The very same mechanisms that makes WordPress extensible can be used to make your plugin extensible as well.  Most of the time this will mean action and filter hooks.  As a plugin author, you are no doubt familiar with how these hooks work, since your plugin is using them to hook into WordPress.  But what some newer developers may not realize is just how easy it is to provide your own hooks to extend the functionality of your plugin.</p>

<p><span id="more-671"></span></p>

<h2>Where to add hooks</h2>

<p>When you&#8217;re getting started with your plugin it may not be obvious where to add hooks, and that&#8217;s okay.  If you already have a number of people using your plugin, then perhaps you may have already received requests from people wanting to add some kind of functionality to the plugin or change how something works.  Oftentimes these changes are appropriate to add directly into your plugin, and you are most certainly encouraged to do so when it makes sense.  But sometimes the request represents an edge-case&#8230; something that one individual is wanting to do, but is very likely <em>not</em> going to be useful to most people using your plugin.  Even worse, making such a change may be confusing or even undesirable by other users.  In these cases, see if you can provide the appropriate hooks to allow people to extend your plugin to suit their needs.</p>

<p><a href="http://wordpress.org/extend/plugins/extended-profile/">Extended Profile</a> is a good example which provides quite a few hooks for people to extend.  One of the core features of the plugin is that it allows you to output an hCard Profile on a page, like I have on the front page of <a href="http://willnorris.com/">willnorris.com</a>.  The plugin provides most of the common hCard attributes that we thought an individual might be interested in like name, website, address, telephone number, etc. To collect this data from the user, the plugin extends the standard WordPress Profile administration page.  But we knew that users might already have a different plugin capable of providing this data, or that they may want to pull the data form some other source. Additionally, the <a href="http://microformats.org/wiki/hCard">hCard microformat</a> supports a number of other attributes that we didn&#8217;t include in the plugin.  In order to support these use-cases, we used a combination of action and filter hooks (mostly filters, in our case) to allow the hCard profile to be supplemented, or outright replaced. This is actually how I added the &#8220;Last Seen&#8221; geo data to my hCard, which pulls data from <a href="http://brightkite.com/">Brightkite</a>.</p>

<p>As a general rule of thumb, action hooks are used to alert other plugins that you are at a particular point within a process.  Perhaps that you&#8217;re about to begin doing something, or that you&#8217;ve just finished doing something which other code may care about.  If you&#8217;re printing things to the screen, an action hook may be a good place to allow other plugins to print things as well at a very particular point in your plugin&#8217;s processing.</p>

<p>Filters are intended to allow other pieces of code to actually modify something that your plugin has done.  As mentioned above, the Extended Profile plugin makes heavy use of filters to allow other plugins to modify various aspects of the generated hCard before it is printed to the screen.  In fact, the plugin hooks into its own filters in order to provide most of the functionality, just like any other plugin would.</p>

<p>That last point is worth underscoring: <strong>hooks are not just for other plugins to use, you should be using them yourself</strong>.  WordPress makes extensive use of its own actions and filters, just take a look at <a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/default-filters.php">default-filters.php</a>.  This has a number of benefits &#8212; it allows you to keep your own code fairly clean and modular, but perhaps more importantly it allows other plugins to actually <em>remove</em> functionality they don&#8217;t want using the <code>remove_action</code> and <code>remove_filter</code> methods. When it comes to making your plugin extensible, being able to remove functionality is just as important as the ability to add it.</p>

<h2>How to add hooks</h2>

<p>Adding new action or filter hooks is deceptively simple &#8212; there is no registration of hooks, you simply call <code>do_action</code> or <code>apply_filters</code> as needed.  A simplified version of what happens in the Extended Profile plugin might look like this:</p>

<pre><code>function get_extended_profile($user_id) {
    // start output buffering
    ob_start();

    // call the action hook which actually builds the profile
    do_action('extended_profile', $user_id);

    // get buffered content
    $profile = '&lt;div id="profile"&gt;' . ob_get_contents() . '&lt;/div&gt;';
    ob_end_clean();

    // filter everything before returning
    return apply_filters('post_extended_profile', $profile, $user_id);
}
</code></pre>

<p>Here you can see both a custom action and filter being used, first to build the profile and then to filter it.  When adding hooks to your plugin, its important to think about what data those hook functions may need in order to do something useful.  For example, functions which hook into the &#8216;extended&#95;profile&#8217; action need to know the ID of the user the profile is being built for so that they can fetch the appropriate data.  The same user ID is also passed to the &#8216;post&#95;extended&#95;profile&#8217; filter for the same reason.  With filters it&#8217;s important to remember that only the first parameter passed into the hooking functions gets filtered.  You can certainly pass other data as well to provide context, but only the first one is filtered (which is actually the second parameter passed to <code>apply_filters</code>, since the first one is the filter name).</p>

<p>The real beauty of WordPress action and filter hooks is in how lightweight the entire system is.  Calling a hook that has no registered functions returns almost immediately.  And registering a function to a non-existent hook has basically no overhead, and absolutely no consequence&#8230; the function simply never gets executed.  While you should certainly think through your plugin and add hooks at the logical points, don&#8217;t worry too much about adding too many.  Consider this: on a standard, out of the box WordPress installation with no plugins activated, a page load can easily cause over 1,000 calls to <code>do_action</code> and <code>apply_filter</code>.  Having your plugin add in a handful more is not going to have any kind of adverse effect on WordPress performance, and you will potentially make your plugin users much happier.</p>

<h2>Custom Constants</h2>

<p>Another way to expose additional functionality within your plugin is through the use of custom constants.  This is generally most appropriate to enable advanced functionality that you don&#8217;t want to expose through the normal WordPress option pages.  For example, suppose you have a plugin which makes API calls to some service.  The URL for that API endpoint is constant, but you might want to allow it to be overridden for testing purposes.  Use a PHP constant for your API URL, but check to see if it is already defined:</p>

<pre><code>// near the beginning of your plugin
if ( !defined('MY_PLUGIN_API_URL') ) {
    define('MY_PLUGIN_API_URL', 'http://api.example.com/service'); // default value
}

// throughout the rest of your plugin, always use the constant
file_get_contents( MY_PLUGIN_API_URL . '?user=joe' );
</code></pre>

<p>In this way, the API URL can be overridden by defining the constant in <code>wp-config.php</code>:</p>

<pre><code>define('MY_PLUGIN_API_URL', 'http://testing.example.net/test-service');
</code></pre>

<p>This is not as common as using action and filter hooks, but is still useful especially when you want to ensure that other plugins are not able to manipulate the value.  Unless you do some additional checking, you never know what functions may be hooking into your filter or what they&#8217;re going to do with the value&#8230; in fact that&#8217;s kind of the point, you&#8217;re not supposed to know or care.  But in cases where you want to allow the user to define a custom value, but also ensure that other plugins don&#8217;t manipulate the data in any way, constants are the way to go.</p>

<p>A final note if you do end up adding hooks or constants to your plugin.  Because so many plugins <strong>aren&#8217;t</strong> able to be extended in these ways, it is well worth drawing attention to the fact in your plugin&#8217;s readme.txt.  You can even go so far as to document all of the extension points as I did <a href="http://wiki.diso-project.org/wordpress-openid-api">with the OpenID plugin</a>, but you don&#8217;t necessarily have to.  Just pointing out that hooks exist is often enough, developers can quickly scan your code for them.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files'>WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files</a></li>
<li><a href='http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #1: Hardcoding wp-content'>WordPress Plugin Pet Peeve #1: Hardcoding wp-content</a></li>
<li><a href='http://willnorris.com/2007/11/new-wordpress-plugin-fullfeed' rel='bookmark' title='Permanent Link: New WordPress plugin - FullFeed'>New WordPress plugin - FullFeed</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files</title>
		<link>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files</link>
		<comments>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files#comments</comments>
		<pubDate>Tue, 02 Jun 2009 20:05:45 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[pet-peeve]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=637</guid>
		<description><![CDATA[This is actually very similar to my first pet peeve of hardcoding the path to wp-content, in that it makes assumptions about where files are placed on the filesystem.  Oftentimes, plugins need to handle certain kinds of requests, maybe for some specific protocol, or to handle an AJAX request.  Some plugins will do [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #1: Hardcoding wp-content'>WordPress Plugin Pet Peeve #1: Hardcoding wp-content</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2007/11/new-wordpress-plugin-fullfeed' rel='bookmark' title='Permanent Link: New WordPress plugin - FullFeed'>New WordPress plugin - FullFeed</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>This is actually very similar to my first pet peeve of <a href="http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content">hardcoding the path to wp-content</a>, in that it makes assumptions about where files are placed on the filesystem.  Oftentimes, plugins need to handle certain kinds of requests, maybe for some specific protocol, or to handle an AJAX request.  Some plugins will do this by making an HTTP request directly to one of the files in the plugin&#8230; something like:</p>

<pre><code>echo '&lt;script type="text/javascript"&gt;
    jQuery.get("' . plugins_url('my-plugin/ajax-handler.php') . '");
    // do something with AJAX data ...
&lt;/script&gt;';
</code></pre>

<p>This is not a problem in and of itself, in fact it&#8217;s great that the plugin developer is actually using the <code>plugins_url</code> function!  The problem arises in the <code>my-plugin/ajax-handler.php</code> file itself.  <span id="more-637"></span> If that plugin needs to make use of any WordPress data or functions, then the developer is certain to do something very ugly.  You&#8217;ll know it when you see it:</p>

<pre><code>require_once('../../../wp-load.php');

// or sometimes you'll see...
require_once('../../../wp-config.php');
</code></pre>

<p>So what is this, and why is it so bad?  Well, the <code>wp-load.php</code> is a file provided by WordPress core that bootstraps the WordPress environment.  It loads in the <code>wp-config.php</code> file, loads all the common WordPress functions and classes, initializes the database connection, and gets everything in place to process the request.  These are all important things, and provides a lot of functionality that the plugin developer may need.  The problem is that in the <code>require_once</code> call above, the plugin developer is assuming that the <code>wp-load.php</code> file is in a directory exactly three levels up in the filesystem from their plugin directory.  In a standard WordPress deployment, this will be true and everything will work fine (for the most part).  But <a href="http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content">as we&#8217;ve already seen</a>, WordPress allows deployers to move where their <code>wp-content</code> or their plugins directory lives, so the above code will break completely.  Yes, there are files in WordPress core that do something similar to the above, for example <code>wp-admin/admin.php</code>.  But these are safe for WordPress core files because they <strong>do</strong> know where certain files will be.  It is <strong>never</strong> safe to make this assumption from a plugin.  I think it&#8217;s pretty safe to say that if you have a <code>require</code> or <code>include</code> call that goes up more than a couple of directories (&#8220;<code>../../</code>&#8221;), you&#8217;re almost certainly doing it wrong.</p>

<p>A couple of points to emphasize before moving on: if your plugin files are <strong>not</strong> accessing any built-in WordPress functions, classes, or data, calling them directly should be just fine.  Also, if you&#8217;re doing <a href="http://codex.wordpress.org/AJAX_in_Plugins#Ajax_on_the_Administration_Side">AJAX calls on admin pages</a>, use the built-in functionality WordPress core provides.</p>

<h3>The Right Way</h3>

<p>So the right way of doing this is actually pretty straightforward conceptually, but in practice there are a couple of ways to do it depending on your needs.  The short answer is that instead of calling your plugin file directly, you must send the request through the standard WordPress request handling mechanisms.  This requires two things: constructing your request properly, and then hooking into the WordPress request handling code at the appropriate time to take over the request handling yourself.</p>

<p>All standard WordPress requests eventually get broken down to a request to <code>/index.php</code> with a bunch of URL parameters.  For example, when someone goes to your blog post at</p>

<pre><code>http://example.com/2009/01/hello-world
</code></pre>

<p>WordPress uses the configured permalink structure to break this down to</p>

<pre><code>http://example.com/index.php?year=2008&amp;monthnum=01&amp;name=hello-world
</code></pre>

<p>And from that, WordPress can determine which post the request is for, and serve that up accordingly.  So what we want to do is be able to construct a request along the lines of</p>

<pre><code>http://example.com/index.php?my-plugin=ajax-handler
</code></pre>

<p>and then hook into the WordPress request handling logic so that we can process this request ourselves.  Fortunately, WordPress provides an action hook for exactly that purpose, called <code>process_request</code>.  Functions that hook into this action are passed one parameter, an instance of the <code>WP</code> class, which encapsulates most of the specific parameters for the current request.  If we want to process only the requests which include <code>my-plugin=ajax-handler</code>, we would add something like this to the plugin:</p>

<pre><code>function my_plugin_parse_request($wp) {
    // only process requests with "my-plugin=ajax-handler"
    if (array_key_exists('my-plugin', $wp-&gt;query_vars) 
            &amp;&amp; $wp-&gt;query_vars['my-plugin'] == 'ajax-handler') {

        // process the request.
        // For now, we'll just call wp_die, so we know it got processed
        wp_die('my-plugin ajax-handler!');
    }
}
add_action('parse_request', 'my_plugin_parse_request');
</code></pre>

<p>If you&#8217;re following along at home, try accessing <code>http://example.com/index.php?my-plugin=ajax-handler</code>.  What happens?  Most likely, nothing at all&#8230; it still loads your normal blog index page.  So what went wrong?  In order to have the WordPress request handling code process custom URL parameters, we have to register them.  This is necessary for a number of reasons including security, performance, and also to ensure that WordPress doesn&#8217;t accidentally process something it wasn&#8217;t meant to.  Fortunately, registering a new query variable is very simple using the <code>query_vars</code> filter hook:</p>

<pre><code>function my_plugin_query_vars($vars) {
    $vars[] = 'my-plugin';
    return $vars;
}
add_filter('query_vars', 'my_plugin_query_vars');
</code></pre>

<p>This simply registers &#8216;my-plugin&#8217; as a valid query variable to be processed by WordPress, but says nothing about valid values for that variable.  So now try reloading the page, and you should be greeted with a simple styled page reading &#8220;my-plugin ajax-handler!&#8221;.  Now you just need to modify the <code>my_plugin_parse_request</code> function to actually do your custom request logic, and you&#8217;re good to go.</p>

<p>I mentioned earlier that there are a couple of ways to do this.  The one caveat to be aware of with the above approach is that you are hooking into the WordPress request processing logic <strong>before</strong> WordPress has processed the query itself.  WordPress&#8217;s query handling logic is responsible for examining the request and figuring out what page or post within WordPress the request maps to.  This is also what makes the <code>is_*</code> functions work: <code>is_page</code>, <code>is_front_page</code>, <code>is_feed</code>, etc.  If your plugin is actually doing things on normal WordPress page requests and needs access to these functions, then instead of hooking into the <code>parse_request</code> action, you should use the <code>wp</code> action.  You are still passed an instance of the <code>WP</code> class, so all you need to modify is the <code>add_action</code> call:</p>

<pre><code>add_action('wp', 'my_plugin_parse_request');
</code></pre>

<p>I would recommend that you <strong>not</strong> make this change unless you know that you need to.  Otherwise, you&#8217;re having WordPress perform a lot of logic that isn&#8217;t necessary (including hits against the database), potentially making the request take longer than it needs to be.  Though the difference is likely to be imperceptible, it&#8217;s just good practice to keep things as fast as possible.  And when dealing with custom request handling, you can keep things fast by hooking into as soon in the flow as possible.</p>

<h3>Additional Exercise for the reader</h3>

<p>If you don&#8217;t like the look of URL containing <code>index.php?my-plugin=ajax-handler</code>, and instead want something pretty like</p>

<pre><code>http://example.com/my-plugin/ajax-handler
</code></pre>

<p>that is certainly possible with just a little bit more work (see <a href="http://codex.wordpress.org/Function_Reference/WP_Rewrite">WP_Rewrite</a>).  The <a href="http://wordpress.org/extend/plugins/openid/">WordPress OpenID Plugin</a> does this to achieve nice endpoint URLs for the OpenID authentication protocol.  A word of caution with this however: if you want to make sure that your plugin works on the widest number of deployments, where you have no idea what their permalink structure is going to be, there is a bit more work that is necessary.  You can see the rewrite rules I setup for the OpenID plugin in the <a href="http://code.google.com/p/diso/source/browse/wordpress/openid/trunk/common.php">common.php</a> file.  There&#8217;s a lot of other stuff in there, and the rewrite code is a little confusing at parts, but it&#8217;s all there.  I will actually be changing this in the future to simplify things a bit, so avoid complicating matters unless there is a real reason to.</p>

<p>Further codex reading:</p>

<ul>
<li><a href="http://codex.wordpress.org/Query_Overview">http://codex.wordpress.org/Query_Overview</a></li>
<li><a href="http://codex.wordpress.org/Custom_Queries">http://codex.wordpress.org/Custom_Queries</a></li>
</ul>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #1: Hardcoding wp-content'>WordPress Plugin Pet Peeve #1: Hardcoding wp-content</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2007/11/new-wordpress-plugin-fullfeed' rel='bookmark' title='Permanent Link: New WordPress plugin - FullFeed'>New WordPress plugin - FullFeed</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>WordPress Plugin Pet Peeve #1: Hardcoding wp-content</title>
		<link>http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content</link>
		<comments>http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content#comments</comments>
		<pubDate>Sat, 23 May 2009 22:50:31 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[pet-peeve]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=618</guid>
		<description><![CDATA[Perhaps my biggest pet peeves I run across with WordPress plugins is when developers hardcode the URL or path to the WordPress content folder.  By default this folder is named &#8216;wp-content&#8217;, and resides at the root of the primary WordPress folder.  However, since WordPress 2.6 (released July 2008), this location can be moved [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files'>WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files</a></li>
<li><a href='http://willnorris.com/2008/09/wordpress-mu-in-a-development-environment' rel='bookmark' title='Permanent Link: WordPress MU in a development environment'>WordPress MU in a development environment</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Perhaps my biggest pet peeves I run across with WordPress plugins is when developers hardcode the URL or path to the WordPress content folder.  By default this folder is named &#8216;wp-content&#8217;, and resides at the root of the primary WordPress folder.  However, since WordPress 2.6 (released July 2008), this location <a href="http://codex.wordpress.org/Editing_wp-config.php#Moving_wp-content">can be moved</a> by simply defining a constant in <code>wp-config.php</code>.  That&#8217;s precisely what I do on my website: my WordPress installation lives at <a href="http://willnorris.com/wordpress/">/wordpress</a>, while my content folder is at <a href="http://willnorris.com/wordpress-content/">/wordpress-content</a>.  I like having this separation of core WordPress files from the themes, plugins, and uploads I&#8217;ve added myself.  It also makes it easier for me to upgrade WordPress, since I don&#8217;t use the built-in upgrade system added in 2.7.  Any plugins that still hardcode the path of the <code>wp-content</code> folder break in often spectacular ways on my site.</p>

<p>So what should plugins do instead?  In order to make moving your content folder possible, WordPress 2.6 added a number of constants and functions which refer to the correct location of several often used folders.  <span id="more-618"></span> So instead of including an image using something like:</p>

<pre><code>&lt;img src="&lt;?php bloginfo('wpurl') ?&gt;/wp-content/plugins/my-plugin/images/logo.png" /&gt;
</code></pre>

<p>you would have:</p>

<pre><code>&lt;img src="&lt;?php echo WP_PLUGIN_URL ?&gt;/my-plugin/images/logo.png" /&gt;
</code></pre>

<p>or even better:</p>

<pre><code>&lt;img src="&lt;?php echo plugins_url('my-plugin/images/logo.png') ?&gt;" /&gt;
</code></pre>

<p>Since these constants were added in WordPress 2.6, they obviously won&#8217;t work in earlier versions.  No problem, you can define them yourself in your plugin.  The WordPress Codex page <a href="http://codex.wordpress.org/Determining_Plugin_and_Content_Directories">Determining Plugin and Content Directories</a> includes 8 lines of code (plus 1 comment) that you can add to your plugin to ensure these constants are set, even in older versions of WordPress:</p>

<pre><code>// Pre-2.6 compatibility
if ( ! defined( 'WP_CONTENT_URL' ) )
    define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
if ( ! defined( 'WP_CONTENT_DIR' ) )
    define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( ! defined( 'WP_PLUGIN_URL' ) )
    define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
    define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
</code></pre>

<p>Everywhere else in your plugin, make sure that you use the constants, not the hardcoded path.  If the string &#8216;wp-content&#8217; appears anywhere in your plugin that isn&#8217;t defining one of the constants above, you&#8217;re doing it wrong.  If you also want to make sure the functions like <code>plugins_url</code> are available in older versions of WordPress, see the <a href="http://code.google.com/p/diso/source/browse/wordpress/openid/trunk/compatibility.php">compatibility.php</a> file the ships with the <a href="http://wordpress.org/extend/plugins/openid/">WordPress OpenID Plugin</a>.</p>

<p>So plugin authors, please go and fix this in your plugins.  Please?  Otherwise I can&#8217;t use your plugin at all on my site.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files'>WordPress Plugin Pet Peeve #2: Direct Calls to Plugin Files</a></li>
<li><a href='http://willnorris.com/2008/09/wordpress-mu-in-a-development-environment' rel='bookmark' title='Permanent Link: WordPress MU in a development environment'>WordPress MU in a development environment</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/05/wordpress-plugin-pet-peeve-hardcoding-wp-content/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Authentication in WordPress 2.8</title>
		<link>http://willnorris.com/2009/03/authentication-in-wordpress-28</link>
		<comments>http://willnorris.com/2009/03/authentication-in-wordpress-28#comments</comments>
		<pubDate>Tue, 10 Mar 2009 20:50:07 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[diso]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xmlrpc]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=508</guid>
		<description><![CDATA[Use Case

I&#8217;ve spent a lot of time working with the WordPress authentication system.  I took over the OpenID plugin for WordPress two years ago, and was hired by Vidoop last May to work on the DiSo Project full time.  Last summer, Matt Mullenweg invited me to talk at WordCamp SF 2008 about OAuth. [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/02/strong-authentication-and-emailing-passwords' rel='bookmark' title='Permanent Link: strong authentication and emailing passwords'>strong authentication and emailing passwords</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2009/09/wordpress-openid-v3-3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.3'>WordPress OpenID v3.3</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<h2>Use Case</h2>

<p>I&#8217;ve spent a <strong>lot</strong> of time working with the WordPress authentication system.  I took over the <a href="http://wordpress.org/extend/plugins/openid/">OpenID plugin</a> for WordPress two years ago, and <a href="http://willnorris.com/2008/05/why-im-going-to-vidoop">was hired by Vidoop</a> last May to work on the <a href="http://diso-project.org/">DiSo Project</a> full time.  Last summer, Matt Mullenweg invited me to talk at <a href="http://2008.sf.wordcamp.org/">WordCamp SF 2008</a> about OAuth.  As you can see in my <a href="http://www.slideshare.net/willnorris/wordpress-oauth-presentation">slidedeck</a>, it was a lot of smoke and mirrors at that point&#8230; we didn&#8217;t have OAuth in WordPress, although it was on the roadmap for 2.7.</p>

<p>We&#8217;ve had an OAuth plugin for a little while that <a href="http://singpolyma.net/">Stephen Paul Weber</a> wrote, but it wasn&#8217;t until a couple of months ago that I finally sat down to polish it up.  The first use-case we wanted to tackled was XML-RPC, so I got to work with <a href="http://josephscott.org/">Joseph Scott</a>.  Having OAuth authentication with XML-RPC would allow for blog clients like MarsEdit or the WordPress iPhone app to communicate with your blog without having to share your WordPress password.</p>

<p><span id="more-508"></span></p>

<h2>Problem</h2>

<p>It wasn&#8217;t very long before we butted up against my biggest complaint about the WordPress authentication system &#8212; it is very &#8220;username/password&#8221; centric.  There are places in the authentication code where it bails out prematurely if the username or password are missing.  This isn&#8217;t a problem if your plugin simply wants to authenticate the user against a different password store like LDAP; in fact that works quite well.</p>

<p>The problem is that there are a number of authentication systems widely deployed in the wild (SAML, OpenID, OAuth, etc) that do not fit the standard model of username and password.  You can look at the OpenID plugin to see some of the more <em>interesting</em> things that need to be done in order to make it work on the various versions of WordPress.  However, when it came to hooking OAuth into the WordPress XML-RPC endpoint, there simply was no way to hack around it&#8230; we had to change some of the underlying assumptions.</p>

<p>It&#8217;s worth noting one additional requirement we had.  Because the <code>wp_authenticate()</code> function, which does most of the heavy lifting for WordPress authentication, resides in <code>pluggable.php</code> it is possible for a plugin to replace the function entirely and authenticate the user however they want.  The problem with this solution is that many authentication mechanisms don&#8217;t know if they should be invoked without examining the request.  If <code>wp_authenticate</code> is replaced, and then the plugin determines it shouldn&#8217;t intervene, then it&#8217;s already too late.  There is no way to pass the function call back to the standard version of <code>wp_authenticate()</code>.  This is actually the case for all functions in <code>pluggable.php</code>.  One possible solution is to create wrapper functions for everything, which I initially <a href="https://core.trac.wordpress.org/ticket/8833">advocated</a>.  Instead, <a href="http://peter.westwood.name/">Peter Westwood</a> came up with a better solution using a well-established model, which we ended up using for the new authentication system.</p>

<h2>Solution</h2>

<p>It took far more planning than actual coding, but we finally developed a solution that breaks the dependence on a username and password, but maintains backward compatibility with existing plugins that hook into the authentication code. WordPress 2.8 includes a new filter called <em>authenticate</em> which is passed three parameters: a mixed value (either a <code>WP_User</code> object, a <code>WP_Error</code> object, or <code>null</code>), along with the username and password (either or both of which may be <code>null</code>).  All of the standard WordPress authentication logic has been moved into two functions that implement this filter, both with relatively low priority.</p>

<ul>
<li><p><code>wp_authenticate_username_password()</code> (priority 20) includes the standard logic for authenticating using a standard username and password.  It still calls the <code>wp_authenticate_user</code> filter, so plugins that rely on that should be fine.  This function also performs the check for an empty username or password.</p></li>
<li><p><code>wp_authenticate_cookie()</code> (priority 30) is only added into the filter chain when the user is authenticating via <code>wp-login.php</code> and does the normal checking for the WordPress authentication cookie.</p></li>
</ul>

<p>Both of these functions first check to see if the first parameter passed in is a valid <code>WP_User</code> object, and immediately stop if it is.  This allows plugins to add their own functions into the filter chain which populate the <code>WP_User</code> object using whatever means they see fit.  WordPress still takes care of setting the authentication cookie when appropriate, so plugins need only worry with authenticating the user and returning a valid <code>WP_User</code> object.</p>

<p>So what will this look like for plugins?  Well, the OAuth plugin for WordPress isn&#8217;t finished yet, but the function below should be pretty close to the final version.  While there is of course a lot more code for actually implementing OAuth, this is the only hook  into the WordPress authentication system needed to make it work.  Note that this function doesn&#8217;t care about the username and password parameters that are available from the <code>authenticate</code> hook&#8230; other plugins may use them.</p>

<pre><code>add_filter('authenticate', 'oauth_authenticate');

/**
 * If the current request was signed using a valid OAuth access token, verify 
 * the request and return the associated user.
 *
 * @param WP_User|WP_Error|null $user authenticated user
 * @return WP_User|WP_Error|null OAuth authenticated user, if request was signed
 */
function oauth_authenticate($user) {
    if (Auth_OAuth_Signer::requestIsSigned()) {
        $oauth_server = oauth_server();
        $user_id = $oauth_server-&gt;verify();
        if ($user_id !== false) {
            $user = new WP_User($user_id);
        }
    }   

    return $user;
}
</code></pre>

<h2>For Plugin Authors</h2>

<p>If you&#8217;re currently hooking into the WordPress authentication system, <strong>especially</strong> if you&#8217;re providing a custom implementation of <code>wp_authenticate()</code>, take a look at the new <code>authenticate</code> hook.  If you are relying on the <code>wp_authenticate</code> action hook, you should also look closely to see if the new hook will do what you need.  We left the <code>wp_authenticate</code> hook in place for now, but I&#8217;m pretty sure it&#8217;s no longer necessary and will likely be removed in future releases.  If you are using the <code>wp_authenticate_user</code> hook exclusively, then you&#8217;re probably fine, but it&#8217;s probably still a good idea to take a look at the new stuff.</p>

<h2>So, OAuth in WordPress?</h2>

<p>We made additional changes to the WordPress XML-RPC code to make it use the new authentication system appropriately, so it is now possible to hook OAuth into WordPress without any core modifications.  We do in fact have a basic <a href="http://diso.googlecode.com/svn/wordpress/oauth/trunk/">OAuth plugin</a> that works with the trunk version of WordPress.  However, I don&#8217;t think I&#8217;m going to push to have the OAuth code included in WordPress 2.8 for two reasons:</p>

<ul>
<li><p>the OAuth libraries are in flux right now.  There have been two main PHP libraries that people have used for OAuth, both with their own strengths and weaknesses.  I&#8217;m currently working with the <a href="http://groups.google.com/group/oauth-php">oauth-php community</a> to combine these libraries  using the best parts from each, and a new clean architecture.  This effort can be found <a href="http://github.com/willnorris/oauth-php/">on github</a>.  (This library also requires PHP5 which is a deal breaker for WordPress&#8230; not sure how we&#8217;ll manage that.)</p></li>
<li><p>Because OAuth has the potential to be such an important part of how third party clients interact with a WordPress blog, I want to make sure we get this right.  Personally, I&#8217;d feel much more comfortable getting some real world experience with this code in a slightly more constrained environment by releasing it as a plugin first.  Once we&#8217;ve done that and are comfortable with how it integrates into WordPress (plugin API, admin interface, database schema, etc), I&#8217;m all for making it a core part of WordPress.</p></li>
</ul>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/02/strong-authentication-and-emailing-passwords' rel='bookmark' title='Permanent Link: strong authentication and emailing passwords'>strong authentication and emailing passwords</a></li>
<li><a href='http://willnorris.com/2009/06/wordpress-plugin-pet-peeve-3-not-being-extensible' rel='bookmark' title='Permanent Link: WordPress Plugin Pet Peeve #3: Not being extensible'>WordPress Plugin Pet Peeve #3: Not being extensible</a></li>
<li><a href='http://willnorris.com/2009/09/wordpress-openid-v3-3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.3'>WordPress OpenID v3.3</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/03/authentication-in-wordpress-28/feed</wfw:commentRss>
		<slash:comments>62</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Challenges in changing my OpenID</title>
		<link>http://willnorris.com/2008/12/challenges-in-changing-my-openid</link>
		<comments>http://willnorris.com/2008/12/challenges-in-changing-my-openid#comments</comments>
		<pubDate>Fri, 19 Dec 2008 22:35:21 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xrd]]></category>
		<category><![CDATA[xrds-simple]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=457</guid>
		<description><![CDATA[I recently decided to combine two personal websites I had (this one, willnorris.com, and will.norris.name) so that I had a single web presence.  I chose to use willnorris.com as my canonical URL, but this presented two problems:


I have been listing will.norris.name as my homepage in my various social networks profiles and on blog comments. [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2008/09/the-next-steps-with-wp-openid' rel='bookmark' title='Permanent Link: The Next Steps with wp-openid'>The Next Steps with wp-openid</a></li>
<li><a href='http://willnorris.com/2007/02/free-your-id' rel='bookmark' title='Permanent Link: Free Your ID'>Free Your ID</a></li>
<li><a href='http://willnorris.com/2007/10/openid-delegation-and-xfn' rel='bookmark' title='Permanent Link: OpenID delegation and XFN'>OpenID delegation and XFN</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>I recently decided to combine two personal websites I had (this one, willnorris.com, and will.norris.name) so that I had a single web presence.  I chose to use willnorris.com as my canonical URL, but this presented two problems:</p>

<ul>
<li><p>I have been listing will.norris.name as my homepage in my various social networks profiles and on blog comments.  I&#8217;ve built up some Google page rank love through these links, and I want to make sure that is transferred over to willnorris.com.  I also want any visitors that go to will.norris.name to be sent over to willnorris.com.  The easiest (and correct) way to accomplish both of these is to setup a simple 301 &#8220;Moved Permanently&#8221; redirect.</p></li>
<li><p>I have also been using will.norris.name as my primary OpenID to login to numerous websites.  Many OpenID consumers will allow you to connect multiple OpenIDs or at least change your OpenID, so I can go through them all and update my account.  But that will take a while, and I&#8217;d like to combine my domains now.  The problem is that if I go ahead and setup a 301 redirect (as mentioned above), then it breaks my ability to use will.norris.name as an OpenID (see #4 under <a href="http://openid.net/specs/openid-authentication-2_0.html#normalization">OpenID Normalization</a>).</p></li>
</ul>

<p>So I want Google and other visitors to see a permanent redirect to willnorris.com, but I don&#8217;t want to break my ability to use will.norris.name as an OpenID.  I was originally planning to use Apache to perform the redirect, and I wasn&#8217;t sure if I&#8217;d actually be able to find a solution to my problem.  Then I started thinking about WordPress request processing, and came up with the following bit of code:</p>

<pre><code>add_action('wp', 'redirect_wp');

function redirect_wp($wp) {
    // only redirect plain home page requests
    if (!is_front_page() &amp;&amp; !is_home()) return;
    if (!empty($_SERVER['QUERY_STRING'])) return;

    // don't redirect OpenID requests
    if (stripos($_SERVER['HTTP_ACCEPT'], 'application/xrds+xml') !== FALSE) return;
    if (stripos($_SERVER['HTTP_USER_AGENT'], 'openid') !== FALSE) return;
    if (empty($_SERVER['HTTP_USER_AGENT'])) return;

    wp_redirect('http://willnorris.com/', 301);
    exit;
}
</code></pre>

<p>So it&#8217;s pretty simple really&#8230; First, we only care about requests to the front page.  Because I was only using will.norris.name as a one-page identity site, not a full blog, I only need to worry with requests to the front page.  If I had been writing blog posts or other pages on this site, I would need to have different logic here.  Second, we do some basic detection for OpenID requests &#8212; things like the content negotiation header for XRDS, or the &#8220;openid&#8221; string that appears in the user agent of JanRain OpenID libraries.  If it doesn&#8217;t look like an OpenID request, we go ahead and redirect to willnorris.com.</p>

<p>Now of course this only works in my specific use case, but perhaps it will prove useful for others.  For what it&#8217;s worth, the new work we&#8217;re doing on <a href="http://groups.google.com/group/metadata-discovery">metadata discovery</a> with XRD would prevent this problem, since we&#8217;re moving away from overloading normal HTTP requests where possible.</p>

<p><strong>Update:</strong> I now also treat an empty user agent string as an OpenID request.  This covers Blogger, which uses the <a href="http://openid4java.org">OpenID4Java</a> library.  I&#8217;m fairly certain all major search engine spiders include a user agent, so this should be a fairly safe addition.</p>

<h3>Additional Note for FastCGI Users</h3>

<p>It&#8217;s worth noting as well that WordPress loses the HTTP status code when using FastCGI, as is used at Joyent.  A <a href="http://trac.wordpress.org/browser/tags/2.7/wp-includes/pluggable.php#L848">comment in the code</a> claims that it causes problems with some FastCGI setups, but I&#8217;ve not experienced that.  This is very important, because Google will not transfer your page rank repuation if only using a 302 &#8220;Moved Temporarily&#8221; redirect; it must be a 301.  A quick fix for this is to add the following to the very beginning of the above code:</p>

<pre><code>add_filter('wp_redirect_status', 
    create_function('$s', 'status_header($s); return $s;'));
</code></pre>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2008/09/the-next-steps-with-wp-openid' rel='bookmark' title='Permanent Link: The Next Steps with wp-openid'>The Next Steps with wp-openid</a></li>
<li><a href='http://willnorris.com/2007/02/free-your-id' rel='bookmark' title='Permanent Link: Free Your ID'>Free Your ID</a></li>
<li><a href='http://willnorris.com/2007/10/openid-delegation-and-xfn' rel='bookmark' title='Permanent Link: OpenID delegation and XFN'>OpenID delegation and XFN</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/12/challenges-in-changing-my-openid/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>WordPress MU in a development environment</title>
		<link>http://willnorris.com/2008/09/wordpress-mu-in-a-development-environment</link>
		<comments>http://willnorris.com/2008/09/wordpress-mu-in-a-development-environment#comments</comments>
		<pubDate>Fri, 19 Sep 2008 05:44:44 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[localhosting]]></category>
		<category><![CDATA[mu]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wpmu]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=311</guid>
		<description><![CDATA[Most of the development I do for my job is within WordPress, so I have quite a few WordPress instances running on my local workstation.  I&#8217;ve been using the same custom Apache setup for three years, and have been developing on WordPress for almost as long, so I&#8217;ve been a bit bewildered with the [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2005/05/dev_environment' rel='bookmark' title='Permanent Link: Setting up a web development environment'>Setting up a web development environment</a></li>
<li><a href='http://willnorris.com/2007/12/wordpress-plugins-development-version' rel='bookmark' title='Permanent Link: WordPress plugins - development version'>WordPress plugins - development version</a></li>
<li><a href='http://willnorris.com/2005/03/bashrc' rel='bookmark' title='Permanent Link: ~/.bashrc'>~/.bashrc</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Most of the development I do for my job is within WordPress, so I have quite a few WordPress instances running on my local workstation.  I&#8217;ve been using the same <a href="http://willnorris.com/2005/05/dev_environment">custom Apache setup</a> for three years, and have been developing on WordPress for almost as long, so I&#8217;ve been a bit bewildered with the amount of trouble I&#8217;ve had the several times I&#8217;ve attempted to get <a href="http://mu.wordpress.org/">WordPress MU</a> running on my laptop.  I identified a couple of specific problems and solutions, which I wanted to outline here.</p>

<p><span id="more-311"></span></p>

<h3>Choosing the right hostname</h3>

<p>Part of my custom setup is that I have a whole slew of bogus hostnames pointing to localhost, which Apache then dynamically maps to the correct document root.  For the most part, I just drop the TLD from the actual hostname&#8230; so <em>http://willnorris/</em> is my locally hosted development site for this blog <em>http://willnorris.com/</em>, and <em>http://will.norris/</em> is my development site for <em>http://will.norris.name/</em>.  I also keep a handful of WordPress versions running locally, so I can test plugins in those different environments &#8212; <em>http://wordpress-2.3/</em>, <em>http://wordpress-2.5/</em>, etc.  When I began to setup my WordPress MU (and <a href="http://buddypress.org/">BuddyPress</a>) instance, I used the site <em>http://wpmu/</em>.  The installation went fine, but when I tried to login it failed every time.  Given that this same setup worked fine with single-user WordPress, I was quite confused.  I quickly realized though, that the authentication cookies were never being set for WPMU&#8230; in fact no cookies were.</p>

<p>The difference between the two versions of WordPress is the value of <code>COOKIE_DOMAIN</code> which is passed to <a href="http://php.net/setcookie">setcookie()</a>.  Both flavors of WordPress allow you to define this constant in <code>wp-config.php</code>, but they differ in what happens if it is not defined there.  WordPress sets it to the boolean false, whereas WordPress MU sets it to <code>'.'.$current_site-&gt;domain</code>.  This results in a different <code>Set-Cookie</code> HTTP header between the two.  Take for example the <code>wordpress_test_cookie</code> cookie.  WordPress sends the response header</p>

<pre><code>Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/
</code></pre>

<p>whereas WordPress MU sends the response header</p>

<pre><code>Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/; domain=.wpmu
</code></pre>

<p>The difference of course is the <code>domain=.wpmu</code> there on the end.  In a production environment, this wouldn&#8217;t make a bit of difference.  But because I&#8217;m using fake hostnames in a development environment, this makes all the difference in the world.  You see, the <a href="http://www.ietf.org/rfc/rfc2109.txt">HTTP Cookie Spec</a> (Section 4.3.2 Rejecting Cookies) requires that the domain attribute includes an &#8220;embedded dot&#8221;.  This is a security feature that prevents a site from setting a cookie on a top level domain like &#8220;.com&#8221;.  Since single-user WordPress wasn&#8217;t specifying a domain attribute, it didn&#8217;t have any problem setting the cookie.  Because my hostname <em>wpmu</em> doesn&#8217;t contain an embedded dot, the browser was properly rejecting the cookies, preventing me from being able to login.  So our solution here was to use the site <em>http://wp.mu/</em> (note the added dot in the middle) for hosting our WordPress MU development site.</p>

<h3>Sending Mail</h3>

<p>The other main problem I had with WordPress MU was that none of the notification emails were being delivered.  This was actually a problem with single-user WordPress as well, but it didn&#8217;t matter as much then.  Now I&#8217;m needing to test the account sign-up process a bit more, and so I need the activation emails that are being sent out.  It&#8217;s been a long time since I&#8217;ve administered an email server, so I won&#8217;t embarrass myself by trying to explain what the problem was (something along the lines of my ISP&#8217;s SMTP server not liking what <a href="http://php.net/mail">mail()</a> was sending) .  I was however able to fix it by writing a very simple plugin, <a href="http://willnorris.com/svn/will.norris.name/trunk/public/wordpress-content/plugins/development-mailer.php">Development Mailer</a>, that changes a few configuration options of PHPMailer.  This works for me on Mac OS X (Leopard), but I make no guarantees for anyone else.  Keep in mind that his plugin should only ever be needed for a development environment&#8230; if you&#8217;re unable to send notification emails from your production blog, then you&#8217;ve got other problems.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2005/05/dev_environment' rel='bookmark' title='Permanent Link: Setting up a web development environment'>Setting up a web development environment</a></li>
<li><a href='http://willnorris.com/2007/12/wordpress-plugins-development-version' rel='bookmark' title='Permanent Link: WordPress plugins - development version'>WordPress plugins - development version</a></li>
<li><a href='http://willnorris.com/2005/03/bashrc' rel='bookmark' title='Permanent Link: ~/.bashrc'>~/.bashrc</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/09/wordpress-mu-in-a-development-environment/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Providing and Delegating OpenIDs</title>
		<link>http://willnorris.com/2008/09/providing-and-delegating-openids</link>
		<comments>http://willnorris.com/2008/09/providing-and-delegating-openids#comments</comments>
		<pubDate>Tue, 16 Sep 2008 21:18:00 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-openid]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=270</guid>
		<description><![CDATA[The next major release of wp-openid includes a built-in OpenID provider and delegation engine.  This will certainly be the most exciting feature of this release for most people, so let me explain a bit how it works.  Each authorized user on the WordPress blog will have an OpenID at the author posts URL [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/10/openid-delegation-and-xfn' rel='bookmark' title='Permanent Link: OpenID delegation and XFN'>OpenID delegation and XFN</a></li>
<li><a href='http://willnorris.com/2007/02/wp-xrds' rel='bookmark' title='Permanent Link: wp-xrds'>wp-xrds</a></li>
<li><a href='http://willnorris.com/2008/10/wordpress-openid-v3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.0'>WordPress OpenID v3.0</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://willnorris.com/2008/09/the-next-steps-with-wp-openid">next major release</a> of wp-openid includes a built-in OpenID provider and delegation engine.  This will certainly be the most exciting feature of this release for most people, so let me explain a bit how it works.  Each authorized user on the WordPress blog will have an OpenID at the author posts URL (ie. http://example.com/author/admin).  Authorization to use the OpenID provider is controlled based on user roles and is managed in the main OpenID settings page.  Each user can choose between one of three options for their OpenID:</p>

<ul>
<li>Don&#8217;t use OpenID at all</li>
<li>Use the local OpenID provider built in to the plugin</li>
<li>Delegate to another OpenID</li>
</ul>

<p><span id="more-270"></span>
If a the local OpenID provider is used, it also supports transmitting sreg attributes pulled from the user&#8217;s WordPress profile and the DiSo Profiles plugin, if it&#8217;s installed.  The user can update this data before releasing it to the relying party, but those changes aren&#8217;t currently stored.  In addition, trust decisions are recorded and stored for the user, and can be modified from their config page at any time.</p>

<p>If a user chooses to delegate to another OpenID, they need only provide the delegate OpenID itself.  All server configuration and supported extensions from that provider are discovered and published in the local XRDS document.  Of course this data will have to be cached and probably updated on some interval, but it makes setting up delegation a breeze.</p>

<h3>Server Modes</h3>

<p>Remember that every user&#8217;s OpenID is their author posts URL.  So what about the home URL for the blog itself?  Well, the OpenID server can operate in two basic modes: <strong>multi-user</strong> and <strong>blog-owner</strong>&#8230; perhaps not the best names, but they&#8217;ll work for now.</p>

<p>In multi-user, the default configuration, the server supports a feature in OpenID 2.0 called <em>OpenID Provider driven identifier selection</em>.  What this means is that ANY user on that blog can enter the home URL as their OpenID, and the OpenID provider itself will make sure that the correct identifier is returned to the relying party.  The final identifier will still be something like <em>http://example.com/author/admin/</em>, but the user only needs to enter <em>example.com</em> at a relying party.  If you&#8217;ve used ever used Yahoo&#8217;s OpenID provider, then you&#8217;ve probably seen how this works.</p>

<p>I suspect the more common mode will be blog-owner, which is appropriate for personal blogs.  Even if there are multiple users in the system, the blog is basically owned by one individual and it makes sense for that individual to use the blog home URL as their OpenID.  This mode is activated by selecting a &#8220;Blog Owner&#8221; on the main plugin configuration page.  Once set, this user&#8217;s personal OpenID configuration (whether turned off, using the local provider, or delegated to another OpenID) will be used at the blog home URL.  Other user&#8217;s on the blog could still use their OpenIDs, but they would need to type in the full URL each time&#8230; they just lose the convenience of being able to use the blog home URL.</p>

<p>For security, once a blog owner is set, no other user can update the setting.  The blog owner can set someone else as the new blog owner (a push mechanism), but no-one can take ownership away (a pull mechanism).  Additionally, if a multi-user blog wants to ensure no-one is ever set as the blog owner, they can add the following to their wp-config.php file:</p>

<pre><code>define("OPENID_DISALLOW_OWNER", 1);
</code></pre>

<h3>What&#8217;s left to do</h3>

<p>The main outstanding work to be done before release is the user interface.  You&#8217;ll notice that the user&#8217;s configuration screen (where they manage their external OpenIDs, OpenID Provider preference, and Trusted Sites) is a bit confusing if you&#8217;re not to familiar with OpenID.  The current layout was done simply for convenience while developing the OpenID Provider, and will be overhauled to some degree before the release.</p>

<p>I&#8217;m also not too sure about compatibility with older versions of PHP and WordPress.  I&#8217;ve been developing using PHP 5.2.6, MySQL 5.0.51, and WordPress 2.6.1.  I do intend to remain as backwards compatible on these as possible (within reason), but make no guarantees for the current development code.  I&#8217;ll also be working to make everything compatible with WordPressMU and BuddyPress.  For now, I just wanted to get the code out there, and get people playing with it a little bit.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/10/openid-delegation-and-xfn' rel='bookmark' title='Permanent Link: OpenID delegation and XFN'>OpenID delegation and XFN</a></li>
<li><a href='http://willnorris.com/2007/02/wp-xrds' rel='bookmark' title='Permanent Link: wp-xrds'>wp-xrds</a></li>
<li><a href='http://willnorris.com/2008/10/wordpress-openid-v3' rel='bookmark' title='Permanent Link: WordPress OpenID v3.0'>WordPress OpenID v3.0</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/09/providing-and-delegating-openids/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>wp-openid - faster, stronger, better</title>
		<link>http://willnorris.com/2008/09/wp-openid-faster-stronger-better</link>
		<comments>http://willnorris.com/2008/09/wp-openid-faster-stronger-better#comments</comments>
		<pubDate>Tue, 16 Sep 2008 21:17:48 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-openid]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=268</guid>
		<description><![CDATA[One of the primary focuses for this next major release of wp-openid is stability.  While most people have had great success with the plugin, there are a fair number that seem to have all kinds of strange problems, ranging from conflicts with other plugins, data corruption, library issues, etc.  In order to reach [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/12/rebuild-wp-openid-tables' rel='bookmark' title='Permanent Link: rebuild wp-openid tables'>rebuild wp-openid tables</a></li>
<li><a href='http://willnorris.com/2007/11/final-push-for-wp-openid-20' rel='bookmark' title='Permanent Link: final push for wp-openid 2.0'>final push for wp-openid 2.0</a></li>
<li><a href='http://willnorris.com/2008/07/wp-openid-220-released' rel='bookmark' title='Permanent Link: wp-openid 2.2.0 released'>wp-openid 2.2.0 released</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>One of the primary focuses for this <a href="http://willnorris.com/2008/09/the-next-steps-with-wp-openid">next major release</a> of wp-openid is stability.  While most people have had great success with the plugin, there are a fair number that seem to have all kinds of strange problems, ranging from conflicts with other plugins, data corruption, library issues, etc.  In order to reach the level of adoption I&#8217;d love to see, we have to make this plugin as easy to install and run as WordPress itself.  This is certainly no easy task, but we&#8217;ve come a very long way.  To this end, you&#8217;ll find the following changes:</p>

<p><span id="more-268"></span></p>

<h3>Simplified Database Structure</h3>

<p>Version 1.0 of wp-openid added four new database tables and overloaded one of the comment table fields in a weird way.  Version 2.0 required only three of those four tables and added one column to the comment table to eliminate the overloaded field.  The current development version doesn&#8217;t add any columns or overload fields of existing tables, and adds only one new table of its own, which I&#8217;m still hoping to eliminate.</p>

<p>The two removed tables were used to store OpenID associations and nonces, both of which are temporary data necessary to make OpenID security actually work.  Instead of using these tables, I&#8217;ve opted to use an updated version of the OpenID store used in Simon Willison&#8217;s <a href="http://wordpress.org/extend/plugins/mu-open-id/">mu-open-id</a> plugin which uses the WordPress options table to store this data.  I&#8217;ve updated his store to use the latest php-openid APIs as well as to reduce the potential for race conditions.</p>

<p>I&#8217;ve removed the column from the comments table that was tracking which comments were left using OpenIDs, and am instead storing this in the postmeta table for the post the comment is associated with.  It would certainly be preferable to have a commentmeta table, but I like this better than the previous solution.</p>

<p>The one remaining table is the identity table which tracks the identity URLs of each user.  I would like to store this in the usermeta table, but because <a href="http://trac.wordpress.org/ticket/7540">it requires unique keys</a> there&#8217;s just not a real clean way to do this and keep the plugin scalable to support large deployments.  If this is fixed in 2.7, we could theoretically eliminate any custom database stuff in the plugin, which I&#8217;d absolutely love.</p>

<h3>Removed PEAR_LOG</h3>

<p>For the time being I&#8217;ve removed PEAR&#95;LOG and am simply using error&#95;log() for what logging still remains.  The problem is that most people weren&#8217;t taking advantage of the logs anyway, so they were just taking up space.  I&#8217;ll likely look at making use of the WP&#95;DEBUG constant to allow more verbose logging when it&#8217;s desired.  For now this just simplifies things a bit, and eliminates at least one case of library conflict that was reported.</p>

<h3>Code Refactoring</h3>

<p>Really?  More refactoring?  Didn&#8217;t I just do a lot of this in the last point release?  Well yes, but more was needed&#8230; MUCH more.  Previously, code was roughly divided based on the MVC (model, view, controller) model into store.php, interface.php, and logic.php, respectively.  That worked for a while, but got to be pretty confusing as those individual files became a bit unmanageable.  Instead, things are now broken into more logical segments&#8230; comments, admin panel, logging in through wp-login.php, etc.  This seems to be a lot easier to manage and more importantly, easier to extend.</p>

<h3>More Hooks</h3>

<p>I haven&#8217;t sat down to document them all yet, but I&#8217;m adding in more hooks for other plugins to add functionality.  Want to pull profile data from FOAF instead of sreg?  No problem, now you have a hook you can implement.  This makes everything in the plugin much more lightweight and &#8220;loosely joined&#8221; which is always good.  All of the existing non-core OpenID functionality (like SREG) is currently using these hooks.</p>

<h3>Bug Fixes</h3>

<p>Though I&#8217;m not always good about replying, I generally do monitor <a href="http://wordpress.org/tags/openid">the conversations</a> on the WordPress support forums.  I will try and put together a more exhaustive list of what bugs have been addressed, but I will simply say for now that most of the major bugs people have reported there should be absent from the current development branch.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/12/rebuild-wp-openid-tables' rel='bookmark' title='Permanent Link: rebuild wp-openid tables'>rebuild wp-openid tables</a></li>
<li><a href='http://willnorris.com/2007/11/final-push-for-wp-openid-20' rel='bookmark' title='Permanent Link: final push for wp-openid 2.0'>final push for wp-openid 2.0</a></li>
<li><a href='http://willnorris.com/2008/07/wp-openid-220-released' rel='bookmark' title='Permanent Link: wp-openid 2.2.0 released'>wp-openid 2.2.0 released</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/09/wp-openid-faster-stronger-better/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>
