Moab Trip 2009 “The Plants” Photoset

I’ve finally synchronized my camera’s memory with my laptop and began sorting through the pictures I took on my trip to Moab, Utah in June. Below are some of the better shots of plants in the area. Surprisingly, many of the plants were still green and flowering, or just finished flowering. It’s too bad I don’t have anything better than a Cannon PowerShot SD850 IS with CHDK, getting it to focus on the correct object can be a pain at times (plus there is a caveat with using 4GB SDHC cards (FAT32 format is the culprit) and CHDK where it won’t auto boot).

-John Havlik

[end of transmission, stay tuned]

goto code_hell;

code_hell: echo 'Yes, PHP 5.3 has the goto operator';

In one’s opinion, the only people that should be allowed to use the goto operator are expert assembly language programmers (and you are not one). Besides, most things written in PHP are not “low level” enough to warrant the use of goto. However, if you must use the goto operator, please do so responsibly. Use it as if it costs $10,000 per use, and properly document what’s going on.

-John Havlik

[end of transmission, stay tuned]

Windows 7 PunkBuster Revisit

Well, well, well, look what we have here. Looks like Even Balance finally got their act together. Anyone taking part in the Battlefield Heroes Beta will know that DICE now has PunkBuster enabled for it. Amazingly, Battlefield Heroes still works in Windows 7, no false-positive PunkBuster related kicks. Even better, the PunkBuster client for Battlefield 2142 now works correctly on Windows 7 64Bit now as well. One was able to play on four different Battlefield 2142 servers for more than 30 minutes each today without a single kick, therefore the PunkBuster related issues appear to be solved. No hacks, no compatibility mode, no running as administrator, it just works. Hurray for silent updates! Oh wait, they are still a major security risk.

-John Havlik

[end of transmission, stay tuned]

Let’s Play a Game

Question: What causes the following error in Apache’s error logs?

[IP_address] Undeclared entity warning at line 226, column 1

Answer: A fairly popular, yet, poorly written WordPress plugin.

The first time this error hit the Weblogs.us error_log, one had no clue what was causing it. Unfortunately, the error does not indicate what file triggers the error. However, it will include the referring URI, if applicable. That’s how one found the specific virtual host on the Weblogs.us server that was triggering the error. Next, was finding the infringing code. To do this, one added define('WP_DEBUG', true); to the wp-config.php file for the virtual host. Now, there will be an avalanche of errors and warnings for most sites, all that needs to be done is sift through them and look for ones like “undeclared variable” and “undeclared index”.

Now, what was the actual culprit? The Twitter-for-Wordpress plugin. Specifically, lines 100, and 158. Line 100 tries to increment a non-initialized variable. To fix the issue on line 100, add a new line between line 66 and 67 and place in it $i = 0;. The error on line 158 is it tries to use the undeclared variable $username. What probably happened was author copied the line directly from line 53, while not properly modified for its location. Line 158 should read:
$messages = fetch_rss('http://twitter.com/statuses/user_timeline/'.$item['username'].'.rss');

After these two changes everything should be good to go. Yes, the plugin author was notified of these problems. We’ll see when they officially get fixed in the plugin.

-John Havlik

[end of transmission, stay tuned]

Keep a Page Out of the Breadcrumb Trail

Note: This guide is only valid for versions of Breadcrumb NavXT prior to 4.0. Since Breadcrumb NavXT 4.0 the bcn_after_fill action should be used to remove breadcrumbs from the breadcrumb trail.

In the past, several users have asked how to exclude certain pages from the breadcrumb trail generated by Breadcrumb NavXT. As with most programming problems, many solutions exist to this problem. Previously, one posted code that removed the breadcrumb from the bcn_breadcrumb_trail::trail array before calling bcn_breadcrumb_trail::display(). However, since the introduction of Breadcrumb NavXT 3.0 a much better solution exists. This method uses the inheritance principle of OOP and requires no editing of the distributed files.

Code in this tutorial was written against the SVN Trunk version of Breadcrumb NavXT (the basis or Breadcrumb NavXT 3.3.0). Therefore, any code contained herein will require some modifications to work with Breadcrumb NavXT 3.2.x. The general process, however, is the same for any version of Breadcrumb NavXT since 3.0.0. Also, note that you must have a PHP5 environment for this to work as it requires the PHP5 object model.

First, open the functions.php file of your theme. Within it we are going to create a new class named ext_breadcrumb_trail, and tell PHP that it is an extension of the bcn_breadcrumb_trail class. We’ll place the skeleton for the class constructor in at this time as well.

class ext_breadcrumb_trail extends bcn_breadcrumb_trail
{
	//Default constructor
	function __construct()
	{
		//Need to make sure we call the constructor of bcn_breadcrumb_trail
		parent::__construct();
	}
}

We need a way to get the IDs that will be excluded from the trail into the class. They could be hard coded into the class, but that is not very extensible (and a very bad coding practice). Instead, a public member variable named $excluded_ids will be added to store the IDs. Now, we should have the constructor accept IDs to exclude and store them in $excluded_ids. Our code now looks similar to the following:

