123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?php
- namespace mall;
- /**
- * 树
- *
- * 0是根结点
- */
- class Tree
- {
- var $data = array();
- var $child = array(-1 => array());
- var $layer = array(0 => 0);
- var $parent = array();
- var $value_field = '';
- /**
- * 构造函数
- *
- * @param mix $value
- */
- function construct($value = 'root')
- {
- $this->Tree($value);
- }
- function Tree($value = 'root')
- {
- $this->setNode(0, -1, $value);
- }
- /**
- * 构造树
- *
- * @param array $nodes 结点数组
- * @param string $id_field
- * @param string $parent_field
- * @param string $value_field
- */
- function setTree($nodes, $id_field, $parent_field, $value_field)
- {
- $this->value_field = $value_field;
- foreach ($nodes as $node)
- {
- $this->setNode($node[$id_field], $node[$parent_field], $node);
- }
- $this->setLayer();
- }
- /**
- * 取得options
- *
- * @param int $layer
- * @param int $root
- * @param string $space
- * @return array (id=>value)
- */
- function getOptions($layer = 0, $root = 0, $except = NULL, $space = ' ')
- {
- $options = array();
- $childs = $this->getChilds($root, $except);
- foreach ($childs as $id)
- {
- if ($id > 0 && ($layer <= 0 || $this->getLayer($id) <= $layer))
- {
- $options[$id] = $this->getLayer($id, $space) . htmlspecialchars($this->getValue($id));
- }
- }
- return $options;
- }
- /**
- * 设置结点
- *
- * @param mix $id
- * @param mix $parent
- * @param mix $value
- */
- function setNode($id, $parent, $value)
- {
- $parent = $parent ? $parent : 0;
- $this->data[$id] = $value;
- if (!isset($this->child[$id]))
- {
- $this->child[$id] = array();
- }
- if (isset($this->child[$parent]))
- {
- $this->child[$parent][] = $id;
- }
- else
- {
- $this->child[$parent] = array($id);
- }
- $this->parent[$id] = $parent;
- }
- /**
- * 计算layer
- */
- function setLayer($root = 0)
- {
- foreach ($this->child[$root] as $id)
- {
- $this->layer[$id] = $this->layer[$this->parent[$id]] + 1;
- if ($this->child[$id]) $this->setLayer($id);
- }
- }
- /**
- * 先根遍历,不包括root
- *
- * @param array $tree
- * @param mix $root
- * @param mix $except 除外的结点,用于编辑结点时,上级不能选择自身及子结点
- */
- function getList(&$tree, $root = 0, $except = NULL)
- {
- foreach ($this->child[$root] as $id)
- {
- if ($id == $except)
- {
- continue;
- }
- $tree[] = $id;
- if ($this->child[$id]) $this->getList($tree, $id, $except);
- }
- }
- function getValue($id)
- {
- return $this->data[$id][$this->value_field];
- }
- function getLayer($id, $space = false)
- {
- return $space ? str_repeat($space, $this->layer[$id]) : $this->layer[$id];
- }
- function getParent($id)
- {
- return $this->parent[$id];
- }
- /**
- * 取得祖先,不包括自身
- *
- * @param mix $id
- * @return array
- */
- function getParents($id)
- {
- while ($this->parent[$id] != -1)
- {
- $id = $parent[$this->layer[$id]] = $this->parent[$id];
- }
- ksort($parent);
- reset($parent);
- return $parent;
- }
- function getChild($id)
- {
- return $this->child[$id];
- }
- /**
- * 取得子孙,包括自身,先根遍历
- *
- * @param int $id
- * @return array
- */
- function getChilds($id = 0, $except = NULL)
- {
- $child = array($id);
- $this->getList($child, $id, $except);
- unset($child[0]);
- return $child;
- }
- /**
- * 先根遍历,数组格式
- * array(
- * array('id' => '', 'value' => '', children => array(
- * array('id' => '', 'value' => '', children => array()),
- * ))
- * )
- */
- function getArrayList($root = 0 , $layer = NULL)
- {
- $data = array();
- foreach ($this->child[$root] as $id)
- {
- if($layer && $this->layer[$this->parent[$id]] > $layer-1)
- {
- continue;
- }
- $data[] = array('id' => $id, 'value' => $this->getValue($id), 'children' => $this->child[$id] ? $this->getArrayList($id , $layer) : array());
- }
- return $data;
- }
- /**
- * 取得csv格式数据
- *
- * @param int $root
- * @param mix $ext_field 辅助字段
- * @return array(
- * array('辅助字段名','主字段名'), //如无辅助字段则无此元素
- * array('辅助字段值','一级分类'), //如无辅助字段则无辅助字段值
- * array('辅助字段值','一级分类'),
- * array('辅助字段值','', '二级分类'),
- * array('辅助字段值','', '', '三级分类'),
- * )
- */
- function getCSVData($root = 0, $ext_field = array())
- {
- $data = array();
- $main = $this->value_field; //用于显示树分级结果的字段
- $extra =array(); //辅助的字段
- if (!empty($ext_field))
- {
- if (is_array($ext_field))
- {
- $extra = $ext_field;
- }
- elseif (is_string($ext_field))
- {
- $extra = array($ext_field);
- }
- }
- $childs = $this->getChilds($root);
- array_values($extra) && $data[0] = array_values($extra);
- $main && $data[0] && array_push($data[0], $main);
- foreach ($childs as $id)
- {
- $row = array();
- $value = $this->data[$id];
- foreach ($extra as $field)
- {
- $row[] = $value[$field];
- }
- for ($i = 1; $i < $this->getLayer($id); $i++)
- {
- $row[] = '';
- }
- if ($main)
- {
- $row[] = $value[$main];
- }
- else
- {
- $row[] = $value;
- }
- $data[] = $row;
- }
- return $data;
- }
- }
- ?>
|