<?php

/**
 *--------------------------------------
 * 树形结构
 *--------------------------------------
 * @project		: pfa
 * @author		: cblee
 * @created		: 2012-12-13
 * @copyright	: (c)2012 AsThis
 *--------------------------------------
 */

class ATree
{
	private $data; /* 树型数据 */
	private $fields; /* 字段名 */
	private $root; /* 顶级分类的父id */
	private $tmp;
	private $arr; /* 结果数组 */
	private $str; /* 结果字符串 */
	private $already = array();
	public $icon = array('┃', '┣', '┗', '　'); //修饰符号

	/** 构造函数 */
	public function __construct($data, $fields = array('id', 'pid', 'child'), $root = 0)
	{
		$this->data = $data;
		$this->fields = $fields;
		$this->root = $root;
		$this->handler();
	}

	/** 树型数据表结果集处理 */
	private function handler()
	{
		foreach($this->data as $node)
		{
			$tmp[$node[$this->fields[1]]][] = $node;
		}
		krsort($tmp);
		for($i = count($tmp); $i > 0; $i--)
		{
			foreach($tmp as $k => $v)
			{
				if(!in_array($k, $this->already))
				{
					if(!$this->tmp)
					{
						$this->tmp = array($k, $v);
						$this->already[] = $k;
						continue;
					}
					else
					{
						foreach($v as $key => $value)
						{
							if($value[$this->fields[0]] == $this->tmp[0])
							{
								$tmp[$k][$key][$this->fields[2]] = $this->tmp[1];
								$this->tmp = array($k, $tmp[$k]);
							}
						}
					}
				}
			}
			$this->tmp = null;
		}
		$this->tmp = $tmp;
	}

	/** 反向递归 */
	private function recur_n($arr, $id)
	{
		foreach($arr as $v)
		{
			if($v[$this->fields[0]] == $id)
			{
				$this->arr[] = $v;
				if($v[$this->fields[1]] != $this->root)
				{
					$this->recur_n($arr, $v[$this->fields[1]]);
				}
			}
		}
	}

	/** 正向递归 */
	private function recur_p($arr)
	{
		foreach($arr as $v)
		{
			$this->arr[] = $v[$this->fields[0]];
			if($v[$this->fields[2]])
			{
				$this->recur_p($v[$this->fields[2]]);
			}
		}
	}

	/** 菜单 多维数组 $id:分类id. 返回分支，默认返回整个树 */
	public function get_leaf($id = null)
	{
		$id = ($id == null) ? $this->root : $id;
		return $this->tmp[$id];
	}

	/** 导航 一维数组 $id 分类id. 返回单线分类直到顶级分类 */
	public function get_navi($id)
	{
		$this->arr = null;
		$this->recur_n($this->data, $id);
		if(!is_null($this->arr))
		{
			krsort($this->arr);
		}
		return $this->arr;
	}

	/** 散落 一维数组 $id 分类id. 返回leaf下所有分类id */
	public function get_leafid($id)
	{
		$this->arr = null;
		$this->arr[] = $id;
		$this->recur_p($this->get_leaf($id));
		return $this->arr;
	}

	/* 获取select表单 <option value='\$id' \$selected>\$spacer\$name</option>\r\n, <optgroup label='\$name'></optgroup>\r\n */
	public function get_leafStr($id, $str, $selectId = 0, $selectedStr = '', $spacer_addon = '')
	{
		$return = '';
		$child = $this->get_leaf($id);
		if(is_array($child))
		{
			$number = 1;
			$count = count($child);
			foreach($child as $v)
			{
				if($number == $count)
				{
					$icon = $this->icon[2];
					$spacer = $spacer_addon.$icon;
				}
				else
				{
					$icon = $this->icon[1];
					$spacer = $spacer_addon.$icon;
				}

				@extract($v);
				if(!is_array($selectId))
				{
					$selectId = explode(',', $selectId);
				}
				in_array($v[$this->fields[0]], $selectId) ? eval("\$_t_str = \"$selectedStr\";") : eval("\$_t_str = \"$str\";");
				$return .= $_t_str;

				if(isset($v[$this->fields[2]]))
				{
					if($number == $count)
					{
						$addon = $spacer_addon.$this->icon[3];
					}
					else
					{
						$addon = $spacer_addon.$this->icon[0];
					}
					$return .= $this->get_leafStr($v[$this->fields[0]], $str, $selectId, $selectedStr, $addon);
				}
				$number++;
			}
		}
		return $return;
	}
}

/**
 * $tree= new ATree($data, array('id', 'pid', 'child'));
 * $arr=$tree->get_leaf(0);
 * $nav=$tree->get_navi(15);
 * $str = $tree->get_leafStr(0, "<option value='\$id'>\$spacer\$name</option>\r\n", 4, "<option value='\$id' selected='selected'>\$spacer\$name</option>\r\n");
 *
 * echo "<select name=\"f_id\" size=10>\r\n";
 * echo $str;
 * echo "</select>";
 */

?>