<?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>GeneralThreat.com &#187; php</title>
	<atom:link href="http://www.generalthreat.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.generalthreat.com</link>
	<description>Dangerously different projects and code</description>
	<lastBuildDate>Sun, 19 Jan 2014 20:00:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Grappling with BP theme compatibility</title>
		<link>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/</link>
		<comments>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/#comments</comments>
		<pubDate>Wed, 28 Aug 2013 18:16:26 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=104</guid>
		<description><![CDATA[Theme compatibility was introduced in BuddyPress 1.7 and allows site operators to use BP with any available WordPress theme. I have been way behind at updating BP Group Hierarchy to support theme compatibility, and&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p><a href="http://codex.buddypress.org/theme-compatibility/">Theme compatibility</a> was introduced in BuddyPress 1.7 and allows site operators to use BP with any available WordPress theme. I have been way behind at updating <a href="http://wordpress.org/plugins/bp-group-hierarchy/">BP Group Hierarchy</a> to support theme compatibility, and as a result the Group Tree page looks like garbage when not using a theme that was written for BuddyPress. This post is about the effort to fix that.</p>
<p>If you are writing a normal BuddyPress plugin &#8212; one that adds pages rather than replacing them &#8212; see <a href="http://codex.buddypress.org/theme-compatibility/upgrading-older-plugins-that-bundle-custom-templates-for-bp-1-7/">this excellent article</a> (and <a href="http://codex.buddypress.org/theme-compatibility/how-to-enjoy-bp-theme-compat-in-plugins/">this one too</a>) at the BuddyPress Codex for info on how to implement BP theme compatibility.</p>
<h2>First idea: Replace the content from <code>directory_content</code> with the group tree.</h2>
<p><code>BP_Groups_Theme_Compat::directory_content()</code> is the native BP function that displays the group list page. It&#8217;s called as a hook to a filter called <code>bp_replace_the_content</code>, so the content should be available for further filtering after it runs.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Filter the theme-compatibility content for a group tree page
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_inject_group_tree<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_buffer_group_tree'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">100</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_buffer_group_tree<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$content</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$loop_template</span> <span style="color: #339933;">=</span> apply_filters<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_located_template'</span><span style="color: #339933;">,</span> locate_template<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;tree/index.php&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;tree/index.php&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        load_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$loop_template</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ob_get_clean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups_directory_groups_setup'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_inject_group_tree'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> No dice. Directory content is echoed to the screen, not returned to the filter chain. The group tree appears below the flat group list.</p>
<h2>Workaround / second idea: Unhook the <code>directory_content</code> function so it doesn&#8217;t echo.</h2>
<p>Here&#8217;s a snippet that I threw together testing this out (warning: closure => PHP 5.3+ !):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Filter the theme-compatibility content for a group tree page
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_inject_group_tree<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #009933; font-style: italic;">/**
                 * Filter is hooked by a method of an anonymous instance...
                 * Search all registered listeners and pick off the BP_Groups_Theme_Compat one.
                 */</span>
&nbsp;
                <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_filter</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wp_filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$filter</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'BP_Groups_Theme_Compat'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                                <span style="color: #666666; font-style: italic;">// Found and removing the native content</span>
                                <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wp_filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_buffer_group_tree'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">100</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_buffer_group_tree<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$content</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Same as before */</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups_directory_groups_setup'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_inject_group_tree'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works well but is pretty awkward and brittle. It looks like the kind of solution I&#8217;d really like to avoid.</p>
<p>Let&#8217;s try something completely different. <img src="http://www.generalthreat.com/wordpress/wp-includes/images/smilies/simple-smile.png" alt=":)" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>Third idea: Use BP Theme Compat functions to replace the loop template file.</h2>
<p>BuddyPress theme compatibility adds a lot of flexibility in how content is gathered for the site. I actually find the theme compatibility process much more intuitive to work with than the traditional template loading process.</p>
<p>Here are some highlights:</p>
<ol>
<li><code>bp_register_template_stack()</code> lets you add a source of template files without filtering <code>bp_located_template</code>. Nice!</li>
<li><code>bp_get_template_part()</code> offers an easy way to switch out template files on the fly that is just not possible with <code>load_template</code>.</li>
</ol>
<p>Is it really this easy?</p>
<p><strong>SPOILER ALERT:</strong> This does not work for BP Group Hierarchy. But for most applications, I think this is the best way to conditionally replace a BP page with content from a plugin.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Add plugin templates folder to list of available template paths
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_register_template_location<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span> <span style="color: #009900; font-weight: bold;">__FILE__</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/templates/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Replace groups/groups-loop with tree/tree-loop depending on user settings
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_maybe_replace_group_loop_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">,</span> <span style="color: #000088;">$slug</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups/groups-loop'</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$slug</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'tree/tree-loop.php'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_register_template_stack'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	bp_register_template_stack<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_group_hierarchy_register_template_location'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_get_template_part'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_maybe_replace_group_loop_template'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works(!)<br />
But when you trigger an AJAX request, the unaltered ID on the &#8220;All Groups&#8221; tab leads BP to load the flat list.<br />
We also still need to hook the <code>bp_located_template</code> filter to find stylesheets, since we are enqueue-ing them instead of loading the contents inline.<br />
It also also removes the ability to customize the &#8220;Group Tree&#8221; label, a feature added by popular demand.</p>
<h2>Fourth idea: Use BP Theme Compat functions to replace the whole Groups list page.</h2>
<p>This is really just a twist on how things are currently handled, and it looks like the current way will be around as long as BP-compatible themes bypass <code>bp_get_template_part</code>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Add plugin templates folder to list of available template paths
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_register_template_location<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span> <span style="color: #009900; font-weight: bold;">__FILE__</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/templates/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Replace groups/index with tree/index-compat depending on user settings
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_maybe_replace_group_index_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">,</span> <span style="color: #000088;">$slug</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups/index'</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$slug</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'tree/index-compat.php'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_register_template_stack'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	bp_register_template_stack<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_group_hierarchy_register_template_location'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_get_template_part'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_maybe_replace_group_index_template'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works seamlessly. It even allows BP to load templates from the stylesheet and template directories before falling back to those included with the plugin.</p>
<p>The only drawback is that it requires a new template file, the group tree version of the <code>bp-templates/bp-legacy/buddypress/groups/index.php</code> file from BP. Which is to say that it adds another layer of template hijinks and possible theme compatibility issues rather than removing an existing one.</p>
<h2>Wrap up</h2>
<p>I don&#8217;t know if this is the strategy that will ultimately make it into the plugin, but it is straightforward and has performed well in early tests. In the meantime, I hope this post will be useful to anyone else trying to do something crazy and ill-advised with BuddyPress.</p>
<p>If you use any of the techniques on this page, please drop me a line in the comments and let me know how they worked for you. And if you have any suggestions on techniques that work even better than these, please send those along too. <img src="http://s.w.org/images/core/emoji/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Make P2 posts private by default (and control them with tags)</title>
		<link>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/</link>
		<comments>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/#comments</comments>
		<pubDate>Sun, 30 Jun 2013 20:02:24 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[p2]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=101</guid>
		<description><![CDATA[The Wordpress theme <a href="http://p2theme.com/">P2</a> is great for collaboration and team discussion. Sometimes that discussion can be entirely public, and at other times it makes sense to put the entire site behind a login screen. But what if you want to combine a private discussion stream with public pages? Or mix public posts with private ones? This post will show you how to mix and match private and public posts on your P2 blog and will set up a framework for controlling post behavior through tags.]]></description>
				<content:encoded><![CDATA[<p>The WordPress theme <a href="http://p2theme.com/">P2</a> is great for collaboration and team discussion. Sometimes that discussion can be entirely public, and at other times it makes sense to put the entire site behind a login screen. But what if you want to combine a private discussion stream with public pages? Or mix public posts with private ones? P2 emphasizes quick and easy posting by streamlining the process, but this comes at the expense of options.</p>
<p>This post will show you how to mix and match private and public posts on your P2 blog and will set up a framework for controlling post behavior through tags.</p>
<p>No changes to P2&#8217;s files are needed, and this trick will work even with older versions on the theme. This code should be placed in your child theme&#8217;s <code>functions.php</code> file or in a plugin of your own. There&#8217;s a <a href="#combined">combined block</a> at the bottom of this post for easy copy and paste.</p>
<h2><a name="step1"></a>1. Hook P2&#8217;s post save mechanism</h2>
<p>While P2 exposes limited posting options, authors using the back-end dashboard have access to the full publishing UI. So we want to make sure to target only posts made from the front-end to avoid confusion for authors using full UI.</p>
<p>Loading our handlers this way allows us to ensure that only P2 posts are affected by these magic tags.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Use this action to catch requests to P2 AJAX functions
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_add_hooks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp_insert_post_data'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_maybe_make_post_private'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'pre_get_posts'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_include_private_posts'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p2_ajax'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_add_hooks'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>2. Check for magic tags when saving</h2>
<p>Having hooked the action above, we know that the function below will only run on P2 posts. First, the list of tags is split into an array so we can look for them more easily. Then, we search for any tags we have decided will control post behavior, and change the post accordingly.</p>
<p><strong>Check out lines 21-24</strong> &mdash; this is where the magic happens. We check whether the post is tagged <code>public</code>. If it is, we leave it alone (P2 posts are public by default). If it isn&#8217;t, we change its status to private.</p>
<p>This example only implements a single check, but you can create as many as you want.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Change post status to private unless it is tagged &quot;public&quot;
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_maybe_make_post_private<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$postarr</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$postarr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tags_input'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$comma</span> <span style="color: #339933;">=</span> _x<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'tag delimiter'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$comma</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$comma</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #660099; font-weight: bold;">\0</span><span style="color: #660099; font-weight: bold;">\x0B</span>,&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Look for tags and control what they do here
	 */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'public'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Change attributes of the post here</span>
		<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'post_status'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'private'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Make sure to return the data!</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>3. Fix the in-page refresh</h2>
<p>P2&#8217;s fancy in-page refresh only loads public posts. To make our change seamless to users, this needs to be expanded to load private posts too. We&#8217;ll need to add one more short function to accomplish this. You may have seen a hint of it in <a href="#step1">Step 1</a>, but here&#8217;s the function itself.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Expand query to include all post status values visible to current user
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_include_private_posts<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$obj</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'post_status'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'any'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>That&#8217;s it! Users logged in with Editor or Administrator privileges won&#8217;t notice a difference, but other users and anonymous visitors will see only their own posts and those tagged <code>public</code>.</p>
<p>Feel free to drop me a line in the comments if you have any questions or find a use for this on your own sites!</p>
<hr />
<h2><a name="combined"></a>The whole thing</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Make all P2 posts Private unless they are tagged &quot;public&quot;
 */</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Use this action to catch requests to P2 AJAX functions
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_add_hooks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp_insert_post_data'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_maybe_make_post_private'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'pre_get_posts'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_include_private_posts'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p2_ajax'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_add_hooks'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Change post status to private unless it is tagged &quot;public&quot;
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_maybe_make_post_private<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$postarr</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$postarr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tags_input'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$comma</span> <span style="color: #339933;">=</span> _x<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'tag delimiter'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$comma</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$comma</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #660099; font-weight: bold;">\0</span><span style="color: #660099; font-weight: bold;">\x0B</span>,&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Look for tags and control what they do here
	 */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'public'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Change attributes of the post here</span>
		<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'post_status'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'private'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Make sure to return the data!</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Expand query to include all post status values visible to the current user
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_include_private_posts<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$obj</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'post_status'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'any'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a (relatively) secure dynamic PHP test environment with nginx</title>
		<link>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/</link>
		<comments>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/#comments</comments>
		<pubDate>Fri, 30 Nov 2012 02:51:54 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=95</guid>
		<description><![CDATA[I&#8217;ve been working on a deployment tool for WordPress development environments; one that can quickly provision and maintain the dizzying array of sites needed to test plugins against different versions of WordPress (with and&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been working on a deployment tool for WordPress development environments; one that can quickly provision and maintain the dizzying array of sites needed to test plugins against different versions of WordPress (with and w/o Multisite), BuddyPress, bbPress, etc.</p>
<p>Some cocktail napkin math suggested at least 20 combinations were needed to cover all the currently-supported configurations. Besides the chore of setting up environments for each, the need to add or remove environments as components are updated makes a manual deployment effort seem ridiculous.</p>
<p>While I&#8217;m finishing up work on that tool, I thought I&#8217;d start by posting the web server and PHP configs I&#8217;m using to make this happen.</p>
<h3>nginx Configuration</h3>
<p>I went with nginx because of its low memory usage and its handy regular-expression hostname matching, which I find more flexible and less kludgey for this application than mod_vhost_alias or mod_rewrite. This nginx config will provide the flexibility of dynamically-creating sites while still providing some isolation between them.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="nginx" style="font-family:monospace;">server {
        server_name ~^(.*)\.dev.your.domain$ ;
&nbsp;
        set $instance $1;
        set $session_root /var/www/dev/$instance/sessions;
&nbsp;
        root /var/www/dev/$instance/html;
        index index.php;
&nbsp;
        location ~ \.php$ {
&nbsp;
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
&nbsp;
                fastcgi_pass unix:/var/run/fpm-devsites.sock;
#               fastcgi_pass 127.0.0.1:9000
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_param PHP_ADMIN_VALUE  &quot;open_basedir=$document_root\nsession.save_path=$session_root&quot;;
                include /etc/nginx/fastcgi_params;
&nbsp;
        }
&nbsp;
        location / {
                try_files $uri $uri/ /index.php;
        }
}</pre></td></tr></table></div>

<p>Thanks to mike at <a href="http://michaelshadle.com/2011/02/11/setting-php-ini-parameters-from-nginx">http://michaelshadle.com/2011/02/11/setting-php-ini-parameters-from-nginx</a> for the great guide to the PHP_ADMIN_VALUE param.</p>
<h3>PHP-FPM Configuration</h3>
<p>Ideally each site would have its own FPM pool, but that would mean root privileges were needed to provision new sites. So a single but separate pool for the dev environments was a necessary compromise. The goal of dynamically creating sites through an unprivileged web interface also meant that the <code>devsites</code> pool needed to run as the web user.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">; Start a new pool named 'www'.</span>
<span style="color: #666666; font-style: italic;">; the variable $pool can we used in any directive and will be replaced by the</span>
<span style="color: #666666; font-style: italic;">; pool name ('www' here)</span>
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>devsites<span style="">&#93;</span></span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Unix user/group of processes</span>
<span style="color: #666666; font-style: italic;">; Note: The user is mandatory. If the group is not set, the default user's group</span>
<span style="color: #666666; font-style: italic;">;       will be used.</span>
<span style="color: #000099;">user</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
<span style="color: #000099;">group</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; The address on which to accept FastCGI requests.</span>
<span style="color: #666666; font-style: italic;">; Valid syntaxes are:</span>
<span style="color: #666666; font-style: italic;">;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on</span>
<span style="color: #666666; font-style: italic;">;                            a specific port;</span>
<span style="color: #666666; font-style: italic;">;   'port'                 - to listen on a TCP socket to all addresses on a</span>
<span style="color: #666666; font-style: italic;">;                            specific port;</span>
<span style="color: #666666; font-style: italic;">;   '/path/to/unix/socket' - to listen on a unix socket.</span>
<span style="color: #666666; font-style: italic;">; Note: This value is mandatory.</span>
<span style="color: #000099;">listen</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /var/run/fpm-$pool.sock</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Set permissions for unix socket, if one is used. In Linux, read/write</span>
<span style="color: #666666; font-style: italic;">; permissions must be set in order to allow connections from a web server. Many</span>
<span style="color: #666666; font-style: italic;">; BSD-derived systems allow connections regardless of permissions.</span>
<span style="color: #666666; font-style: italic;">; Default Values: user and group are set as the running user</span>
<span style="color: #666666; font-style: italic;">;                 mode is set to 0666</span>
listen.owner <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
listen.group <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
listen.mode <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0666</span></pre></td></tr></table></div>

<p>If you&#8217;ve found this helpful (or troublesome), feel free to drop me a line in the comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending BuddyPress Group Hierarchy &#8211; Adding Breadcrumbs to Your Theme</title>
		<link>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/</link>
		<comments>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 17:49:34 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=87</guid>
		<description><![CDATA[Once you&#8217;ve created a hierarchy of BuddyPress groups, you can help your users navigate and give your site the professional touch by including group breadcrumbs where appropriate. Here&#8217;s how! Step One: Change the link&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>Once you&#8217;ve created a hierarchy of BuddyPress groups, you can help your users navigate and give your site the professional touch by including group breadcrumbs where appropriate. Here&#8217;s how!</p>
<h3>Step One: Change the link at the top of every group page to a trail of links to parent groups</h3>
<p>This is the easy part! BuddyPress Group Hierarchy includes a function, <code>bp_group_hierarchy_breadcrumbs()</code>, that will generate a string of links to a group and all its parents. Use it in the Groups loop, and no parameter is required. </p>
<p><strong>Note:</strong> If you need to pass in a different group for some reason, you&#8217;ll need to use <code>bp_group_hierarchy_get_breadcrumbs( $separator = '|', $group = false )</code> function and echo the result yourself. This tutorial won&#8217;t address using that more advanced function.</p>
<p>Just locate your theme&#8217;s <code>groups/single/group-header.php</code> file, and find the current group header which will look something like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&lt;h2&gt;&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; title=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&lt;/h2&gt;</pre></td></tr></table></div>

<p>Replace it with this simple line:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&lt;h2&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_hierarchy_breadcrumbs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h2&gt;</pre></td></tr></table></div>

<h3>Step Two: Change the page title on group pages to reflect your group structure</h3>
<p>Changing the page title is more complicated. BuddyPress builds its page titles with a function hooked to the <code>wp_title</code> filter. This function in turn presents its own filter, and that&#8217;s the one we have to hook to put breadcrumbs in the title of our Group page. This makes sure our filtering function runs only when BuddyPress is enabled and on as few pages as necessary.</p>
<p>If you zoned out during that bit, don&#8217;t worry! Just place the code below into your theme&#8217;s <code>functions.php</code> file.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_modify_page_title'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_group_breadcrumbs'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_func_group_breadcrumbs<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sep</span><span style="color: #339933;">,</span> <span style="color: #000088;">$seplocation</span>  <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">;</span>
&nbsp;
 	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups'</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">groups</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current_group</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$processed_title</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sep</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$processed_title</span> <span style="color: #339933;">=</span> bp_group_hierarchy_get_full_name<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">groups</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current_group</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">;</span>
 	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This function strips the group name from the page title, but re-adds the names of the group and all its ancestors. The <code>bp_group_hierarchy_get_full_name</code> function works like the <code>bp_group_hierarchy_get_breadcrumbs</code> function I mentioned earlier, but it builds a plain text list instead of a list of links.</p>
<p>That&#8217;s it!  Check back soon for a reference child theme, implementing this technique. As always, if you have any questions or problems adding this to your site, or if you have a novel implementation you&#8217;d like to share, please post in the comments below!</p>
<p><ins datetime="2012-04-06T15:02:01+00:00"><strong>Update:</strong> As promised, here is the sample child theme! <a href="http://www.generalthreat.com/downloads/GroupBreadcrumbs.zip" title="Download BuddyPress Group Hierarchy Breadcrumbs - Sample Theme">BuddyPress Group Hierarchy Breadcrumbs - Sample Theme</a></ins></p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding Externally-Authenticated Users to BuddyPress</title>
		<link>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/</link>
		<comments>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 01:49:26 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=85</guid>
		<description><![CDATA[BuddyPress does a great job integrating new users who register through your WordPress site into the community &#8212; optionally synchronizing profile information between BP and WP, and creating an activity feed item for new&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>BuddyPress does a great job integrating new users who register through your WordPress site into the community &mdash; optionally synchronizing profile information between BP and WP, and creating an activity feed item for new user signups.</p>
<p>But what about users who login against an external authentication provider, and whose accounts are created and managed by such a system? Today we&#8217;re going to look at how to bring those users into the community in the same way as those who registered locally. Be warned &mdash; this is a fairly dense piece, especially if you haven&#8217;t worked with an <code>authenticate</code> filter before.</p>
<h3>A crash course on <code>authenticate</code></h3>
<p>If you are using (or writing) an external authentication plugin, you&#8217;ll need a function hooked to the <code>authenticate</code> filter. This function is where your plugin gets a chance to authenticate users against your outside system. It is also where your users will have subordinate WordPress accounts made and managed by the external system.</p>
<p>A very quick example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #666666; font-style: italic;">// if $user is a valid WP_User, authenticated by an upstream filter</span>
 <span style="color: #666666; font-style: italic;">// pass these params to the external auth source for verification</span>
 <span style="color: #666666; font-style: italic;">// proceed if user is logged in, otherwise return a WP_Error</span>
<span style="color: #009900;">&#125;</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'authenticate'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_to_authenticate'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>The first login</h3>
<p>The first time your users log in to your WordPress install using their external credentials, you&#8217;ll probably want to create a WP account for them. You may skip this if you&#8217;re just trying to restrict read access, but this is about BuddyPress, so I&#8217;m assuming you want them to post and contribute to the site. <img src="http://www.generalthreat.com/wordpress/wp-includes/images/smilies/simple-smile.png" alt=":)" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Here&#8217;s a rundown of the process:</p>
<ol>
<li>Suppress the BuddyPress activation email</li>
<li>Create WP user account</li>
<li>Update user meta and, optionally, xprofile data</li>
<li>Activate user and set proper <code>display_name</code></li>
<li>Publish activity stream message about new user, with properly-formatted display name</li>
</ol>
<h4>Suppress the BuddyPress activation email</h4>
<p>These users are already verified by virtue of being in our external auth system, so an activation email would just be confusing.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/** Suppress activation key email for users logging in with external auth */</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_core_signup_send_activation_key'</span><span style="color: #339933;">,</span> <span style="color: #990000;">create_function</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'return false;'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>Create WordPress user account</h4>
<p>Normally, you&#8217;d use <code><a href="http://codex.wordpress.org/Function_Reference/wp_create_user">wp_create_user</a></code> (or <code><a href="http://codex.wordpress.org/Function_Reference/wp_insert_user">wp_insert_user</a></code> if you want access to the full set of user properties).<br />
But BuddyPress comes with a wrapper function that can be used to do a lot of the heavy lifting for us.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
	<span style="color: #000088;">$user_login</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$user_password</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> is_wp_error<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>Update user meta and, optionally, xprofile data</h4>
<p>There are actually a few ways to handle this, ranging from bull-in-a-china-shop overwriting to graceful but more complicated filtering. Which one you choose may depend on your comfort with WP or PHP, which BuddyPress features you have enabled, or the structure of your authentication script.</p>
<p><div class='postTabs_divs postTabs_curr_div' id='postTabs_0_85'>
<span class='postTabs_titles'><b>Easiest</b></span></p>
<h5>Easiest</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$display_name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$first_name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$last_name</span><span style="color: #339933;">;</span>
&nbsp;
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'nickname'</span><span style="color: #339933;">,</span>   <span style="color: #000088;">$display_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'first_name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$first_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'last_name'</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$last_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Even though setting the xprofile value, above, should take care of this, </span>
<span style="color: #666666; font-style: italic;">// testing revealed that we needed to prime the cache with the right value</span>
wp_cache_set<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_user_fullname_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Very straightforward and procedural &mdash; no objects or data sharing needed</li>
<li>Complete control over format of display_name and BP fullname field</li>
<li>Control over any other BP xprofile values you want to set</li>
<li>Does not require xprofile or WP-BP profile sync in order to operate</li>
</ul>
<p>CONS:</p>
<ul>
<li>Will ultimately drift out of sync with BP development</li>
<li>Still need to set the display_name property below</li>
<li>Might as well use <code>wp_insert_user</code>, since we&#8217;re manually adding so much</li>
</ul>
<p></div>

<div class='postTabs_divs' id='postTabs_1_85'>
<span class='postTabs_titles'><b>Shortest</b></span></p>
<h5>Shortest</h5>
<p>Replace the <code>bp_core_signup_user</code> call above with this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
	<span style="color: #000088;">$login_name</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$email</span><span style="color: #339933;">,</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'profile_field_ids'</span> <span style="color: #339933;">=&gt;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">&quot;field_{bp_xprofile_fullname_field_name()}&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$display_name</span>
	<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Uses BP to eliminate the need for additional filters or processing</li>
<li>Least code redundancy of all</li>
<li>Can supply additional xprofile fields to be added to the new user</li>
<li>Most natural method in terms of program flow</li>
</ul>
<p>CONS:</p>
<ul>
<li>Complex meta parameter structure can be difficult to read</li>
<li>Parameter or data structure may change in future BP releases</li>
<li>Requires xprofile and WP-BP profile sync to update WP display_name and usermeta</li>
</ul>
<p></div>

<div class='postTabs_divs' id='postTabs_2_85'>
<span class='postTabs_titles'><b>Fanciest</b></span></p>
<h5>Fanciest</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_display_name_filter<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_login</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_password</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span> <span style="color: #000088;">$usermeta</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// must get $display_name from another part of the authentication process</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Change your authenticate function to look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// ... authenticate user</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_core_signup_user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_display_name_filter'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
		<span style="color: #000088;">$login_name</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$email</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Uses BP filters for forward compatibility</li>
<li>Reduces the amount of repeated code</li>
</ul>
<p>CONS:</p>
<ul>
<li>Requires an object or data-sharing infrastructure to get user details to the filter</li>
<li>Requires xprofile and WP-BP profile sync to  update WP display_name and usermeta</li>
</ul>
<p></div>

</p>
<hr />
Now that the xprofile and usermeta data are set up, it&#8217;s time to activate the user! This is done by simply setting the <code>user_status</code> column to <code>0</code>.</p>
<h4>Activate user (and set proper display_name, if needed)</h4>
<p><ins datetime="2012-08-06T23:43:09+00:00"><strong>Update 08-06-2012:</strong> I used to recommend <code>wp_update_user</code> for this, but that has proven unreliable on a recent project. So to be safe, just use a direct query.</ins></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// activate user and set display name appropriately</span>
<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET display_name=<span style="color: #009933; font-weight: bold;">%s</span>, user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And if you set <code>$display_name</code> above, use the shortened version:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// activate user</span>
<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>Publish an activity stream message about the new user and notify the site admin</h4>
<p>Since the display_name property and associated xprofile field are finally set the way we want them, it&#8217;s time to trigger the activity stream message and administrator notification.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">bp_core_new_user_activity<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
wp_new_user_notification<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>And you&#8217;re done!</h4>
<p>Return a <code>WP_User</code> object to let other authentication filters know you&#8217;ve handled this user.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_User<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>A complete example</h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// if $user is a valid WP_User, authenticated by an upstream filter</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'WP_User'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$user</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// pass these params to the external auth source for verification</span>
	<span style="color: #666666; font-style: italic;">// proceed if user is logged in, otherwise return a WP_Error</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_details</span> <span style="color: #339933;">=</span> my_external_auth<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// for simplicity's sake, I'm assuming that $user_details is an array with all the right keys</span>
		<span style="color: #666666; font-style: italic;">// in practice, more checks would be required</span>
		<span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_details</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// this function returns the new user account ID if successful</span>
		<span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
			<span style="color: #000088;">$username</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span>
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// If signup returned an error, skip the rest</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> is_wp_error<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$display_name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$first_name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$last_name</span><span style="color: #339933;">;</span>
&nbsp;
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'nickname'</span><span style="color: #339933;">,</span>   <span style="color: #000088;">$display_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'first_name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$first_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'last_name'</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$last_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
			xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Even though setting the xprofile value, above, should take care of this, </span>
		<span style="color: #666666; font-style: italic;">// testing revealed that we needed to prime the cache with the right value</span>
		wp_cache_set<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_user_fullname_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// activate user and set display name appropriately</span>
		<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET display_name=<span style="color: #009933; font-weight: bold;">%s</span>, user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		bp_core_new_user_activity<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		wp_new_user_notification<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_User<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// you can return FALSE, or a WP_Error if you have something specific to say</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_Error<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'login_failed'</span><span style="color: #339933;">,</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Could not authenticate user'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'authenticate'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_to_authenticate'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If you have questions, or if you put this to use in your next project, feel free to drop me a line in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending BuddyPress Group Hierarchy &#8211; Creating a Member Groups list</title>
		<link>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/</link>
		<comments>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 19:44:39 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=82</guid>
		<description><![CDATA[In this post, I&#8217;m going to show you how to create a Member Groups page/list/widget, with a little background on how Group Hierarchy extends the BuddyPress Groups loop. BuddyPress Groups loop overview If you&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>In this post, I&#8217;m going to show you how to create a Member Groups page/list/widget, with a little background on how Group Hierarchy extends the BuddyPress Groups loop.</p>
<h2>BuddyPress Groups loop overview</h2>
<p>If you aren&#8217;t familiar with <code>bp_has_groups()</code> from looking at the BuddyPress theme files, you should take a look at <a href="http://codex.buddypress.org/developer-docs/custom-buddypress-loops/the-groups-loop/">this overview</a> from the BP Codex before continuing.</p>
<p>In a nutshell, <code>bp_has_groups()</code> accepts a series of parameters which it uses to populate the global <code>$groups_template</code> variable with a set of groups. This, in turn, allows all the cool template functions to work without parameters cluttering up your theme file.</p>
<h2>How Group Hierarchy changes the Loop</h2>
<p>BuddyPress Group Hierarchy changes this in two important ways:</p>
<ol>
<li><code>bp_has_groups()</code> creates a set of <code>BP_Groups_Hierarchy</code> objects instead of <code>BP_Groups_Group</code> objects</li>
<li><code>bp_has_groups_hierarchy()</code> extends the loop with a <code>parent_id</code> parameter for getting only child groups of the passed group ID</li>
</ol>
<p>There are more changes made just for the Group Tree, but that&#8217;s enough to get us started. Onward!</p>
<h2>Creating a Member Groups list</h2>
<p>Before we build our Member Groups page / widget / list, there&#8217;s something you should know about working &#8220;in the loop,&#8221; i.e. in the context of the current group. The only thing telling BuddyPress what group we&#8217;re looking at is the <code>$groups_template</code> variable introduced above. Our member group list is going to change that variable, so we need to save its current state and restore it when we&#8217;re done.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// If you're in a function, bring $groups_template into scope</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Save the current group context for later</span>
<span style="color: #000088;">$current_group_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Using the Codex article I posted at the top as a reference, you&#8217;ll see how easy it is to create a Member Groups page / widget / whatever.</p>
<p>Just replace:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>with:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups_hierarchy<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 
	<span style="color: #0000ff;">'type'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'alphabetical'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'parent_id'</span> <span style="color: #339933;">=&gt;</span> bp_get_current_group_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>&#8230;and the rest works as is! Since 1.3.0, pagination is handled automatically.</p>
<p>Don&#8217;t forget to restore the original context!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$groups_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$current_group_template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>A complete example</h2>
<p>Here&#8217;s a quick example that adds a list of Member Groups on the Members page, above the list of users. Drop this in your <code>functions.php</code> file, or in a custom plugin, but note that it will only display if the parent group has at least one member!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_before_group_members_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_list_member_groups'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_func_list_member_groups<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// If you're in a function, bring $groups_template into scope</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Save the current group context for later</span>
	<span style="color: #000088;">$current_group_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups_hierarchy<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 
		<span style="color: #0000ff;">'type'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'alphabetical'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'parent_id'</span> <span style="color: #339933;">=&gt;</span> bp_get_current_group_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
	&lt;h3&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Member Groups'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;br /&gt;&amp;nbsp;&lt;/h3&gt;
&nbsp;
	&lt;div class=&quot;pagination&quot;&gt;
&nbsp;
		&lt;div class=&quot;pag-count&quot; id=&quot;group-dir-count&quot;&gt;
			<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_groups_pagination_count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		&lt;/div&gt;
&nbsp;
		&lt;div class=&quot;pagination-links&quot; id=&quot;group-dir-pag&quot;&gt;
			<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_groups_pagination_links<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		&lt;/div&gt;
&nbsp;
	&lt;/div&gt;
&nbsp;
	&lt;ul id=&quot;groups-list&quot; class=&quot;item-list&quot;&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> bp_groups<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> bp_the_group<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
		&lt;li&gt;
			&lt;div class=&quot;item-avatar&quot;&gt;
				&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_avatar<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'type=thumb&amp;width=50&amp;height=50'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;
			&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;item&quot;&gt;
				&lt;div class=&quot;item-title&quot;&gt;&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&lt;/div&gt;
				&lt;div class=&quot;item-meta&quot;&gt;&lt;span class=&quot;activity&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'active %s ago'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'buddypress'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> bp_get_group_last_active<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/span&gt;&lt;/div&gt;
&nbsp;
				&lt;div class=&quot;item-desc&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_description_excerpt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/div&gt;
&nbsp;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_directory_groups_item'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
				&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;action&quot;&gt;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_join_button<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
				&lt;div class=&quot;meta&quot;&gt;
					<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_type<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> / <span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_member_count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
				&lt;/div&gt;
&nbsp;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_directory_groups_actions'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
			&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;
		&lt;/li&gt;
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endwhile</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;/ul&gt;
&nbsp;
		<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_after_member_groups_loop'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
		&lt;div id=&quot;message&quot; class=&quot;info&quot;&gt;
		&lt;p&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'There were no member groups found.'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;
		&lt;/div&gt;
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// restore original group context!</span>
	<span style="color: #000088;">$groups_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$current_group_template</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>That&#8217;s it! Drop me a line in the comments if you find a novel use for this technique.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Highlighting Features with WordPress Admin Pointers &#8211; A Quick Guide for Plugin Authors</title>
		<link>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/</link>
		<comments>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 05:24:12 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=80</guid>
		<description><![CDATA[Here&#8217;s a quick intro to admin pointers for plugins to WordPress 3.3+, based on some work I recently put into making the help system in Networks more intuitive: Step One &#8212; Add the admin&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a quick intro to admin pointers for plugins to WordPress 3.3+, based on some work I recently put into making the help system in <a href="http://wordpress.org/extend/plugins/networks-for-wordpress/" title="Networks for WordPress">Networks</a> more intuitive:</p>
<h3>Step One &mdash; Add the admin pointer style and script to your page</h3>
<p>This is a fairly standard chain of <code>admin_menu</code> action functions, which should look familiar if you&#8217;re using a class for your plugin. If they don&#8217;t, some <a href="http://codex.wordpress.org/Administration_Menus">light background reading</a> may be in order.</p>
<p>You&#8217;ll need to create a script file for your admin page to follow this guide, although you could also dump the required JavaScript into the admin page itself.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> admin_menu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span> <span style="color: #339933;">=</span> add_menu_page<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'My Page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'My Page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'manage_options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my-page'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">FUNCTION</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	wp_register_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> plugins_url<span style="color: #009900;">&#40;</span>SCRIPT <span style="color: #990000;">FILE</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'admin_print_scripts-'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_admin_scripts'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'admin_print_styles-'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_admin_styles'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> add_admin_styles<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	wp_enqueue_style<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp-pointer'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> add_admin_scripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp-pointer'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wp_localize_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'strings'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">localize_admin_js</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In addition to enqueueing the admin pointer CSS and script files, we&#8217;ve set up a localization function.  Beside being good coding practice, generating the strings for the admin pointer here, instead of in the script file, is going to allow us to use a nice shortcut.</p>
<h3>Step Two &mdash; Build the pointer text and check for dismissal</h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> localize_admin_js<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;h3&gt;'</span> <span style="color: #339933;">.</span> esc_js<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'My Pointer Header'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/h3&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;p&gt;'</span> <span style="color: #339933;">.</span> esc_js<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'This is the text of my pointer.'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the list of dismissed pointers for the user</span>
	<span style="color: #000088;">$dismissed</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> get_user_meta<span style="color: #009900;">&#40;</span> get_current_user_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'dismissed_wp_pointers'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Check whether our pointer has been dismissed</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> POINTER HANDLE<span style="color: #339933;">,</span> <span style="color: #000088;">$dismissed</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'pointerText'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$pointer_text</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In testing, setting the pointer text to <code>''</code> was sufficient to hide the pointer from the screen. However, we can add another layer of protection in the script, which you&#8217;ll see below.</p>
<h3>Step Three &#8211; Script the pointer object gracefully</h3>
<p>If you don&#8217;t already have an admin script file, you&#8217;ll need to create one for this step.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">/** Check that pointer support exists AND that text is not empty */</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #339933;">&amp;&amp;</span> strings.<span style="color: #660066;">pointerText</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		jQuery<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#OBJECT_YOU_WANT_TO_POINT_AT'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
			content    <span style="color: #339933;">:</span> strings.<span style="color: #660066;">pointerText</span><span style="color: #339933;">,</span>
			close  <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				jQuery.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span> ajaxurl<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
					pointer<span style="color: #339933;">:</span> POINTER HANDLE<span style="color: #339933;">,</span>
					action<span style="color: #339933;">:</span> <span style="color: #3366CC;">'dismiss-wp-pointer'</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'open'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Note the <code>close</code> property of the pointer object: calling this action hooks us right into WordPress&#8217;s pointer management, so that when the user clicks the <code>Dismiss</code> button, our pointer is added to his list of dismissed pointers.  The <code>wp-pointer</code> stylesheet takes care of making the pointer look right so long as there&#8217;s an <code>&lt;h3&gt;</code> and one or more paragraphs, and the close button is added and wired up automatically.</p>
<p>Hope this helps anyone wishing to use this neat, new feature!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending BuddyPress Group Hierarchy &#8211; Join to Upstream Groups</title>
		<link>http://www.generalthreat.com/2011/12/extending-groups-hierarchy-join-upstream/</link>
		<comments>http://www.generalthreat.com/2011/12/extending-groups-hierarchy-join-upstream/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 18:23:16 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=74</guid>
		<description><![CDATA[Introduction A frequent feature request for BuddyPress Group Hierarchy has been to automatically join members of a subgroup to its parent groups. While pretty straightforward to implement, there are two main reasons this feature&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<h3>Introduction</h3>
<p>A frequent feature request for BuddyPress Group Hierarchy has been to automatically join members of a subgroup to its parent groups.  While pretty straightforward to implement, there are two main reasons this feature won&#8217;t make it into the plugin:</p>
<ol>
<li>This behavior isn&#8217;t appropriate for many or even most setups</li>
<li>Everyone who has requested it has wanted it to work on groups by different criteria &mdash; some want groups of a certain depth, others a specific set of groups, others all the children of a certain group. Building a UI that would let this work the way anyone wants would overwhelm the project.</li>
</ol>
<p>Instead, I decided to post this sample implementation, including a few ways to select groups. Take a look!</p>
<h3>The Code</h3>
<p><ins datetime="2011-12-08T11:55:27+00:00">The code below can be included in your theme&#8217;s <code>functions.php</code> file, or can be part of a new plugin.</ins></p>
<p><strong>Note for the true novice:</strong> you must <strong>choose one</strong> of the <code>if</code> statements in the block below with this code and substitute the placeholders for things you care about. It will not work pasted as is.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/* groups_join_group is called whenever someone joins a group in both BP 1.2 and 1.5.x */</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'groups_join_group'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_join_group_action'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_join_group_action<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$group_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_id</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">/* This part is critical - you must select ONLY the groups you want to START this chain
	 * This function will recurse up to the toplevel on its own, so if you have a parent group
	 * in the list, you will waste resources trying to join the same group multiple times
	 * as this function is called on each step up the tree
	 */</span> 
	<span style="color: #009933; font-style: italic;">/** Pick from a list of groups */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$group_id</span><span style="color: #339933;">,</span> ARRAY_OF_GROUPS_I_CARE_ABOUT <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">/* -- OR -- */</span>
	<span style="color: #009933; font-style: italic;">/** Select groups by depth */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> bp_group_hierarchy_get_parents<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> DEPTH_OF_GROUP_I_CARE_ABOUT_EG_3 <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">/* -- OR ANYTHING ELSE YOU LIKE */</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">/* However you choose to select groups, once the group_id matched this part will 
		 * walk up the tree, joining the user to each parent group along the way
		 */</span>
&nbsp;
		<span style="color: #000088;">$parents</span> <span style="color: #339933;">=</span> bp_group_hierarchy_get_parents<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$parents</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$parent_group_id</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			groups_join_group<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$parent_group_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_id</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>If this helps you, or if you have some code to select the groups that matter to YOU, feel free to post in the comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2011/12/extending-groups-hierarchy-join-upstream/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress Plugin Help Panels with WP_Screen &#8211; Features and Limits</title>
		<link>http://www.generalthreat.com/2011/11/wordpress-help-panels-with-wp_screen/</link>
		<comments>http://www.generalthreat.com/2011/11/wordpress-help-panels-with-wp_screen/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 21:31:40 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=70</guid>
		<description><![CDATA[With version 3.3 (currently at beta 4), WordPress has introduced the WP_Screen API for adding rich help screens to your plugin&#8217;s admin page(s). This is still a very new API so, even though some&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>With version 3.3 (currently at beta 4), WordPress has introduced the WP_Screen API for adding rich help screens to your plugin&#8217;s admin page(s).  This is still a very new API so, even though some options functions exist, you won&#8217;t be making crazy customizations or replacing meta boxes just yet.</p>
<p><ins datetime="2011-12-07T18:27:39+00:00"><strong>Update:</strong> version 3.3 is current at RC 2 and, while there have been many internal improvements, the API still works as described below.</ins></p>
<h3>Creating an admin page and WP_Screen instance</h3>
<p>Creating an admin page for your plugin hasn&#8217;t changed, but it&#8217;s more important than ever to save the handle of your admin page.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Save the handle to your admin page - you'll need it to create a WP_Screen object
	 */</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span> <span style="color: #339933;">=</span> add_options_page<span style="color: #009900;">&#40;</span> 
		__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WP_Screen Test'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'my-plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
		__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WP_Screen Test'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'my-plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
		<span style="color: #0000ff;">'manage_options'</span><span style="color: #339933;">,</span> 
		<span style="color: #0000ff;">'wp_screen_test'</span><span style="color: #339933;">,</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'test_page'</span><span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/** Use this hook to catch your admin page's loading */</span>
	add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;load-<span style="color: #006699; font-weight: bold;">{$this-&gt;admin_page}</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'create_help_screen'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> create_help_screen<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/** 
	 * Create the WP_Screen object against your admin page handle
	 * This ensures we're working with the right admin page
	 */</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span> <span style="color: #339933;">=</span> WP_Screen<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>Working with WP_Screen &#8211; Tabs and the Sidebar</h3>
<p>The main feature of the new Help tab system is the ability to divide your help menu into separate sections without a lot of effort.</p>
<p>For each help tab you want to create, call the <code>add_help_tab</code> method to build it.  You can specify the content of the help tab inline, or use a callback to generate it.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Inline tab content
	 */</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_help_tab</span><span style="color: #009900;">&#40;</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'title'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Help'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'id'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'help_tab'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'content'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;p&gt;This is my content.&lt;/p&gt;'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span>
		<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Content generated by callback
	 * The callback fires when tab is rendered - args: WP_Screen object, current tab
	 */</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_help_tab</span><span style="color: #009900;">&#40;</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'title'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Info on this Page'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'id'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'page_info'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'content'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">create_function</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'echo &quot;&lt;p&gt;This is my generated content.&lt;/p&gt;&quot;;'</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The sidebar is a much nicer way to display the list of links we&#8217;ve often put at the bottom of the help panel.  It&#8217;s displayed regardless of which tab is selected.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set_help_sidebar</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'&lt;p&gt;This is my help sidebar content.&lt;/p&gt;'</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>WP_Screen and Options</h3>
<p><code>WP_Screen</code> excels at handling help pages. Unfortunately, the only options it seems to recognize with the <code>add_option</code> method are the built-in <code>per_page</code> and <code>layout_columns</code>.  Anything else simply isn&#8217;t displayed.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
		<span style="color: #0000ff;">'per_page'</span><span style="color: #339933;">,</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Entries per page'</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'option'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'edit_per_page'</span>
		<span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
		<span style="color: #0000ff;">'layout_columns'</span><span style="color: #339933;">,</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'max'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span>
		<span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * This option will NOT show up
	 */</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
		<span style="color: #0000ff;">'invisible_option'</span><span style="color: #339933;">,</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'label'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'I am a custom option'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'wow'</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'max'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span>
		<span style="color: #009900;">&#41;</span> 
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>But you can use a metabox to at least get a custom checkbox generated.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Old-style metaboxes still work for creating custom checkboxes in the option panel
	 * This is a little hack-y, but it works
	 */</span>
	add_meta_box<span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'my_meta_id'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'My Metabox'</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'create_my_metabox'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And here&#8217;s the complete skeleton:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP 3.3 WP_Screen Test
Version: 1.0
*/</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> wp_screen_test <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$slug</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'screentest'</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$admin_page</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$admin_screen</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'admin_menu'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin_menu'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> admin_menu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/**
		 * Save the handle to your admin page - you'll need it to create a WP_Screen object
		 */</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span> <span style="color: #339933;">=</span> add_options_page<span style="color: #009900;">&#40;</span> 
			__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WP_Screen Test'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'my-plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
			__<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WP_Screen Test'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'my-plugin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'manage_options'</span><span style="color: #339933;">,</span> 
			<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">slug</span><span style="color: #339933;">,</span> 
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'test_page'</span><span style="color: #009900;">&#41;</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;load-<span style="color: #006699; font-weight: bold;">{$this-&gt;admin_page}</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'create_help_screen'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> create_help_screen<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/** 
		 * Create the WP_Screen object against your admin page handle
		 * This ensures we're working with the right admin page
		 */</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span> <span style="color: #339933;">=</span> WP_Screen<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/**
		 * Content specified inline
		 */</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_help_tab</span><span style="color: #009900;">&#40;</span>
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'title'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Help'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'id'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'help_tab'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'content'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;p&gt;This is my content.&lt;/p&gt;'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span>
			<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/**
		 * Content generated by callback
		 * The callback fires when tab is rendered - args: WP_Screen object, current tab
		 */</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_help_tab</span><span style="color: #009900;">&#40;</span>
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'title'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Info on this Page'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'id'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'page_info'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'content'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">create_function</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'echo &quot;&lt;p&gt;This is my generated content.&lt;/p&gt;&quot;;'</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set_help_sidebar</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'&lt;p&gt;This is my help sidebar content.&lt;/p&gt;'</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
			<span style="color: #0000ff;">'per_page'</span><span style="color: #339933;">,</span> 
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'label'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Entries per page'</span><span style="color: #339933;">,</span> 
				<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">,</span> 
				<span style="color: #0000ff;">'option'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'edit_per_page'</span>
			<span style="color: #009900;">&#41;</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
			<span style="color: #0000ff;">'layout_columns'</span><span style="color: #339933;">,</span> 
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> 
				<span style="color: #0000ff;">'max'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span>
			<span style="color: #009900;">&#41;</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/**
		 * This option will NOT show up
		 */</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_option</span><span style="color: #009900;">&#40;</span> 
			<span style="color: #0000ff;">'invisible_option'</span><span style="color: #339933;">,</span> 
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'label'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'I am a custom option'</span><span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'wow'</span><span style="color: #339933;">,</span> 
				<span style="color: #0000ff;">'option'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'my_option_id'</span>
			<span style="color: #009900;">&#41;</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/**
		 * But old-style metaboxes still work for creating custom checkboxes in the option panel
		 * This is a little hack-y, but it works
		 */</span>
		add_meta_box<span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'my_meta_id'</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'My Metabox'</span><span style="color: #339933;">,</span>
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'create_my_metabox'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> test_page<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Plugin options page content</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> screen_test_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$screenTest</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> wp_screen_test<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'init'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'screen_test_init'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2011/11/wordpress-help-panels-with-wp_screen/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Pull Parsing ARIN WHOIS Data in PHP</title>
		<link>http://www.generalthreat.com/2011/11/parsing-arin-whois-data-in-php/</link>
		<comments>http://www.generalthreat.com/2011/11/parsing-arin-whois-data-in-php/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 02:56:47 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=68</guid>
		<description><![CDATA[At JerseyConnect, we have been using the Bulk WHOIS Data from ARIN for a few years now, mostly as a diagnostic tool for libraries concerned about their bandwidth usage, but also for capacity planning and judging peering options. After years of using the flat text format dumps, this week I decided to take the plunge and change to the much larger &#8212; but much better structured &#8212; XML formatted files. Here's how I did it!]]></description>
				<content:encoded><![CDATA[<p>At <a href="http://www.jerseyconnect.net/">JerseyConnect</a>, we&#8217;ve been using the <a href="https://www.arin.net/resources/request/bulkwhois.html">Bulk WHOIS Data from ARIN</a> for a few years now, mostly as a diagnostic tool for libraries concerned about their bandwidth usage, but also for capacity planning and judging peering options. After years of using the flat text format dumps, this week I decided to take the plunge and change to the much larger &mdash; but much better structured &mdash; XML formatted files. Here&#8217;s how I did it.</p>
<h4>TL;DR? <a href="#arin_parser">Skip to the solution!</a></h4>
<h3>The Old Way &#8211; The Flat Text Dump</h3>
<p>ARIN bulk WHOIS data was originally available only as a flat text dump from their database. This format made it easy to convert into individual records into a data structure, as it came in a pseudo-tab delimited format.  But it lacked any structure, and you had to convert each record and inspect its properties to determine its type. This slowed down processing significantly.</p>
<p>I had written a parser for the flat text dump format when we first started using the data and it worked well enough that we&#8217;ve stuck with it.  However, not every record in the flat text file has every key, and some fields are used differently between records, so it had to be built with a maze of filters and regular expressions and ended up an unmanageable mess with sections like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/** create or re-create any missing fields */</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/** sometimes street address is its own field, but sometimes not */</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Street'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'City'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/(.*?)[\s]{2,}(.*?)/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #009933; font-style: italic;">/** if there is a clear break, use it to delineate city from street */</span>
			<span style="color: #000088;">$addr</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_split</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/[\s]{2,}/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$addr</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$addr</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #009933; font-style: italic;">/** 
			 * if we can't tell just grab everything but the last word
			 * This misses cases like &quot;Los Angeles&quot; and &quot;Palm Beach&quot; but it will have to do
			 */</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #990000;">strrpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #990000;">strrpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #009933; font-style: italic;">/** if there is no data, just put in blanks */</span>
		<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'City'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Company'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Company'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FirstName'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'LastName'</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'LastName'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">','</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span><span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'LastName'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'LastName'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'FirstName'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$record</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'FirstName'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>The New Way &#8211; XML Format</h3>
<p>In XML, the bulk WHOIS data is huge &mdash; at over 3 <strong>GB</strong> and growing by over 25 MB per month, it is about 3x the size of the flat file &mdash; but is far more consistent in terms of structure.  This makes writing the parser MUCH more straightforward. The biggest problem is the sheer size, and for that we have <a href="http://php.net/manual/en/book.xmlreader.php">XMLReader</a>.</p>
<h3>Parsing a Large XML File</h3>
<p>Since the file is so large, we need to read it piece by piece.  Fortunately, XMLReader makes this simple. No more chunking with <code>fread()</code> or <code>fget*</code> variants!  While this post is about parsing ARIN data, not general XML, here&#8217;s an example of how easy it is to get started with XMLReader:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$xmlHandle</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XMLReader<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$xmlStatus</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">open</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'any_xml_file.xml'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009933; font-style: italic;">/** any processing on current node */</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeValue</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xmlStatus</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The modest code above will scan an XML file of any size without running out of memory. Of course, depending on how deeply nested your data is, it may take a VERY long time.</p>
<p class="note">For more information on XML processing with PHP, see this excellent IBM series, &#8220;XML for PHP developers&#8221; (<a href="http://www.ibm.com/developerworks/xml/library/x-xmlphp1/index.html">part 1</a>) (<a href="http://www.ibm.com/developerworks/xml/library/x-xmlphp2/index.html">part 2</a>).</p>
<h3>Parsing the ARIN WHOIS XML File</h3>
<p>Our parser needs to be tailored to the ARIN WHOIS data.  We want it to locate the four types of record (ASN, NET, ORG, and POC) that may be in the file we&#8217;re scanning and hand them off to subordinate functions as efficiently as possible.</p>
<p><a name="arin_parser"></a>Here&#8217;s the finished skeleton parser:</p>
<h5>ARIN XML Parser &#8211; Skeleton</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * ARIN Bulk XML Data Parser class
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Parse_ARIN <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$xmlStatus</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$xmlHandle</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$startTime</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * @param string XMLFile File containing bulk whois data in XML format
	 */</span>
	<span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$xmlFile</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XMLReader<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ob_get_level</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xmlFile</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xmlFile</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">open</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$xmlFile</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">function</span> __destruct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/** Report time taken */</span>
		<span style="color: #000088;">$endTime</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Processed '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">count</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' records in: '</span> <span style="color: #339933;">.</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$endTime</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">startTime</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' seconds.'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setSource<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$xmlFile</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xmlFile</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">open</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$xmlFile</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> process<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlStatus</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">startTime</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">scan</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Echo progress to the browser and continue execution
	 * @param string Message Message to be echoed
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> report<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$message</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #990000;">str_pad</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4096</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">ob_flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> scan<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'asn'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'net'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'poc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'org'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeType</span> <span style="color: #339933;">==</span> XMLREADER<span style="color: #339933;">::</span><span style="color: #004000;">ELEMENT</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'asn'</span><span style="color: #339933;">:</span>
						<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveASNRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
					<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'net'</span><span style="color: #339933;">:</span>
						<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveNETRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
					<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'org'</span><span style="color: #339933;">:</span>
						<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">saveORGRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
					<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'poc'</span><span style="color: #339933;">:</span>
						<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">savePOCRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">count</span><span style="color: #339933;">++;</span>
				<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">count</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">10000</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">report</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Processed: '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">count</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' records.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlHandle</span><span style="color: #339933;">-&gt;</span><span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Convert the DOMNode into a SimpleXML object for manipulation
	 * @param DOMNode RecordData XML data from the file being scanned
	 * @return SimpleXMLElement
	 */</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> processRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$recordData</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #009933; font-style: italic;">/** From Listing 9: http://www.ibm.com/developerworks/xml/library/x-xmlphp2/index.html */</span>
		<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DomDocument<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$n</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">importNode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$recordData</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">appendChild</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">simplexml_import_dom</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$n</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> saveASNRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$asnNode</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$record</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$asnNode</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> saveNETRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$netNode</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$record</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$netNode</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> saveORGRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$orgNode</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$record</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$orgNode</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> savePOCRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pocNode</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$record</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pocNode</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>Calling the ARIN Parser</h4>
<p>The class we created keeps the surface area as small as possible.  We can now use the parser with just a few lines of code.</p>
<h5>Calling the ARIN Parser &#8211; Sample Code</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$ARIN</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Parse_ARIN<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'arin_db.xml'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$ARIN</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">report</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Starting process...'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$ARIN</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">process</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>Processing the XML Data</h4>
<p>In order to do something useful with the data, like store it in a database or display it to the screen, you can alter the <code>save{TYPE}Record</code> functions (or extend the parser) to suit your needs.  Here&#8217;s an example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> savePOCRecord<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pocNode</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$record</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processRecord</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$pocNode</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * DB structure:
	 * POCHandle (PK)
	 * IsRole
	 * Company
	 * LastName
	 * FirstName
	 * RoleName
	 * Street
	 * City
	 * State
	 * Country
	 * PostalCode
	 * RegDate
	 * Updated
	 * OfficePhone
	 * Mailbox
	 */</span>
&nbsp;
	<span style="color: #000088;">$POCrecord</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'POCHandle'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">handle</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'IsRole'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isRoleAccount</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'Y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'Company'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">companyName</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'LastName'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">lastName</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'FirstName'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">firstName</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'RoleName'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'Street'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'City'</span>			<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">city</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'State'</span>			<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">'iso3166-2'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'Country'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">'iso3166-1'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">code2</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'PostalCode'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">postalCode</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'RegDate'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">registrationDate</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'Updated'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">updateDate</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'OfficePhone'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">phones</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">phone</span><span style="color: #009900;">&#41;</span> ? <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">phones</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">phone</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">number</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">phoneNumber</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'Mailbox'</span>		<span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">emails</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">email</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/** create or re-create any missing fields */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">streetAddress</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">line</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$streetAddress</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_object_vars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">streetAddress</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$POCrecord</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'companyName'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$POCrecord</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Company'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_shift</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$streetAddress</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'line'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$POCrecord</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">join</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$streetAddress</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'line'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">streetAddress</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">line</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$POCrecord</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Street'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span><span style="color: #000088;">$record</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">streetAddress</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">line</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$POC_DB</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$POCrecord</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Other Notes &#8211; Processing Speed</h3>
<p>Finally, this data set is big enough that I thought a quick analysis might be a useful contribution to the age-old if/else vs. switch debate.</p>
<p>Here are the results for iterating over the approx. 4.6 million records in this file without further processing. Tests were run on Win7/PHP 5.3.5:</p>
<table>
<thead>
<tr>
<th scope="col">Method</th>
<th scope="col">Min. time (seconds)</th>
<th scope="col">Max. time (seconds)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">No Test</th>
<td>141.1</td>
<td>141.6</td>
</tr>
<tr>
<th scope="row">If/Else</th>
<td>149.1</td>
<td>150.2</td>
</tr>
<tr>
<th scope="row">Switch</th>
<td>147.7</td>
<td>147.7</td>
</tr>
</tbody>
</table>
<p>Copyright 2011, David Dean. All rights reserved. The code on this page is provided under the terms of the <a href="http://www.opensource.org/licenses/BSD-3-Clause">Modified BSD License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2011/11/parsing-arin-whois-data-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced

 Served from: www.generalthreat.com @ 2026-06-14 16:23:09 by W3 Total Cache -->