<?php
/*
Plugin Name: Oaktree
Plugin URI: http://janit.iki.fi/oaktree/
Description: Generates a nested unordered list of your pages
Version: 0.5
Author: Jani Tarvainen
Author URI: http://janit.iki.fi/

INSTALLATION:

	1. copy oaktree.php to wp-content/plugins/
	2. make sure you've got permalinks on
	3. activate plugin
	4. place the appropriate code where you want the navigation to appear

		full tree: <?php global $oaktree; $oaktree->writeNavigation(); ?>

		custom tree: <? global $oaktree;
				
				// exclude pages 4 and 5
				$noShow = array(4,5);
				$oaktree->writeNavigation(false,'',$noShow);

				?>

		write crumbs:	<?php $oaktree->writeCrumbs(); ?>
				<h1><?php the_title(); ?></h1>

	Remember that you can customize the tree as you wish (ad categories by hand, etc.) and
	that XHTML+CSS has some great tricks for this stuff... you should get it:

	<div id="naviContainer"><?php global $oaktree; $oaktree->writeNavigation(); ?></div>

	<style type="text/css">
	#naviContainer * {
		display:block;
		margin:0;
		padding:0;
	}

	#naviContainer a {
		text-decoration:none;
		padding:5px;
	}

	#naviContainer a:hover {
		text-decoration:underline;
	}

	#naviContainer a.selected {
		font-weight:bold;
	}

	#naviContainer li li {
		padding-left:15px;
		font-weight:normal;
	}
	</style>

*/

// add action to init
$oaktree = new oaktree();
add_action('init',array(&$oaktree, 'initialize'));

class oaktree {

	var $tree = array();

	// constructor
	function oaktree() {
		if (!strpos($_SERVER[REQUEST_URI],'/wp-admin/')){
			$this->tree = $this->buildTree(0,get_bloginfo('wpurl').'/','');
		}
	}
	
	function initialize(){

		// do tree inserts, etc. in the future
		
	}

	// build a hierarchical array of your page structure, used recursively
	function buildTree($parent=0,$prevPath='/',$exclude=''){
	
	// build exclude string
	$excludeString = '';
	
	if ($exclude){
		$toExclude = explode(',',$exclude);
	
		foreach ($toExclude as $pageId){
			$excludeString.= "AND p.ID != $pageId ";
		}
	}
	
	// set query
	$query = "
	SELECT ID, post_title, post_parent, post_name
	FROM wp_posts as p
	WHERE post_category = 0
		$excludeString
		AND post_parent = $parent
		AND post_status = 'static'
	ORDER by menu_order
	";
	
	// do query
	$pages = $GLOBALS[wpdb]->get_results($query);
	
	
	if($pages){
	
	// loop through the results
	foreach ($pages as $page){

	// check is branch active
	if(strpos($_SERVER[REQUEST_URI],"$page->post_name/")){
		$isActive = true;
		
		$GLOBALS['oaktree_crumbID'][] = $page->ID;
		$GLOBALS['oaktree_crumbs'][] = array (
			'title' => $page->post_title,
			'path' => $prevPath.$page->post_name.'/',
		);
	}

	// insert page to array
	$pagetree[$page->ID] = array (
		"id" => $page->ID,
		"title" => $page->post_title,
		"path" => $prevPath.$page->post_name.'/',
		"active" => $isActive,
	);

	// if page is active, get sub pages
	if ($isActive) {
		$pagetree[$page->ID][sub] = $this->buildTree($page->ID, $prevPath.$page->post_name.'/',$exclude);
	}

	unset($isActive);	

	}
	}

	return $pagetree;
	
	} // end buildTree

	function returnTree($id='0'){
	  if($id){
	    $subTree = $this->tree;
	    return $subTree[$id][sub];
	  } else {
	  return $this->tree;
	  }
	}

	function setPath($id,$newPath){
	  $this->tree[$id][path] = $newPath;
	}

	function writeNavigation($noUnfold=false, $noShow='', $tempTree='',$widget=''){

	// if no tree given, use full
	if(!$tempTree){
		$tempTree = $this->tree;
	}

	// begin list
	echo "\n"; ?><ul><? echo "\n";

	// loop pages
	foreach($tempTree as $page){
	
		// if active, set class
		if($page[active]){
			$classString = ' class="selected"';

		if($widget){
		  $page[title] = $widget.$page[title];
		} 
		}

		if(!in_array($page[id],$noShow)){

		// write item
		?><li><a href="<?=$page[path]; ?>"<?=$classString; ?>><?=$page[title]; ?></a><?

		// if active, get subpages
		if ($page[active] && $page[sub] && !$noUnfold) {
			$this->writeNavigation($noUnfold, $noShow, $tempTree[$page[id]][sub]);
		}

		// finish list, unset classString
		?></li><? // echo "\n";

		}

		unset($classString);
		
	}

	// end list
	?></ul><? echo "\n";
	
	} // end writeNavigation

	// generate exclude string for query
	function generateExcludeString($exclude='',$rulingField='p.ID') {
	
	$excludeString = '';
	
	if ($exclude){
		$toExclude = explode(',',$exclude);
	
		foreach ($toExclude as $pageId){
			$excludeString.= "AND $rulingField != $pageId ";
		}
	}
	
	return $excludeString;
	
	} // end generateExcludeString

	function writeCrumbs(){

	global $oaktree_crumbs;

	// let the current page have it!
	array_pop($oaktree_crumbs);

	?><div><?
	foreach($oaktree_crumbs as $link){
		?><a href="<?=$link[path]; ?>"><?=$link[title]; ?></a> &raquo; <?php
	};
	?></div><?
	}

}
