玩转无限级分类

    赶在下班前写完的一段程序。主要为了写xml在线编辑器.不说了没直接上程序代码吧!下面是数据库的表:

drop table if exists xml_node;
create table xml_node
(
  id mediumint unsigned not null auto_increment comment 'id',
  parent_id mediumint unsigned not null comment '父id',
  file_id    mediumint unsigned not null comment '文件ID',
  name varchar(50) not null default '' comment '节点名',
  title    varchar(50) not null default '' comment '节点标题',
  type enum('0','text','html','image') default '0' comment '0父节点;text纯文本;html富文本;image图片',
  note varchar(50) not null default '' comment '节点备注',
  primary key(id),
  key parent_id(parent_id),
  key file_id(file_id),
  key name(name),
  key title(title)
)engine = InnoDB default charset = utf8 comment '节点表';


drop table if exists xml_content;
create table xml_content
(
  id mediumint unsigned not null auto_increment comment 'id',
  not_id mediumint unsigned not null comment '节点id',
  content text not null default '' comment '内容',
  primary key(id),
  key not_id(not_id)
)engine = InnoDB default charset = utf8 comment '节点内容表';

    主要用的还是thinkPHP3.2.3,比较老的框架。但是开发还是挺顺手的。下面上模型代码。

// +----------------------------------------------------------------------
// | Mender: arvin// +----------------------------------------------------------------------
namespace Admin\Model;
use Common\Model\Model;
class NoteModel extends Model {
    protected $trueTableName = 'mall_xml_node';
    //array(验证字段,验证规则,错误提示,[验证条件,附加规则,验证时间])
    protected $_validate = array(
        array('file', 'require', '文件名不能为空!'),
        array('title', 'require', '标题不能为空!'),
        array('note', 'require', '备注不能为空!', 0, 'regex', 1),
    );
    protected function _before_insert(&$data, $option)
    {
    }
    public function _after_insert(&$data, $option)
    {
        // 判断是否存在有节点内容
        $cmodel = M('xml_content');
        $content = I('post.content');
        if($content)
        {
            $cmodel->add(array(
                'not_id' => $data['id'],
                'content' => $content,
            ));
        }
    }
    public function getChildren($catId)
    {
        // 取出所有的分类
        $data = $this->select();
        // 递归从所有的分类中挑出子分类的ID
        return $this->_getChildren($data, $catId, TRUE);
    }
    /*
    * 递归从数据中找子分类
    */
    private function _getChildren($data, $catId, $isClear = FALSE)
    {
        static $_ret = array();  // 保存找到的子分类的ID
        if($isClear)
            $_ret = array();
            // 循环所有的分类找子分类
            foreach ($data as $k => $v)
            {
                if($v['parent_id'] == $catId)
                {
                    $_ret[] = $v['id'];
                    // 再找这个$v的子分类
                    $this->_getChildren($data, $v['id']);
                }
            }
        return $_ret;
    }
    // 获取树形数据
    public function getTree()
    {
        $data = $this->select();
        return $this->_getTree($data);
    }
    private function _getTree($data, $parent_id=0, $level=0)
    {
        static $_ret = array();
        foreach ($data as $k => $v)
        {
            if($v['parent_id'] == $parent_id)
            {
                $v['level'] = $level;  // 用来标记这个分类是第几级的
                $_ret[] = $v;
                // 找子分类
                $this->_getTree($data, $v['id'], $level+1);
            }
        }
        return $_ret;
    }
    /*
     * 生成一个公用的数列
     */
    private function makeArray($data)
    {
        $array['parent_id'] = $data['parent_id'];
        $array['file_id'] = $data['file_id'];
        $array['name'] = $data['name'];
        $array['title'] = $data['title'];
        $array['type'] = $data['type'];
        $array['note'] = $data['note'];
        return $array;
    }
  /*
   *提供控制器完整复制之前的节点
   */
    public function againnote($id)
    {
        // 异常处理
        try{
            $id = $id;
            $conModel = M('xml_content');
            // 获取是否存在子类
            $data = $this->getChildren($id);
            // 不存在为null
            if(empty($data))
            {
                $da = $this->getAnote($id);
                $new = $this->makeArray($da);
                // 这个返回值原来就是插入数据的ID
                $newid = $this->add($new);
                $content['not_id'] = $newid ;
                $content['content'] = $da['content'] ? $da['content'] : null;
                $conModel->add($content);
            }
            // 若不为空,则先处理父ID的值
            $oldParent_id = (string)$id;
            // 父ID没有内容,则不做处理
            $da = $this->getAnote($id);
            $new = $this->makeArray($da);
            $new['id'] = "";
            // 返回ID作为下面插入的数据的父ID
            $newParent_id = $this->add($new);
            foreach($data as $k => $v)
            {
                $da = $this->getAnote($v);
                $child = $this->makeArray($da);
                $child['parent_id'] = $newParent_id;
                //这里获取的是子键插入ID
                $childId = $this->add($child);
                // 考虑子类是否有父id,则不存在内容
                $is_child = $this->getChildren($v);
                // 如果不存在子类,意味着有内容,就添加到数据库,否则,扔掉
                if(empty($is_child))
                {
                    $content['not_id'] = $childId;
                    $content['content'] = $da['content'];
                    $conModel->add($content);
                }
            }
        } catch (Exception $e) {
            print $e->getMessage();
            exit();
        }
    }
    /*
     *提供控制器删除节点
     */
    public function deletenode($id)
    {
        try{
            $conModel = M('xml_content');
            // 传过来的是父ID
            $delId = $this->getChildren($id);
            // 删除整个列的话就得把自己也捎上
            if(empty($delId))
            {
                $this->delete($id);
                $conModel->where(array(
                    'not_id' => $id
                ))->delete();
            }
            //  若存在子类,遍历轮询删除
            $delId[] = (string)$id;
            // 循环取出里面的ID数据
            foreach($delId as $v)
            {
                $da = $this->delete($v);
                $conModel->where(array(
                    'not_id' => $v
                ))->delete();
            }
        } catch (Exception $e) {
                print $e->getMessage();
                exit();
        }
    }
    // 获取所有节点的内容
    public function getNote()
    {
        $data = $this->select();
        $conModel = M('xml_content');
        foreach($data as$k => $v)
        {
            $content = $conModel->where(array(
                'not_id' => $v['id'],
            ))->find();
            // 把两个数组压成一个数据循环遍历
            // $data[$k]['not_id'] = $content ? $content['not_id'] : null;
            $data[$k]['content'] = $content ? $content['content'] : null;
        }
        return $data;
    }
    // 逐个获取节点的内容
    public function getAnote($id)
    {
        $data = $this->find($id);
        $conModel = M('xml_content');
        $content = $conModel->where(array(
            'not_id' => $data['id'],
        ))->find();
        // 把两个数组压成一个数据循环遍历
        $data['content'] = $content ? $content['content'] : null;
        return $data;
    }
}

    这里提供了许多thinkphp手册里没有写好的东西,也是反复研究测试了好久。百度里面的鱼龙混杂。得不到准确要的信息。不说了,还没下班,继续写前台js.心累哦!


本文链接:https://itarvin.com/detail-3.aspx

登录或者注册以便发表评论

登录

注册