无限级分类,左右值算法

<?php

class IndexAction extends Action{
    
    private $model;
    
    public function __construct()
    {
        parent::__construct();
        $this->model= M("catagory");
        //var_dump($this->model);
    }
    // 首页
    public function index(){
        $this->delete();

        $arry = array();
        $arry['text'] = 'root';$pid = $this->insert($arry,0);

        $arry['text'] = "1";$id1 = $this->insert($arry,$pid);
        $arry['text'] = "2";$id2 = $this->insert($arry,$pid);
        $arry['text'] = "3";$id3 = $this->insert($arry,$pid);
        $arry['text'] = "4";$id4 = $this->insert($arry,$pid);

        $arry['text'] = "2-1";$id21 = $this->insert($arry,$id2);
        $arry['text'] = "2-2";$id22 = $this->insert($arry,$id2);

        $arry['text'] = "4-1";$id41 = $this->insert($arry,$id4);
        $arry['text'] = "4-2";$id42 = $this->insert($arry,$id4);

        $arry['text'] = "5";$id5 = $this->insert($arry,$pid);

        $arry['text'] = "3-1";$id31 = $this->insert($arry,$id3);
        $arry['text'] = "3-2";$id32 = $this->insert($arry,$id3);
        $arry['text'] = "3-3";$id33 = $this->insert($arry,$id3);

        $arry['text'] = "3-2-1";$id321 = $this->insert($arry,$id32);
        $arry['text'] = "3-2-2";$id322 = $this->insert($arry,$id32);
        $arry['text'] = "3-2-3";$id323 = $this->insert($arry,$id32);

        var_dump($this->get($id3)); //获取节点数据
        var_dump($this->parents($id322)); //获取直属父节点,不包含自身
        var_dump($this->parents($id322,true)); //获取直属父节点,包含自身
        var_dump($this->parents($id322,false,true));//获取全部父节点,不包含自身
        var_dump($this->parents($id322,true,true)); //获取全部父节点,包含自身
        var_dump($this->count($id3)); //获取直属子节点个数
        var_dump($this->childs($id3)); //获取直属子节点,不包含自身
        var_dump($this->childs($id3,true)); //获取直属子节点,包含自身
        var_dump($this->childs($id3,false,true)); //获取全部子节点,不包含自身
        var_dump($this->childs($id3,true,true)); //获取全部子节点,包含自身

        echo "exchange";
        $this->exchange($id321,$id322); //同节点替换
        $this->exchange($id323,$id31); //不同节点替换
        var_dump($this->childs($id3,false,true)); //检查

    }

