westdc-core/Westdc/Reference/Ris.php

334 lines
7.5 KiB
PHP
Raw Normal View History

<?php
namespace Westdc\Reference;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Westdc\EventModel\AbstractEventManager;
use Westdc\Reference\Listener\RisListener;
use LibRIS\RISReader;
use LibRIS\RISTags;
use LibRIS\RISWriter;
class Ris extends AbstractEventManager implements ServiceManagerAwareInterface
{
protected $serviceManager;
public $table;
public $ris_records = NULL;
private $dbh;
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
$this->init();
return $this;
}
public function init()
{
$Listener = new RisListener;
$this->getEventManager()->attachAggregate($Listener);
$this->table = new \stdClass;
$this->table->reference = "reference";
$this->table->reference_author = "ref_author";
$this->table->reference_tag = "ref_tag";
}
//ris导入
public function loadout()
{
$file = $this->uploadRisFile();
$text = $this->loadRisText();
if(empty($text) && $file === false)
{
return "导入失败请选择要导入的文件或直接使用ris文本";
}
$records = array();
if($file !== false)
{
$records = array_merge($records,$this->processRis($file,NULL));
}
if(!empty($text))
{
$records = array_merge($records,$this->processRis(NULL,$text));
}
$this->ris_records = $records;
$data = $this->reBuildRisArray($records);
return $data;
}
//上传RIS文件
public function uploadRisFile()
{
if(!isset($_FILES['Filedata']))
{
return;
}
$file = $_FILES['Filedata'];
if (@is_uploaded_file($file['tmp_name']) === false) {
return;
}
return $file;
}
//文本直接导入
public function loadRisText()
{
if(!isset($_REQUEST['ristext']))
{
return;
}
$text = $_REQUEST['ristext'];
return $text;
}
//处理ris文件
public function processRis($file = NULL,$text = NULL)
{
$ris = new RISReader();
if(!empty($file) && empty($text))
{
$ris->parseFile($file['tmp_name']);
}else{
$ris->parseString($text);
}
$records = $ris->getRecords();
return $records;
}
//对解析过的数据进行编排
public function reBuildRisArray($records)
{
$data = array();
foreach($records as $k=>$ref)
{
$data[$k] = array();
foreach($ref as $index=>$value)
{
if(isset($this->attr[$index]))
{
$index_name = $this->attr[$index];
if(count($value) > 1)
{
$data[$k][$index_name] = array();
foreach($value as $item)
{
$data[$k][$index_name][] = $item;
}
}else{
$data[$k][$index_name] = $value[0];
}
}
}
}
unset($records);
return $data;
}
//将解析好的ris数据写入数据库
public function pushToDataTable($data){
if(!is_array($data) || count($data) < 1)
{
return false;
}
$dbService = $this->serviceManager->get('Db');
$dbh = $this->dbh = $dbService->getDbh();
foreach($data as $k=>$ref)
{
if (is_null($ref['title']))
{
return;
}
@$tags = $ref['tags'];
@$author = $ref['author'];
$ref['ris'] = $this->makeRisData(array(0=>$this->ris_records[$k]));
$results = $this->getEventManager()->trigger('checkLoad', $this, compact('ref'));
$id = $results->bottom();
if ($id > 0)
{
$this->unsetVar($ref);
$this->getEventManager()->trigger('delete.after', $this, compact('id'));
unset($ref['reference']);
$dbh->update($this->table->reference,$ref," id=$id ");
} else {
$ref['reference'] = $this->makeReferenceFlag($ref);
$this->unsetVar($ref);
$id = $dbh->insert($this->table->reference,$ref,true);
}
$this->insertTags($id,$tags);
$this->insertAuthor($id,$author);
}
}
//更新单个reference的RIS
public function updateWithRis($id,$ref)
{
if(empty($id) || !is_numeric($id))
{
return false;
}
if (is_null($ref['title']))
{
return;
}
@$tags = $ref['tags'];
@$author = $ref['author'];
$ref['ris'] = $this->makeRisData(array(0=>$this->ris_records[0]));
$this->getEventManager()->trigger('delete.after', $this, compact('id'));
$this->getEventManager()->trigger('delete.after', $this, compact('id'));
$this->unsetVar($ref);
if(isset($ref['reference'])) unset($ref['reference']);
$dbService = $this->serviceManager->get('Db');
$this->dbh = $dbh = $dbService->getDbh();
if($dbh->update($this->table->reference,$ref," id=$id "))
{
$this->insertTags($id,$tags);
$this->insertAuthor($id,$author);
return true;
}else{
return false;
}
}
//写入标签
public function insertTags($id,$tags){
if(is_array($tags) && count($tags) > 0)
{
foreach($tags as $v)
{
$this->dbh->insert($this->table->reference_tag,array('id'=>$id,'tag'=>$v));
}
return true;
}else{
return false;
}
}
//写入作者
public function insertAuthor($id,$author)
{
$index = 0;
if(is_array($author) && count($author) > 0)
{
foreach($author as $v)
{
$index ++ ;
$author_splited = $this->splitAuthor($v);
$this->dbh->insert($this->table->reference_author,array('id'=>$id , 'lastname'=>$author_splited['lastname'] , 'firstname'=>$author_splited['firstname'] , 'place'=>$index ));
}
return true;
}else{
if(is_string($author))
{
$author_splited = $this->splitAuthor($author);
$this->dbh->insert($this->table->reference_author,array('id'=>$id , 'lastname'=>$author_splited['lastname'] , 'firstname'=>$author_splited['firstname'] , 'place'=>0 ));
}
return false;
}
}
//创建ris格式的数据
public function makeRisData($ref)
{
$ris_writer = new RISWriter();
return $ris_writer->writeRecords($ref);
}
//创建reference 字段
public function makeReferenceFlag($ref){
$str='';
if(is_array($ref['author']) && count($ref['author']) > 0)
{
$str .= join(', ',$ref['author']).'. ';
} else if (is_string($ref['author'])) {
$str .= $ref['author'].'. ';
}
$str .= $ref['title'].'. ';
$str .= $ref['publisher'].', ';
isset($ref['year']) ? $str .= $ref['year'].', ':"";
isset($ref['volume']) ? $str .= $ref['volume']:"";
isset($ref['issue']) ? $str .= '('.$ref['issue'].')':"";
isset($ref['pages']) ? $str .= ':'.$ref['pages']:"";
isset($ref['endpage'])? $str .= '-'.$ref['endpage']:"";
isset($ref['doi']) ? $str .= '. doi:'.$ref['doi'] : "";
return $str;
}
//卸载不需要的变量
public function unsetVar(&$ref)
{
unset($ref['pages']);
unset($ref['endpage']);
unset($ref['issue']);
unset($ref['volume']);
unset($ref['tags']);
unset($ref['author']);
}
//将作者名字分割为数组
public function splitAuthor($author){
if(preg_match("/\,/",$author))
{
$arr = explode(",",$author);
return array(
'lastname' => trim($arr[0]),
'firstname' => trim($arr[1])
);
}else{
return array(
'firstname' => '',
'lastname' => trim($author)
);
}
}
public $attr = array(
'TY' => 'type',
'TI' => 'title',
'AU' => 'author',
'PY' => 'year',
'LA' => 'language',
'KW' => 'tags',
'AB' => 'abstract',
'DO' => 'doi',
'T2' => 'publisher',
'VL' => 'volume',
'IS' => 'issue',
'SP' => 'pages',
'EP' => 'endpage'
);
}