westdc-zf1/application/models/ArchiveCategory.php

561 lines
15 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* ArchiveCategroy - 文档分类类
*/
class ArchiveCategory
{
//PDO对象
private $db;
//数据库中分类表
public $CategoryTable;
//分类左值字段名称
private $fld_left;
//分类右值字段名称
private $fld_right;
//顶级栏目标记字段
private $fld_tid;
//输出栏目中的深度信息
public $DeepTitle;
//数据新闻栏目标识
public $DataNewsCode;
function __construct($db){
$this->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 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
//获得子栏目
function getSubNode($left,$right,$data = NULL)
{
if(empty($data))
{
$sql = "SELECT * FROM ".$this->CategoryTable." WHERE ".$this->fld_left.">$left AND ".$this->fld_right."<$right ORDER BY ".$this->fld_left." ASC";
$rs = $this->db->query($sql);
$SN = $rs->fetchAll();
}else{
$SN = array();
foreach($data as $k=>$v)
{
if($left < $v[$this->fld_left] && $v[$this->fld_right] < $right)
$SN[] = $data[$k];
}
}
return $SN;
}
//获取子栏目中的最大右值
function getMaxSubRight($left,$right){
$sql = "SELECT max(".$this->fld_right.") as mx FROM ".$this->CategoryTable." WHERE ".$this->fld_left.">".$left." AND ".$this->fld_right."<".$right;
$rs = $this->db->query($sql);
$row = $rs->fetch();
return $row['mx'];
}
//获取平级栏目中的上一个栏目
function prevnode($tid,$left,$right)
{
$sql = "SELECT * FROM ".$this->CategoryTable." WHERE
".$this->fld_tid."=$tid AND
".$this->fld_left."<$left AND
".$this->fld_right."<$right
ORDER BY ".$this->fld_left." DESC
LIMIT 1
";
$rs = $this->db->query($sql);
$row = $rs->fetch();
if(empty($row))
{
return NULL;
}
return $row;
}
//获取平级栏目中的下一个栏目
function nextnode($tid,$left,$right)
{
$sql = "SELECT * FROM ".$this->CategoryTable." WHERE
".$this->fld_tid."=$tid AND
".$this->fld_left.">$left AND
".$this->fld_right.">$right
ORDER BY ".$this->fld_left." ASC
LIMIT 1
";
$rs = $this->db->query($sql);
$row = $rs->fetch();
if(empty($row))
{
return NULL;
}
return $row;
}
//移动栏目
function move($action,$id){
if($action == 'up')
{
return $this->moveup($id);
}
if($action == "down")
{
return $this->movedown($id);
}
}
//栏目上移
function moveup($id){
$info = $this->GetOne($id);
$tid = $info[$this->fld_tid];
$left = $info[$this->fld_left];
$right = $info[$this->fld_right];
$prev = $this->prevnode($tid,$left,$right);
if($prev === NULL )
{
return "此栏目已位于平级栏目的顶端";
}
if(is_array($prev))
{
$this_fd = $right-$left;
$this_ft = $left - $prev[$this->fld_left];
$prve_fd = $prev[$this->fld_right] - $prev[$this->fld_left];
$new_right = $prev[$this->fld_left] + $this_fd;
$new_left = $right - $prve_fd;
$prev_ft = $new_left - $prev[$this->fld_left];
$exec = array(
'success' => array(),
'error' => array()
);
$sql_1 = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$prev[$this->fld_left].",".$this->fld_right."=".$new_right.
" WHERE id=$id";
$sql_2 = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$new_left.",".$this->fld_right."=".$right.
" WHERE id=".$prev['id'];
if($this->db->exec($sql_1))
{
$exec['success'][] = $info['title']."[$id] :移动成功!";
}else{
$exec['error'][] = $info['title']."[$id] :移动失败! 请手动在数据库中修改,目标左右值 ".$prev[$this->fld_left].":".$new_right;
}
if($this->db->exec($sql_2))
{
$exec['success'][] = $prev['title']."[".$prev['id']."] :移动成功!";
}else{
$exec['error'][] = $prev['title']."[".$prev['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$new_left.":".$right;
}
$thisnode = $this->getSubNode($left,$right);
$prevnode = $this->getSubNode($prev[$this->fld_left],$prev[$this->fld_right]);
/*
$a = array();
echo $prev[$this->fld_left].':'.$prev[$this->fld_right]." - ".$left.":".$right;
echo "<br />";
echo $prev[$this->fld_left].':'.$new_right." - ".$new_left.":".$right;
echo "<br />";
*/
if(!empty($thisnode))
{
foreach($thisnode as $k=>$v)
{
$node_new_left = ($v[$this->fld_left]-$this_ft);
$fd = $v[$this->fld_right] - $v[$this->fld_left];
$node_new_right = $node_new_left + $fd;
/*
echo ($v['lft']) .":". ($v['rgt'])."<br />";
echo $node_new_left .":". $node_new_right."<br />";
echo "<br />";
*/
$sql = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$node_new_left.",".$this->fld_right."=".$node_new_right.
" WHERE id=".$v['id'];
if($this->db->exec($sql))
{
$exec['success'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动成功!";
}else{
$exec['error'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$node_new_left.":".$node_new_right;
}
}
}
if(!empty($prevnode))
{
foreach($prevnode as $k=>$v)
{
$node_new_left = ($v[$this->fld_left]+$prev_ft);
$fd = $v[$this->fld_right] - $v[$this->fld_left];
$node_new_right = $node_new_left + $fd;
/*
echo ($v['lft']) .":". ($v['rgt'])."<br />";
echo $node_new_left .":". $node_new_right."<br />";
echo "<br />";
*/
$sql = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$node_new_left.",".$this->fld_right."=".$node_new_right.
" WHERE id=".$v['id'];
if($this->db->exec($sql))
{
$exec['success'][] = $prev['title']."的子栏目".$v['title']."[".$v['id']."] :移动成功!";
}else{
$exec['error'][] = $prev['title']."的子栏目".$v['title']."[".$v['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$node_new_left.":".$node_new_right;
}
}
}
return $exec;
}
if(is_string($prev))
{
return $prev;
}
}//栏目上移
//栏目下移
function movedown($id){
$info = $this->GetOne($id);
$tid = $info[$this->fld_tid];
$left = $info[$this->fld_left];
$right = $info[$this->fld_right];
$next = $this->nextnode($tid,$left,$right);
if($next === NULL )
{
return "此栏目已位于平级栏目的末端";
}
if(is_array($next))
{
$this_fd = $right-$left;
$next_fd = $next[$this->fld_right] - $next[$this->fld_left];
$new_right = $left + $next_fd;
$new_left = $next[$this->fld_right] - $this_fd;
$this_ft = $new_left - $left;
$next_ft = $next[$this->fld_left] - $left;
//echo $id."[".$left .":".$right ."]-".$next['id']."[".$next[$this->fld_left].":".$next[$this->fld_right] . "]<br />";
//echo $next['id']."[".$left .":".$new_right ."]-".$id."[".$new_left.":".$next[$this->fld_right]."]<br /><br />";
$exec = array(
'success' => array(),
'error' => array()
);
$sql_1 = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$new_left.",".$this->fld_right."=".$next[$this->fld_right].
" WHERE id=$id";
$sql_2 = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$left.",".$this->fld_right."=".$new_right.
" WHERE id=".$next['id'];
if($this->db->exec($sql_1))
{
$exec['success'][] = $info['title']."[$id] :移动成功!";
}else{
$exec['error'][] = $info['title']."[$id] :移动失败! 请手动在数据库中修改,目标左右值 ".$new_left.":".$next[$this->fld_right];
}
if($this->db->exec($sql_2))
{
$exec['success'][] = $next['title']."[".$next['id']."] :移动成功!";
}else{
$exec['error'][] = $next['title']."[".$next['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$left.":".$this->fld_right;
}
$thisnode = $this->getSubNode($left,$right);
$nextnode = $this->getSubNode($next[$this->fld_left],$next[$this->fld_right]);
if(!empty($thisnode))
{
foreach($thisnode as $k=>$v)
{
$node_new_left = ($v[$this->fld_left]+$this_ft);
$fd = $v[$this->fld_right] - $v[$this->fld_left];
$node_new_right = $node_new_left + $fd;
/*echo ($v['lft']) .":". ($v['rgt'])."<br />";
echo $node_new_left .":". $node_new_right."<br />";
echo "<br />";*/
$sql = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$node_new_left.",".$this->fld_right."=".$node_new_right.
" WHERE id=".$v['id'];
if($this->db->exec($sql))
{
$exec['success'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动成功!";
}else{
$exec['error'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$node_new_left.":".$node_new_right;
}
}
}
if(!empty($nextnode))
{
foreach($nextnode as $k=>$v)
{
$node_new_left = ($v[$this->fld_left] - $next_ft);
$fd = $v[$this->fld_right] - $v[$this->fld_left];
$node_new_right = $node_new_left + $fd;
/*echo ($v['lft']) .":". ($v['rgt'])."<br />";
echo $node_new_left .":". $node_new_right."<br />";
echo "<br />";*/
$sql = "UPDATE ".$this->CategoryTable." SET
".$this->fld_left."=".$node_new_left.",".$this->fld_right."=".$node_new_right.
" WHERE id=".$v['id'];
if($this->db->exec($sql))
{
$exec['success'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动成功!";
}else{
$exec['error'][] = $info['title']."的子栏目".$v['title']."[".$v['id']."] :移动失败! 请手动在数据库中修改,目标左右值 ".$node_new_left.":".$node_new_right;
}
}
}
return $exec;
}
if(is_string($next))
{
return $next;
}
}//栏目下移
}