    //返回id号,如果为0则表示失败
    public function insert($data,$pid) {
        if($pid == 0)
        {//根节点
            $v = $this->model->query("select count(*) as result from __TABLE__");
            if (is_array($v) && $v[0]['result'] == 0) {
                $data['left'] = 0;
                $data['right'] = 1;
                $data['level'] = 0;
                return $this->model->add($data);
            }
        }else if(is_array($pdata = $this->get($pid))){
            //非根节点,且存在
            $left=$pdata[0]['left']; 
            $right=$pdata[0]['right']; 
            $this->model->query("UPDATE __TABLE__ SET `left`=`left`+2 WHERE `left` >$right"); 
            $this->model->query("UPDATE __TABLE__ SET `right`=`right`+2 WHERE `right`>=$right");
            $data['left'] = $right;
            $data['right'] = $right+1;
            $data['level'] = $pdata[0]['level']+1;
            return $this->model->add($data);
        }
        return 0;
    }
    public function delete($id = 0){
        //truncate table 你的表名
        if($id == 0 || $id == 1 )
        {
            $this->model->query("truncate table __TABLE__ ");
        }else{
            if(is_array($pdata = $this->get($id))){
                $level = $pdata[0]['level'];
                if($level ==0){//仍然是根节点
                    $this->model->query("truncate table __TABLE__ ");
                    return;
                }
                //非根节点,且存在
                $left = $pdata[0]['left'];
                $right = $pdata[0]['right'];
                $this->model->where("`left`>={$left} and `right`<=$right")->delete();
                //更新左右值
                $value=$right-$left+1; 
                $this->model->query("UPDATE __TABLE__ SET `left` =`left` - $value WHERE `left`> $left"); 
                $this->model->query("UPDATE __TABLE__ SET `right`=`right`- $value WHERE `right`>$right"); 
            }
        }
    }
    public function move($id,$parentId){
        if($id>1 && is_array($src = $this->get($id)) && is_array($pdata = $this->get($parentId)))
        {//不是根节点,两个节点都存在
            $left = $src[0]['left']; 
            $right = $src[0]['right']; 
            $level = $src[0]['level'];
            $pleft = $pdata[0]['left']; 
            $pright = $pdata[0]['right']; 
            $plevel = $pdata[0]['level'];
            
            $value_between = $right-$left + 1;
            $level_src = $plevel - $level +1;
            if($pright>$right){
                $this->model->query("UPDATE __TABLE__ SET `left` =`left` - $value_between WHERE `left`> $right and `right`<=$pright");
                $this->model->query("UPDATE __TABLE__ SET `right` =`right` - $value_between WHERE `right`> $right and `right`<$pright");
                $value_src = $pright-$right-1;
                $this->model->query("UPDATE __TABLE__ SET `right` = `right` + $value_src,`left`=`left`+$value_src,`level`=`level`+$level_src WHERE `right`<= $right and `left`>=$left");
            }else{
                $this->model->query("UPDATE __TABLE__ SET `left` =`left` + $value_between WHERE `left`> $pright and `left`<=$left");
                $this->model->query("UPDATE __TABLE__ SET `right` =`right` + $value_between WHERE `right`>= $pright and `right`<$left");
                $value_src = $left-$pright;
                $this->model->query("UPDATE __TABLE__ SET `right` = `right` - $value_src,`left`=`left`-$value_src,`level`=`level`+$level_src WHERE `right`<= $right and `left`>=$left");
            }
        }
    }
    //如果有返回数组,否则返回false
    public function get($id){
        if($id==0)
            $id = 1;
        return $this->model->query("select * from __TABLE__ where id = {$id}");
    }
    //不存在则返回0
    public function count($id) {
        if(is_array($pdata = $this->get($id))){
            $v = $this->model->query("select count(*) as result from __TABLE__ where `left`>{$pdata[0]['left']} and `right`<{$pdata[0]['right']} and level = {$pdata[0]['level']}+1");
            if (is_array($v)) {
                return $v[0]['result'];
            }
        }
        return 0;
    }
    //获取直属子节点数组 $self:是否包含自身,$allChilds:是否包含所有子节点
    public function childs($id,$self=false,$allChilds=false) {
        if($id == 0){
            $left = 0; 
            $right = 0; 
            $level = 0;
        }else if(is_array($pdata = $this->get($id))){
            $left = $pdata[0]['left'];
            $right = $pdata[0]['right'];
            $level = $pdata[0]['level'];
        }else{
            return 0;
        }
        $self_filter = $self ? " `left`>={$left} and `right`<={$right} " : " `left`>{$left} and `right`<{$right} ";
        if($self){
            $level_filter = $allChilds ? " `level` >={$level} " : " `level` <={$level}+1 ";
        }else
            $level_filter = $allChilds ? " `level` >={$level} " :" `level` ={$level}+1 ";
        return $this->model->query("select * from __TABLE__ where {$self_filter} and {$level_filter} order by `level` asc,`left` asc");
    }
    //获取父节点
    public function parents($id,$self=false,$allParents=false) {
        if($id == 0){
            $left = 0;
            $right = 0;
            $level = 0;
        }else if(is_array($pdata = $this->get($id))){
            $left = $pdata[0]['left']; 
            $right = $pdata[0]['right']; 
            $level = $pdata[0]['level'];
        }else{
            return 0;
        }
        if($self){
            if($allParents)
                $level_filter = "level <=$level";
            else
                $level_filter = "level >=$level-1";
        }else{
            if($allParents)
                $level_filter = "level <$level";
            else
                $level_filter = "level =$level-1";
        }
        return $this->model->query("select * from __TABLE__ where `left`<={$left} and {$level_filter} and `right`>={$right} order by `level` asc,`left` asc");
    }
    //交换
    public function exchange($id1,$id2){
        if(is_array($data1 = $this->get($id1)) && is_array($data2 = $this->get($id2))){
            // left right level
            $udata1 = array();
            $udata1['left'] = $data1[0]['left'];
            $udata1['right'] = $data1[0]['right'];
            $udata1['level'] = $data1[0]['level'];
            
            $udata2 = array();
            $udata2['left'] = $data2[0]['left'];
            $udata2['right'] = $data2[0]['right'];
            $udata2['level'] = $data2[0]['level'];
            $this->model->where("`id`={$data2[0]['id']}")->save($udata1);
            $this->model->where("`id`={$data1[0]['id']}")->save($udata2);
        }
    }
    //返回树结构,暂时未完
    public function tree($id){
        if(is_array($lists = $this->lists($id))){
            $result = array();
            
            $level = -1; //当前的level
            $iter = null; //父item
            $piter = &$result;//父父item
            $index = 0; //父的index

            for($i=0;$i<count($lists);$i++)
            {
                $list_level = $lists[$i]['level'];
                $list_right = $lists[$i]['right'];
                if($list_level > $level){//level增加
                    if($level == -1)
                    {//根,添加
                        $item = array();
                        $item['data'] = $lists[$i];
                        $item['items'] = array();
                        $piter['items'][] = $item;
                        //$piter = &$piter['items'][0];
                        $level = $list_level; //level赋值
                        continue;
                    }else if($level != 0){
                        $piter = &$piter['items'][0];
                    }
                    $index = 0; //父的index重置
                    $level = $list_level; //level赋值
                }
                $iter = &$piter['items'][$index];
                $p_right = $iter['data']['right'];
                if($list_right > $p_right)
                {
                    $iter = &$piter['items'][++$index];
                }
                
                $item = array();
                $item['data'] =$lists[$i];
                $item['items'] = array();
                $iter['items'][] = $item;
            }
            //$result['text']=
            return $result;
        }
    }
}
?>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值