westdc-zf1/vendor/Sookon/Article/Category.php

700 lines
18 KiB
PHP
Raw 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
namespace Sookon\Article;
use Sookon\Helpers\View as view;
use Sookon\Helpers\Dbh as dbh;
use Sookon\Helpers\PDO;
use Sookon\Helpers\Config;
use Sookon\Helpers\Table;
use Zend\Http\PhpEnvironment\Request;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
use Sookon\Article\Listener\CategoryListener as Listener;
class Category
{
private $db; //传入PDO对象
private $config; //站点设置
private $table;
public $opt;
protected $events = NULL;
function __construct()
{
$this->db = new PDO;
$this->config = Config::get();
$this->table = new Table;
$this->opt = new \stdClass();
$this->opt->sort = "DESC";
$this->opt->logic = "AND";
$this->CategoryTable = $this->table->arc_category;
$this->fld_left = "lft";
$this->fld_right = "rgt";
$this->fld_tid = "tid";
$this->DeepTitle = "ROOTDEEP";
$this->DataNewsCode = "datanews";
$Listener = new Listener();
$this->getEventManager()->attachAggregate($Listener);
}
public function setEventManager(EventManagerInterface $events)
{
$events->setIdentifiers(array(
__CLASS__,
get_called_class(),
));
$this->events = $events;
return $this;
}
public function getEventManager()
{
if (NULL === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
public function GetFullCategory()
{
return $this->GetCategory(0,'');
}
public 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;
}
public function fetchAll()
{
$wheresql = array();
if(isset($this->opt->where) && !empty($this->opt->where))
$wheresql = array_merge($wheresql,$this->opt->where);
if(count($wheresql)>0)
{
$wheresql = " WHERE ".join($wheresql," ".$this->opt->logic." ");
}else{
$wheresql = '';
}
if(!empty($this->opt->order))
{
$order = $this->opt->order;
}else{
$order = "id";
}
$sql = "select * from {$this->table->arc_article}
$wheresql
ORDER BY $order {$this->opt->sort} ";
if(!empty($this->opt->start))
{
$sql .= " START {$this->opt->start} ";
}
if(!empty($this->opt->limit)){
$sql .= " LIMIT {$this->opt->limit} ";
}
$rs = $this->db->query($sql);
return $rs->fetchAll();
}
public function fetch($id)
{
if(is_numeric($id))
{
$sql = "SELECT * FROM {$this->table->arc_category} WHERE id=$id";
}else{
if(preg_match("/^[A-Za-z]+$/",$id))
{
$sql = "SELECT * FROM {$this->table->arc_category} WHERE code='$id'";
}else{
return false;
}
}
$rs = $this->db->query($sql);
return $rs->fetch();
}
public $ptype = array(
"新闻" => "news",
"想法" => "idea",
"帮助" => "help",
"关于" => "about"
);
public function getParam()
{
$request = new Request;
$data = array(
'title' => $request->getPost('title'),
'ptype' => $request->getPost('ptype'),
'tid' => (int)$request->getPost('fid'),
'code' => $request->getPost('code'),
);
return $data;
}
//添加
public function add($data,$id = 0)
{
$params = compact('data');
$results = $this->getEventManager()->trigger('submit.checkParam', $this, $params);
$cache_data = $results->last();
if($cache_data !== true)
{
return $cache_data;
}
$results = $this->getEventManager()->trigger('submit.processData', $this, $params);
$data = $results->last();
$dbh = new dbh();
if(empty($id))
{
$id = $dbh->insert($this->table->arc_category,$data,true);
if(!empty($id) && is_numeric($id))
{
$this->getEventManager()->trigger('submit.recordPosted', $this, compact('params','data','id'));
return true;
}else{
if($id === false)
{
return '服务器开小差了,请稍后再试';
}else{
return '服务器处理中遇到错误,请联系管理员';
}
}
}//add
else{
if(!$dbh->update($this->table->arc_category,$data," id=$id ",true))
{
return "修改失败!请重试";
}else{
$this->getEventManager()->trigger('submit.recordChanged', $this, compact('params','data','id'));
return true;
}
}//edit
}// add()
/**
* 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
//移动栏目
public function move($action,$id){
if($action == 'up')
{
return $this->moveup($id);
}
if($action == "down")
{
return $this->movedown($id);
}
}
//栏目上移
public function moveup($id){
$info = $this->fetch($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;
}
}//栏目上移
//栏目下移
public function movedown($id){
$info = $this->fetch($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;
}
}//栏目下移
//获得子栏目
public 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;
}
//获取子栏目中的最大右值
public 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'];
}
//获取平级栏目中的上一个栏目
public 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;
}
//获取平级栏目中的下一个栏目
public 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;
}
//删除某个栏目
public function del($id)
{
if(empty($id) || !is_numeric($id))
{
return "参数错误";
}
$cate = $this->fetch($id);
if($cate[$this->fld_right] - $cate[$this->fld_left] > 1)
{
return "此栏目包含子栏目,不能直接删除,需要先删除子栏目";
}
$sql = "DELETE FROM ".$this->CategoryTable." WHERE id=$id";
if($this->db->exec($sql))
{
$sql = "UPDATE ".$this->CategoryTable.
" SET ".$this->fld_right."=".$this->fld_right."-2".
" WHERE ".$this->fld_right.">".$cate[$this->fld_right];
$sql2 = "UPDATE ".$this->CategoryTable.
" SET ".$this->fld_left."=".$this->fld_left."-2".
" WHERE ".$this->fld_left.">".$cate[$this->fld_left];
if($this->db->exec($sql) || $this->db->exec($sql2))
return true;
else
return false;
}
}
}