<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ikailo</title>
	<atom:link href="http://ikailo.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ikailo.com</link>
	<description>media solutions</description>
	<lastBuildDate>Fri, 04 Mar 2011 04:58:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Cross Domain Cookie Sharing for WordPress</title>
		<link>http://ikailo.com/218/cross-domain-cookie-sharing-wordpress/</link>
		<comments>http://ikailo.com/218/cross-domain-cookie-sharing-wordpress/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 04:30:14 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[cross-domain]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://ikailo.com/?p=218</guid>
		<description><![CDATA[It could just be me, but I feel as though I&#8217;ve seen a lot of emphasis lately on simplifying and consolidating logins actions. One of the things I&#8217;ve been considering, particularly for WordPress, is Cross-Domain Authentication and Cookie Sharing. I took a couple of days to see if it was possible, and as it turns [...]]]></description>
			<content:encoded><![CDATA[<p>It could just be me, but I feel as though I&#8217;ve seen a lot of emphasis lately on simplifying and consolidating logins actions. One of the things I&#8217;ve been considering, particularly for WordPress, is Cross-Domain Authentication and Cookie Sharing.  I took a couple of days to see if it was possible, and as it turns out, it is!</p>
<p>Here&#8217;s how I did it.</p>
<p><strong>Pre-Requisites</strong></p>
<p>The first order of business is to ensure all the sites being shared are using the same database and users tables. To do this, make sure each site points to the same database and add these to wp-config.php:</p>
<pre class="brush: php; title: ;">define('MASTER_DOMAIN', 'domain.com' ); // Change this to the domain name of your master site
define('CAP_PREFIX', 'wp_') // Change this prefix of your master site
define('CUSTOM_USER_TABLE', CAP_PREFIX.'users');
define('CUSTOM_USER_META_TABLE', CAP_PREFIX.'wp_usermeta');</pre>
<p>You could also make this hack in <em>&#8220;/wp-includes/capabilities.php&#8221;</em>:</p>
<p>CHANGE THIS:</p>
<pre class="brush: php; title: ;">$this-&gt;cap_key = $wpdb-&gt;prefix . 'capabilities';</pre>
<p>TO THIS:</p>
<pre class="brush: php; title: ;">$this-&gt;cap_key = defined('CAP_PREFIX') ? CAP_PREFIX . 'capabilities' : $wpdb-&gt;prefix . 'capabilities';</pre>
<p>Cross Domain Authentication works by defining a central domain (which we will call the master), to store a cookie for each user session. Any of the other domains (we will call them slaves) will either get or send the cookie to the master.</p>
<p>First &#8211; store the master and current base urls so we have easy access to them:</p>
<pre class="brush: php; title: ;">$wpcl_master_domain = 'http://'. MASTER_DOMAIN;
$wpcl_current_domain = 'http://'.$_SERVER[&quot;SERVER_NAME&quot;];</pre>
<p>We call it the current domain because it&#8217;s possible that the user might be logged onto the master domain.</p>
<p>On to the actual actions.  Firstly, when content on a slave domain is loaded, there are two possible scenarios.</p>
<p><strong>Scenario 1:</strong></p>
<p>The slave <strong>does not</strong> possess an authenticated cookie. In this case we want to check with the master and create a slave cookie if possible.</p>
<ul>
<li>Slave sends a request to the master that asks for a cookie value</li>
<li>Master sends a request to the slave that provides a cookie value</li>
<li>Slave authenticates the cookie value and sets slave cookie(s)</li>
</ul>
<p><strong>Scenario 2:</strong></p>
<p>The slave <strong>does</strong> posess an authenticated cookie. In this case we want to notify the master and create a master cookie if possible.</p>
<ul>
<li>Slave sends a request to the master that provides a cookie value</li>
<li>Master authenticates the cookie value and sets master cookie(s)</li>
</ul>
<p>You&#8217;ll notice that in both scenarios, there are potentially three actions.</p>
<p><strong>Stage 1, Requesting a Cookie Value:</strong></p>
<p>This is only ever done by a slave to a master, so we don&#8217;t need any parameters for the function. We&#8217;re also providing information about where to send the cookie back to.</p>
<pre class="brush: php; title: ;">
function wpcl_getUrlForCookieRequest(){
	global $wpcl_current_domain, $wpcl_master_domain;
	$target_url = add_query_arg('wpcl-caller', urlencode($wpcl_current_domain), $wpcl_master_domain);
	$target_url = add_query_arg('wpcl-stage', '1', $target_url);
	return $target_url;
}
</pre>
<p><strong>Stage 2, Sending a Cookie Value:</strong></p>
<p>This could be done by both the slave and the master, so we have an option of the URL to start with. We&#8217;re sending the logged-in cookie from the site as a value in the URL.</p>
<pre class="brush: php; title: ;">
function wpcl_getUrlToSendCookie($target_url){
	$target_url = add_query_arg('wpcl-logged-in', urlencode($_COOKIE[LOGGED_IN_COOKIE]), $target_url);
	$target_url = add_query_arg('wpcl-stage', '2', $target_url);
	return $target_url;
}
</pre>
<p><strong>Stage 3, Receiving, authenticating, and setting cookies:</strong></p>
<p>This is super easy with WordPress&#8217; built in functions:</p>
<pre class="brush: php; title: ;">
function wpcl_receive_cookie(){
	$userId = wp_validate_auth_cookie(urldecode($_GET['wpcl-logged-in']), 'logged_in');
	if ( $userId === false ) { return; }
	wp_set_auth_cookie($userId);
}
</pre>
<p><strong>Stage 4, Clear the parameters we were using (Optional):</strong></p>
<p>This is not necessary if we&#8217;re doing things in the background (read on), but if you have the need, here&#8217;s how to do it:</p>
<pre class="brush: php; title: ;">
function wpcl_clear_params() {
	global $wpcl_current_domain;
	$target_url = $wpcl_current_domain .$_SERVER[&quot;REQUEST_URI&quot;];
	$target_url = remove_query_arg('wpcl-caller', $target_url);
	$target_url = remove_query_arg('wpcl-logged-in', $target_url);
	$target_url = remove_query_arg('wpcl-stage', $target_url);
	wp_redirect($target_url);
    exit;
}
</pre>
<p>Let&#8217;s move on to the action logic. With the ability to send and receive cookies out of the way, we need to set up some handling methods. The following code monitors the &#8216;wpcl-stage&#8217; parameter in the URL to determine if any action needs to be carried out. As you can see, if it notices we&#8217;re in Stage 1 it will respond with Stage 2. If it notices we&#8217;re in Stage 2 it will respond with Stage 3. We want this to happen as early as possible in the WP Lifecycle, as to not waste resources. So we hook it into &#8216;init&#8217;.</p>
<pre class="brush: php; title: ;">
function wpcl_action() {
	$wpcl_stage = $_GET['wpcl-stage'];
    switch ($wpcl_stage) {
        case '1':
            $target_url = wpcl_getUrlToSendCookie(urldecode($_GET['wpcl-caller']));
			wp_redirect($target_url);
			exit;
            break;
        case '2':
            wpcl_receive_cookie();
            break;
        default:
			break;
    }
}
add_filter('init', 'wpcl_action', 10, 2);
</pre>
<p>Almost there; we just need to initialize the entire process.  I&#8217;ve chosen to use an image link to do this in the background. But, it could be done other ways too. There are some caveats to this method &#8211; in particular, doing it in the footer requires a full page load before requesting the cookie. So, a user might not be authenticated until the page refreshes a second time.  Nonetheless, this shows one method of how the process can be done in the background.</p>
<pre class="brush: php; title: ;">
function wpcl_background() {
	global $wpcl_master_domain, $wpcl_current_domain;

	if ( $wpcl_current_domain == $wpcl_master_domain ) { return; } // Bypass for master

	if ( is_user_logged_in() ) {
		// If logged in on a slave site, send the cookie to the master
		$target_url = wpcl_getUrlToSendCookie($wpcl_master_domain);
	} else {
		// If not logged in on a slave site, request a cookie from the master
		$target_url = wpcl_getUrlForCookieRequest();
	}
	?&gt;&lt;img src=&quot;&lt;?php echo $target_url; ?&gt;&quot; alt=&quot;&quot; style=&quot;display=none;&quot;; /&gt;&lt;?php
}
add_action('wp_footer', 'wpcl_background');
add_action('admin_footer', 'wpcl_background');
</pre>
<p>Finally, just make sure this code is loaded and active (as a plugin) in the master domain and all slave domains.</p>
<p>Using this technique, one could potentially enable an infinite number of WordPress sites to share login sessions by utilizing cross-domain authentication and cookie sharing.</p>
<p><a href='http://ikailo.com/wp-content/uploads/ikailo/wp-central-login.php_.txt' target="_blank">View the full code here.</a></p>
<p>This has been marginally tested and found to be working on both WP Multisite and <a href="http://wp-hive.com">WP Hive</a>. It comes with no guarantee and no support. If you find it to be useful, please share it with others.</p>
]]></content:encoded>
			<wfw:commentRss>http://ikailo.com/218/cross-domain-cookie-sharing-wordpress/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>BB Press Users Cleanup</title>
		<link>http://ikailo.com/139/bb-press-users-cleanup/</link>
		<comments>http://ikailo.com/139/bb-press-users-cleanup/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 05:14:41 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[BB Press]]></category>
		<category><![CDATA[Spam]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.ikailo.com/?p=139</guid>
		<description><![CDATA[I finally got around to removing all the bot-users (about 3100 in total) that had registered in my BB Press Forum. Here&#8217;s what I did. It&#8217;s not for the novice, and I don&#8217;t take responsibility for anything that blows up. Of course, always backup first. Step 1: Installed Human Test for BB Press Step 2: [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to removing all the bot-users (about 3100 in total) that had registered in my BB Press Forum. Here&#8217;s what I did. It&#8217;s not for the novice, and I don&#8217;t take responsibility for anything that blows up. Of course, always backup first.</p>
<p>Step 1:<br />
Installed <a href="http://bbpress.org/plugins/topic/human-test/">Human Test for BB Press</a></p>
<p>Step 2:<br />
Used <a href="http://webdesign.anmari.com/plugins/users/">AmR-Users</a> to generate a CSV list of bot users by generating a report that excluded user levels of 0,1,2,3,4,5,6,7,8,9,10 and making the id visible.</p>
<p>Note &#8211; my BB Press installation is integrated with WordPress, so they share the same users tables. This method would only work in that case, because if the user doesn&#8217;t validate their email address, then it&#8217;s not set up with a role in WordPress.</p>
<p>Step 3:<br />
Used Excel to reformat the list &#8211; creating a list of all the ID&#8217;s, with a comma after.</p>
<p>Step 4:<br />
I wrote a quick script to actually delete the users. The array part was 3100 lines long, just a copy and paste from Excel.</p>
<pre class="brush: php; title: ;">&lt;?php
/*
Plugin Name: Bot Cleanup
Description: Get rid of BBpress bot users.
Version: 0.1
*/
function wphive_delete_now() {
    $ids = array(
        1856,
        1857,
        1234
    );

    if ($_REQUEST['delete'] == 'now') {
        require_once(ABSPATH.'/wp-admin/includes/user.php');
        foreach ($ids as $id) {
            wp_delete_user( $id );
        }
    }
}
add_action('init', 'wphive_delete_now');
?&gt;</pre>
<p>Step 5:<br />
Installed it as a plugin in WordPress and activated it. Don&#8217;t forget to uninstall it and delete it after you are done.</p>
<p>Step 6:<br />
Loaded up my website with the appropriate GET to activate it:<br />
http://domain.com/index.php?delete=now and Voila! all those spammy users disappeared. I actually had to load it twice because it timed out the first time after deleting about 2400 users.</p>
]]></content:encoded>
			<wfw:commentRss>http://ikailo.com/139/bb-press-users-cleanup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Web Design Partner</title>
		<link>http://ikailo.com/136/web-design-partner/</link>
		<comments>http://ikailo.com/136/web-design-partner/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 03:41:34 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[partner]]></category>
		<category><![CDATA[web design]]></category>

		<guid isPermaLink="false">http://www.ikailo.com/?p=136</guid>
		<description><![CDATA[I&#8217;ve been getting excellent feedback and response from my main project, WP Hive. Alas, even though it&#8217;s not well advertised that I offer custom-plugin-development services, I am getting regular requests from individuals who need various WordPress Web-Development jobs done. Coincidentally (or perhaps not), I am also getting regular requests for Web Design work. The problem [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting excellent feedback and response from my main project, <a title="WP Hive - Multiple Blogs Single Installation of WordPress" href="http://wp-hive.com">WP Hive</a>. Alas, even though it&#8217;s not well advertised that I offer custom-plugin-development services, I am getting regular requests from individuals who need various WordPress Web-Development jobs done.</p>
<p>Coincidentally (or perhaps not), I am also getting regular requests for Web Design work. The problem is that I prefer to focus on what I do best, which is writing great software. As a result, I&#8217;ve had to turn down a number of requests for designing themes and other various work on the WordPress front-end.</p>
<p>Instead of turning these clients away, I would like to send them to someone who can take care of the customer the same way I would.  In return, I would expect to get some leads back.</p>
<p>Ideally I would like to work with someone who:</p>
<p>- Has existing clients and a portfolio of work.<br />
- Has a proven method of generating leads and finding new jobs.<br />
- Has had to turn down requests for web-development, in favor of specializing in web-design.<br />
- Is serious about running this venture as business.</p>
<p>The idea is that this would be an on-going symbiotic relationship.</p>
<p>If you are interested in exploring this type of partnership, please <a title="Contact Ikailo" href="/contact">contact me</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ikailo.com/136/web-design-partner/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>URL Mod-Rewrite Workaround for IIS 6.0 and WordPress</title>
		<link>http://ikailo.com/94/url-modrewrite-workaround-iis-60/</link>
		<comments>http://ikailo.com/94/url-modrewrite-workaround-iis-60/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 02:11:05 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[Mod-Rewrite]]></category>

		<guid isPermaLink="false">http://www.ikailo.com/?p=94</guid>
		<description><![CDATA[I found that the existing solution for using pretty permalinks with WordPress and IIS is good and lightweight, but I needed something a little more robust that fixed as many differences as possible between Apache and IIS. This code uses the same idea as the above, but fixes more values in _SERVER and resolves a [...]]]></description>
			<content:encoded><![CDATA[<p>I found that the existing solution for using <a title="Pretty Permalinks on WordPress and IIS" href="http://tech.einaregilsson.com/2007/07/30/pretty-wordpress-permalinks-on-iis/" target="_self">pretty permalinks with WordPress and IIS</a> is good and lightweight, but I needed something a little more robust that fixed as many differences as possible between Apache and IIS.</p>
<p>This code uses the same idea as the above, but fixes more values in _SERVER and resolves a problem with _GET. It will also work with later versions (2.8+) of WordPress.</p>
<pre class="brush: php; title: ;">&lt;?php
// This is the default file for the site. Usually index.php
$default = 'index.php';

// The name of this file.
// Set this value for the URL in Custom Error Properties of your website in IIS.
// Goto: IIS Manager &gt; Websites &gt; [Site Name] &gt; Properties &gt; Custom Errors &gt;
// 404 &amp; 404;2 &amp; 404;3 &gt; URL (Requires a '/' prefix in IIS).
$thisfile = '404-handler.php';

$_SERVER['ORIG_PATH_TRANSLATED'] = str_replace($thisfile, $default, $_SERVER['ORIG_PATH_TRANSLATED']);
$_SERVER['SCRIPT_FILENAME'] = str_replace($thisfile, $default, $_SERVER['SCRIPT_FILENAME']);
$_SERVER['ORIG_PATH_INFO'] = str_replace($thisfile, $default, $_SERVER['ORIG_PATH_INFO']);
$_SERVER['SCRIPT_NAME'] = str_replace($thisfile, $default, $_SERVER['SCRIPT_NAME']);
$_SERVER['PHP_SELF'] = str_replace($thisfile, $default, $_SERVER['PHP_SELF']);
$_SERVER['PATH_INFO'] = false;

$qs =&amp; $_SERVER['QUERY_STRING'];
$ru =&amp; $_SERVER['REQUEST_URI'];
$pos = strrpos($qs, '://');
$pos = strpos($qs, '/', $pos + 4);
$_SERVER['URL'] = $ru = substr($qs, $pos);
$qs = trim(stristr($ru, '?'), '?');

// Required for WordPress 2.8+
$_SERVER['HTTP_X_ORIGINAL_URL'] = $ru;

// Fix GET vars
foreach ( $_GET as $var =&gt; $val ) {
  if ( substr($var, 0, 3) == '404') {
    if ( strstr($var, '?') ) {
      $newvar = substr($var, strpos($var, '?') + 1);
      $_GET[$newvar] = $val;
    }
    unset($_GET[$var]);
  }
  break;
}
include($default);
?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://ikailo.com/94/url-modrewrite-workaround-iis-60/feed/</wfw:commentRss>
		<slash:comments>102</slash:comments>
		</item>
	</channel>
</rss>

