db = $db; $this->CategoryTable = "ar_category"; $this->fld_left = "lft"; $this->fld_right = "rgt"; $this->fld_tid = "tid"; $this->DeepTitle = "ROOTDEEP"; $this->DataNewsCode = "datanews"; } function GetFullCategory() { return $this->GetCategory(0,''); } /** * GetTree() 获得栏目树 * 用来获得某个栏目下或者所有栏目的树结构 * * 典型表结构 * (PostgreSql) * CREATE TABLE ar_category ( id serial NOT NULL, title character varying(80), tid integer NOT NULL DEFAULT 0, lft integer NOT NULL DEFAULT 0, rgt integer NOT NULL DEFAULT 0, CONSTRAINT ar_category_pkey PRIMARY KEY (id) ) * * @param int $tid * * @return array; */ function GetCategory($tid=0,$ptype='news'){ $left = $this->fld_left; $right = $this->fld_right; $categoryTable = $this->CategoryTable; $tidField = $this->fld_tid; $whereSql = array(); if(!empty($tid)) { $sql = "SELECT $left,$right FROM $categoryTable WHERE id=$tid"; $sth = $this->db->query($sql); $row = $sth->fetch(); $whereSql[] = " $left BETWEEN {$row[$left]} AND {$row[$right]} "; } if(count($whereSql)>0) { $whereSql = " WHERE ".join(" AND ",$whereSql); }elseif ($ptype<>''){ $whereSql = " where ptype='$ptype' "; } else $whereSql=''; $sql = "SELECT * FROM $categoryTable $whereSql ORDER BY ptype ASC,$left ASC "; $sth = $this->db->query($sql); $rows = $sth->fetchAll(); $stack = array(); $categorys = array(); foreach($rows as $k=>$v) { /* 如果它是一个顶级栏目,则为它重置深度 */ if(empty($v[$tidField])) { $stack = array(); }else{ if(count($stack) > 1) { /* 在这个循环中必须追溯直至与其平级的分类 while循环无法重写条件中已经改变的变量 第一次max(array_keys($stack))赋值为当前深度 循环中的第一个if里max(array_keys($stack))是重新统计,而非使用一定义的 因为第二次循环到此时可能max(array_keys($stack))已经发生改变 第三处max(array_keys($stack))表示第一个if中没有break掉的深度值,所以也不能使用赋过值的变量代替。 加入brake 可使程序追溯至平级栏目即进行下一步操作 必须是倒序循环,多个平级栏目时,如果是正序列循环会到第一个平级的栏目后停止循环 */ for($i=max(array_keys($stack));$i>=0;$i--) if($v[$right]>$stack[max(array_keys($stack))]) { if(count($stack)<1) { break; } if($v[$right]>$stack[max(array_keys($stack))]) { array_pop($stack); }else{ break; } }//end if }//end if } //放入输出数组 $rows[$k][$this->DeepTitle] = count($stack); //将此节点加入栈中 $stack[] = $v[$right]; }// end foreach return $rows; } /** * Insert() 插入一个栏目 * 返回数组 left=>左值 right=>右值 * * * @param int $tid * * @return array */ function Insert($tid){ $left = $this->fld_left; $right = $this->fld_right; $categoryTable = $this->CategoryTable; //分别处理有上级栏目和没上级栏目的 if(!empty($tid)) { $sql = "SELECT $right FROM $categoryTable WHERE id=$tid"; $sth = $this->db->query($sql); $row = $sth->fetch(); $right_start = $row[$right]-1; //更新所有右值 $sql = "UPDATE $categoryTable SET $right=$right+2 WHERE $right>$right_start"; $this->db->exec($sql); //更新所有左值 $sql = "UPDATE $categoryTable SET $left=$left+2 WHERE $left>$right_start"; $this->db->exec($sql); //返回应该插入的左右值 $lft = $right_start + 1; $rgt = $lft + 1; return array( 'left'=>$lft, 'right'=>$rgt ); }else{ //取最大的右值 $sql = "SELECT $right FROM $categoryTable WHERE tid=0 ORDER BY $left DESC LIMIT 1"; $sth = $this->db->query($sql); $row = $sth->fetch(); $right_start = $row[$right]-1; if($right_start<1) { return array( 'left'=>1, 'right'=>2 ); } $lft = $right_start + 2; $rgt = $lft + 1; return array( 'left'=>$lft, 'right'=>$rgt ); } }//Insert //获取栏目路径 function GetRouter($lft,$rgt){ $sql = "SELECT * FROM ".$this->CategoryTable." WHERE ".$this->fld_left." < $lft AND ".$this->fld_right." > $rgt ORDER BY ".$this->fld_left." ASC;"; $sth = $this->db->query($sql); $rows = $sth->fetchAll(); return $rows; } function GetSunCount($left,$right){ return ($right-$left-1)/2; } //获取一个栏目 function GetOne($tid){ $wheresql = ""; if(is_numeric($tid)) { $wheresql = "id=$tid"; }else{ $wheresql = "code='$tid'"; } $sql = "SELECT * FROM ".$this->CategoryTable." WHERE $wheresql"; $sth = $this->db->query($sql); return $sth->fetch(); }//GetOne }