class ext_breadcrumb_trail extends bcn_breadcrumb_trail
{
	public $excluded_ids = array();
	//Default constructor
	function __construct($excluded_ids)
	{
		//Set the value of
		$this->excluded_ids = $excluded_ids;
		//Need to make sure we call the constructor of bcn_breadcrumb_trail
		parent::__construct();
	}
}

Now that the IDs of pages to be excluded can get into the class, we need to do something with them. We want to override the function bcn_breadcrumb_trail::page_parents() since it does not know how to exclude pages. To start, we’ll copy the code for page_parents from the class bcn_breadcrumb_trail into our new class. This is the result:

class ext_breadcrumb_trail extends bcn_breadcrumb_trail
{
	public $excluded_ids = array();
	function __construct($excluded_ids)
	{
		$this->excluded_ids = $excluded_ids;
		parent::__construct();
	}
	/**
	 * page_parents
	 *
	 * A Breadcrumb Trail Filling Function
	 *
	 * This recursive functions fills the trail with breadcrumbs for parent pages.
	 * @param  (int)   $id The id of the parent page.
	 * @param  (int)   $frontpage The id of the front page.
	 */
	function page_parents($id, $frontpage)
	{
		$parent = get_post($id);
		//Place the breadcrumb in the trail, uses the constructor
		$breadcrumb = $this->add(new bcn_breadcrumb(apply_filters('the_title', $parent->post_title), $this->opt['page_prefix'], $this->opt['page_suffix']));
		//Assign the anchor properties
		$breadcrumb->set_anchor($this->opt['page_anchor'], get_permalink($id));
		//Make sure the id is valid
		if($parent->post_parent >= 0 && $parent->post_parent != false && $id != $parent->post_parent && $frontpage != $parent->post_parent)
		{
			//If valid, recursively call this function
			$this->page_parents($parent->post_parent, $frontpage);
		}
	}
}

Now, it’s time to modify the page_parents() function. We’ll use ext_breadcrumb_trail::excluded_ids and the PHP function in_array() to skip the breadcrumb insertion step for pages that are to be excluded from the trail. We do this by wrapping the two lines of code containing the variable $breadcrumb within a branch of an if statement. Within the if statement we’ll use $id and $this->excluded_ids as the parameters for in_array(). Since we want the branch to run if the ID is not an excluded ID, we’ll place the not operator (!) in front of in_array. At this point, we have the final version of our class that is ready to use.

class ext_breadcrumb_trail extends bcn_breadcrumb_trail
{
	public $excluded_ids = array();
	function __construct($excluded_ids)
	{
		$this->excluded_ids = $excluded_ids;
		parent::__construct();
	}
	/**
	 * page_parents
	 *
	 * A Breadcrumb Trail Filling Function
	 *
	 * This recursive functions fills the trail with breadcrumbs for parent pages.
	 * @param  (int)   $id The id of the parent page.
	 * @param  (int)   $frontpage The id of the front page.
	 */
	function page_parents($id, $frontpage)
	{
		$parent = get_post($id);
		//Check if the current page should be excluded
		if(!in_array($id, $this->excluded_ids))
		{
			//Place the breadcrumb in the trail, uses the constructor
			$breadcrumb = $this->add(new bcn_breadcrumb(apply_filters('the_title', $parent->post_title), $this->opt['page_prefix'], $this->opt['page_suffix']));
			//Assign the anchor properties
			$breadcrumb->set_anchor($this->opt['page_anchor'], get_permalink($id));
		}
		//Make sure the id is valid
		if($parent->post_parent >= 0 && $parent->post_parent != false && $id != $parent->post_parent && $frontpage != $parent->post_parent)
		{
			//If valid, recursively call this function
			$this->page_parents($parent->post_parent, $frontpage);
		}
	}
}

Next, we need to modify the breadcrumb trail calling code in the theme. Assuming that the theme directly calls the bcn_breadcrumb_trail class, very little has to be modified. We just replace all instances of bcn_breadcrumb_trail with ext_breadcrumb_trail in the calling code. Additionally, when creating the new instance of ext_breadcrumb_trail we need to feed in our array of IDs of pages to be excluded. An example calling code block is located below, in it pages with ID equal to 100, 230, or 231 will not show up in the breadcrumb trail except when they are the current page.

if(class_exists('ext_breadcrumb_trail'))
{
	//Make new instance of the ext_breadcrumb_trail object
	$breadcrumb_trail = new ext_breadcrumb_trail(array(100,230,231));
	//Setup options here if needed
	//Fill the breadcrumb trail
	$breadcrumb_trail->fill();
	//Display the trail
	$breadcrumb_trail->display();
}

In this tutorial we never modified any of the actual plugin files. This was made possible due to inheritance through the creation of a derived class. Since no plugin files were modified, upgrading to new versions of Breadcrumb NavXT are less likely to break the functionality. Finally, this method can easily be modified to exclude categories instead of pages from the breadcrumb trail (replace page_parents with category_parents).

-John Havlik

[end of transmission, stay tuned]