westdc-core/Westdc/Review/Review.php

611 lines
18 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
/**
* Created by PhpStorm.
* User: liujin834
* Date: 15/1/1
* Time: 下午8:04
*/
namespace Westdc\Review;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Westdc\EventModel\AbstractEventManager;
use Zend\Db\Sql;
class Review extends AbstractEventManager implements ServiceManagerAwareInterface{
protected $serviceManager;
public $opt,$orderSql = "",$limitSql = "",$sortSql = "";
const REVIEW_STATUS_CANCELED = -1; //取消评审
const REVIEW_STATUS_DEFAULT = 0; //初始状态
const REVIEW_STATUS_ACCEPT = 1; //接收元数据,进入评审状态
const REVIEW_STATUS_EXPERT_INVITED = 2; //开始邀请专家
const REVIEW_STATUS_EXPERT_ACCEPT = 3; //专家接受邀请
const REVIEW_STATUS_EXPERT_FEEDBACK = 4; //专家有反馈
const REVIEW_STATUS_PUBLISH = 5; //已发布
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
$this->init();
return $this;
}
private function init(){
$dbService = $this->serviceManager->get('Db');
/** @var \PDO $this->db */
$this->db = $dbService->getPdo();
unset($dbService);
$this->opt = new \stdClass;
}
/**
* 处理sql中用到的排序limit等语句
*/
private function processOptions()
{
if(isset($this->opt->limit) && $this->opt->limit > 0)
$this->limitSql = "LIMIT {$this->opt->limit}";
if(isset($this->opt->order) && !empty($this->opt->order)) {
$this->orderSql = "ORDER BY {$this->opt->order}";
if (isset($this->opt->sortSql) && !empty($this->opt->sortSql))
$this->sortSql = "{$this->opt->sort}";
else
$this->sortSql = "DESC";
}
}
/**
* 获得最新的数据
* @return mixed
*/
public function getLatest()
{
$this->processOptions();
$sql = "select m.id,md.title,u.username,u.realname,m.status from mdstatus m
right join metadata md on md.uuid=m.uuid
left join users u on u.id=m.userid
order by m.id desc
{$this->limitSql}";
$rs = $this->db->query($sql);
return $rs->fetchAll();
}//getLatest()
/**
* 获得管理员负责的评审
* @param $userId
* @return mixed
*/
public function getAdminReview($userId)
{
$this->processOptions();
$sql = "select m.id,md.title,u.username,u.realname,m.status from mdstatus m
right join metadata md on md.uuid=m.uuid
left join users u on u.id=m.userid
where u.id='$userId'
{$this->limitSql}";
$rs = $this->db->query($sql);
return $rs->fetchAll();
} //getAdminReview
/**
* 投稿元数据
* @return mixed
*/
public function getDraft(){
$this->processOptions();
$searchJoin = "";
if(isset($this->opt->keyword) && !empty($this->opt->keyword))
{
$searchJoin = " AND md.title LIKE '%{$this->opt->keyword}%'";
}
if(empty($this->orderSql))
{
$this->orderSql = "ORDER BY m.ts_created DESC";
}
$sql = "SELECT m.id,md.title,md.uuid,u.username,u.realname,m.status,m.ts_created,gn.id as gnid FROM mdstatus m
RIGHT JOIN metadata md ON md.uuid=m.uuid
LEFT JOIN users u ON u.id=m.userid
LEFT JOIN geonetworkmetadata gn ON m.uuid=gn.uuid
WHERE m.status=".self::REVIEW_STATUS_DEFAULT." $searchJoin
{$this->orderSql} {$this->sortSql}
{$this->limitSql}";
$rs = $this->db->query($sql);
return $rs->fetchAll(\PDO::FETCH_ASSOC);
}//getDraft()
/**
* 获取被取消评审的元数据
* @return mixed
*/
public function getCanceled()
{
$this->processOptions();
$searchJoin = "";
if(isset($this->opt->keyword) && !empty($this->opt->keyword))
{
$searchJoin = " AND md.title LIKE '%{$this->opt->keyword}%'";
}
if(empty($this->orderSql))
{
$this->orderSql = "ORDER BY m.ts_created DESC";
}
$sql = "SELECT m.id,md.title,md.uuid,m.status,m.ts_created FROM mdstatus m
RIGHT JOIN metadata md ON md.uuid=m.uuid
WHERE m.status=".self::REVIEW_STATUS_CANCELED." $searchJoin
{$this->orderSql} {$this->sortSql}
{$this->limitSql}";
$rs = $this->db->query($sql);
return $rs->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* 获取需要分配编辑的评审
* @param string $filter
* @return mixed
* filter参数帮助生成sql语句中的where、order、sort条件
*/
public function getEditor($filter = ""){
$wheresql = array();
$ordersql = array();
$wheresql[] = " m.status in (".self::REVIEW_STATUS_ACCEPT.",".self::REVIEW_STATUS_EXPERT_INVITED.",".self::REVIEW_STATUS_EXPERT_ACCEPT.",".self::REVIEW_STATUS_EXPERT_FEEDBACK.") ";
$wheresql[] = " (m.userid IS NULL OR u.usertype != 'administrator') ";
if(isset($filter['keyword']) && !empty($filter['keyword']))
{
$wheresql[] = " (md.title like '%".$filter['keyword']."%' OR u.username LIKE '%".$filter['keyword']."%' OR u.realname LIKE '%".$filter['keyword']."%') ";
}
if(count($wheresql)>0)
{
$wheresql = " WHERE ".join(" AND ",$wheresql);
}else{
$wheresql = "";
}
if(isset($filter['order']) && !empty($filter['order']))
{
$sort = "DESC";
if(isset($filter['sort']) && !empty($filter['sort']) && in_array( strtolower($filter['sort']),array('desc','asc')))
{
$sort = $filter['sort'];
}
$ordersql[] = " {$filter['order']} $sort ";
}
if(count($ordersql)>0)
{
$ordersql = " ORDER BY ".join(',',$ordersql);
}else{
$ordersql = " ORDER BY m.ts_created desc ";
}
$sql = "select m.*,md.title,u.username,u.realname from mdstatus m
right join metadata md on md.uuid=m.uuid
left join users u on u.id=m.userid
$wheresql
$ordersql";
$re = $this->db->query($sql);
$rows = $re->fetchAll();
return $rows;
}//getEditor();
/**
* 待审核元数据
* @return mixed
*/
public function getAccept(){
//调试sql时需要输入adapter环境
// $dbService = $this->serviceManager->get('Db');
// $adapter = $dbService->getZendDb();
// $sql = new Sql\Sql($adapter);
// $select = $sql->select();
$select = new Sql\Select;
$select->from(['m'=>'mdstatus']);
$select->columns(array('*'));
$select->join(
["md"=>"metadata"],
"md.uuid=m.uuid",
["title"],
$select::JOIN_RIGHT);
$select->join(
["u"=>"users"],
"m.userid=u.id",
["username","realname"],
$select::JOIN_LEFT);
$select->where(function(Sql\Where $where){
$where->AND->in("m.status",[
self::REVIEW_STATUS_ACCEPT,
self::REVIEW_STATUS_EXPERT_INVITED,
self::REVIEW_STATUS_EXPERT_ACCEPT,
self::REVIEW_STATUS_EXPERT_FEEDBACK
]);
},Sql\Predicate\PredicateSet::OP_AND);
if(!empty($this->opt->keyword))
{
$keyword = $this->opt->keyword;
$tools = $this->serviceManager->get('Tools');
if($tools->isUUID($keyword)) {
$select->where("md.uuid = '$keyword'");
}else{
$whereSql = function(Sql\Where $where) use ($keyword){
$where->AND->like('md.title',"%".$keyword."%");
$where->OR->like('md.title_en',"%".$keyword."%");
};
$select->where($whereSql,Sql\Predicate\PredicateSet::OP_AND);
}
}
$select->order("md.id DESC");
// echo $sql->getSqlStringForSqlObject($select); //带环境的sql
// echo $select->getSqlString(); //普通级别的sql
// exit();
return $select;
}//getAccept()
/**
* 获得我负责的元数据
* @param string $filter
* @return null
*/
public function getAdminReviews($filter = "")
{
$authService = $this->serviceManager->get('Auth');
$user_id = $authService->getIdentity('id');
if(empty($user_id))
return false;
$wheresql = array();
$ordersql = array();
$wheresql[] = " m.status in (1,2,3,4) ";
$wheresql[] = " u.id=$user_id ";
if(isset($filter['keyword']) && !empty($filter['keyword']))
{
$wheresql[] = " md.title like '%".$filter['keyword']."%' ";
}
if(isset($filter['code']) && !empty($filter['code']))
{
$wheresql[] = " s.sourceid=".$filter['code']." ";
}
if(isset($filter['order']) && !empty($filter['order']))
{
$sort = "DESC";
if(isset($filter['sort']) && !empty($filter['sort']) && in_array( strtolower($filter['sort']),array('desc','asc')))
{
$sort = $filter['sort'];
}
$ordersql[] = " {$filter['order']} $sort ";
}
if(count($wheresql)>0)
{
$wheresql = " WHERE ".join(" AND ",$wheresql);
}else{
$wheresql = "";
}
if(count($ordersql)>0)
{
$ordersql = " ORDER BY ".join(',',$ordersql);
}else{
$ordersql = " ORDER BY m.status desc,m.ts_accepted desc ";
}
$sql = "select m.id,g.id as gid, md.uuid,md.title,u.username,u.realname,m.status,md.id as mdid,md.author,m.ts_accepted,count(r.id) as reviews
FROM mdstatus m
right join metadata md on md.uuid=m.uuid
left join geonetworkmetadata g on m.uuid=g.uuid
left join users u on u.id=m.userid
left join datasource s on s.uuid=md.uuid
left join mdreview r ON r.uuid=md.uuid
$wheresql
GROUP BY m.id,g.id, md.uuid,md.title,u.username,u.realname,m.status,md.id,md.author,m.ts_accepted
$ordersql";
$re = $this->db->query($sql);
$rows = $re->fetchAll();
return $rows;
}//getAdminReviews
/**
* 获取通过评审的元数据
* @return Sql\Select
*/
public function getReviewed(){
$select = new Sql\Select;
$select->from(['m'=>'mdstatus']);
$select->columns(['id','status','ts_finished']);
$select->join(["md"=>"metadata"], "md.uuid=m.uuid", ["title","uuid"], $select::JOIN_RIGHT);
$select->join(["u"=>"users"], "u.id=m.userid", ["username","realname"], $select::JOIN_LEFT);
$select->where("m.status = ".self::REVIEW_STATUS_PUBLISH);
if(!empty($this->opt->keyword))
{
$keyword = $this->opt->keyword;
$tools = $this->serviceManager->get('Tools');
if($tools->isUUID($keyword)) {
$select->where("md.uuid = '$keyword'");
}else{
$whereSql = function(Sql\Where $where) use ($keyword){
$where->AND->like('md.title',"%".$keyword."%");
$where->OR->like('md.title_en',"%".$keyword."%");
};
$select->where($whereSql,Sql\Predicate\PredicateSet::OP_AND);
}
}
$select->order("m.ts_finished DESC");
return $select;
}//getReviewed();
/**
* 取消评审
* @param $id
* @return bool
*/
public function cancel($id){
if(is_numeric($id))
{
$this->getEventManager()->trigger('review.canceled', $this, compact('id'));
return $this->changeStatus($id,self::REVIEW_STATUS_CANCELED);
}elseif(is_array($id)){
foreach($id as $item){
$item = (int)$item;
if($this->changeStatus($item,self::REVIEW_STATUS_CANCELED) === false)
return "ID:$item:取消失败";
}
$this->getEventManager()->trigger('review.canceled', $this, compact('id'));
return true;
}
return false;
}
/**
* 接收投稿的元数据
* @param $id
* @return bool
*/
public function accept($id){
if($this->getStatus($id) != self::REVIEW_STATUS_DEFAULT)
return [
'评审状态错误,有可能的错误是:',
'此评审已被取消,请到<b>已取消评审的元数据</b>中将其重置',
'此评审已经被接收',
'此评审已经处于待分配责任编辑、邀请专家、等待专家评审、已通过评审的状态中'
];
$status = $this->changeStatus($id,self::REVIEW_STATUS_ACCEPT);
if(false === $status){
return false;
}
$this->getEventManager()->trigger('review.accepted', $this, compact('id'));
return true;
}//accept($id)
/**
* 重置评审,将评审的状态设置为投稿元数据状态
* @param $id
* @return array|bool
*/
public function reset($id){
if(!is_array($id))
{
if($this->getStatus($id) != self::REVIEW_STATUS_CANCELED)
return [
'此条评审的当前状态已经不属于被取消的评审,可能已经由其他管理人员重置',
];
$status = $this->changeStatus($id,self::REVIEW_STATUS_DEFAULT);
if(false === $status)
return false;
}else{
$message = [];
foreach($id as $item)
{
$item = (int)$item;
if($this->getStatus($item) != self::REVIEW_STATUS_CANCELED){
$message[] = "ID:$item:此条评审的当前状态已经不属于被取消的评审,可能已经由其他管理人员重置";
continue;
}
$status = $this->changeStatus($item,self::REVIEW_STATUS_DEFAULT);
if(false === $status)
$message[] = "ID:$item:重置失败";
}
if(count($message) > 0)
return $message;
}
$this->getEventManager()->trigger('review.reset', $this, compact('id'));
return true;
}//reset()
/**
* 更改管理员
* @param $id array|int 可以输入数组
* @param $user_id int : 不能输入数组
* @return bool|string
*/
public function changeAdmin($id,$user_id)
{
if((!is_numeric($id) && !is_array($id)) || !is_numeric($user_id))
return false;
if(is_numeric($id)){
return $this->db->exec("UPDATE mdstatus SET userid=$user_id WHERE id=$id");
}
if(is_array($id))
{
try{
$this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->db->beginTransaction();
foreach($id as $item_id){
$item_id = $item_id+0;
$this->db->exec("UPDATE mdstatus SET userid=$user_id WHERE id=$item_id");
}
$this->db->commit();
return true;
}catch (\Exception $e){
$this->db->rollBack();
return $e->getMessage();
}
}
return false;
}//changeAdmin();
/**
* 重新评审
* @param $id
* @return bool|string
*/
public function restart($id)
{
if((!is_numeric($id) && !is_array($id)))
return false;
if(is_numeric($id))
return $this->changeStatus($id,self::REVIEW_STATUS_EXPERT_ACCEPT);
if(is_array($id))
{
try{
$this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->db->beginTransaction();
foreach($id as $item_id){
$item_id = $item_id+0;
$this->db->exec("UPDATE mdstatus SET status=".self::REVIEW_STATUS_EXPERT_ACCEPT." WHERE id=$item_id");
}
$this->db->commit();
return true;
}catch (\Exception $e){
$this->db->rollBack();
return $e->getMessage();
}
}
}//restart()
/**
* 更改mdstatus中的status字段
* @param $id
* @param $status
* @return bool
*/
protected function changeStatus($id,$status){
$statusValues = array(
self::REVIEW_STATUS_CANCELED, //取消评审
self::REVIEW_STATUS_DEFAULT, //初始状态
self::REVIEW_STATUS_ACCEPT, //接受元数据评审,进入评审阶段
self::REVIEW_STATUS_EXPERT_INVITED, //开始邀请专家,送审阶段
self::REVIEW_STATUS_EXPERT_ACCEPT, //专家接受邀请,在审阶段
self::REVIEW_STATUS_EXPERT_FEEDBACK,//专家反馈,在审
self::REVIEW_STATUS_PUBLISH, //评审结束,发布
6,7
);
if(empty($id) || !isset($status) || !in_array($status,$statusValues))
{
return false;
}
else
{
if($status==1)
{$sql = "update mdstatus set status='$status',ts_accepted='now()' where id in ($id)"; }
else if($status==5)
{$sql = "update mdstatus set status='$status',ts_finished='now()' where id in ($id)";}
else
{$sql = "update mdstatus set status='$status' where id in ($id)";}
try{
if($this->db->exec($sql)>0)
{
return true;
}
}
catch(\Exception $e)
{
return false;
}
}
}//changestatus 更改状态
/**
* 获取mdstatus表中的status字段
* @param $id
* @return mixed
*/
public function getStatus($id)
{
$sql = "SELECT status FROM mdstatus WHERE id=$id";
$rs = $this->db->query($sql);
return $rs->fetchColumn(0);
}
}