3 require('../../../config.php');
\r
5 // An instance will be created at the end of this file
\r
7 class PubMedAdmin extends BaseActions {
\r
8 private $oPluginAdmin,$plugin;
\r
10 function __construct(){
\r
11 if (method_exists($this,'BaseActions')) $this->BaseActions();
\r
13 global $DIR_LIBS,$manager,$member,$CONF, $HTTP_POST_VARS;
\r
14 include($DIR_LIBS . 'PLUGINADMIN.php');
\r
17 $this->oPluginAdmin = new PluginAdmin('PubMed');
\r
18 $this->plugin=&$this->oPluginAdmin->plugin;
\r
19 if (!($this->blogid=intPostVar('blogid'))) $this->blogid=intGetVar('blogid');
\r
20 $CONF['ItemURL']=quickQuery('SELECT burl as result FROM '.sql_table('blog'). ' WHERE bnumber='.(int)$this->blogid);
\r
22 // Check if there is right to maintain the blog or the manuscript.
\r
24 if (!$member->isLoggedIn()) $ok=false;
\r
25 if (!$member->CanLogin()) $ok=false;
\r
26 if ($this->blogid) {
\r
27 if (!$member->teamRights($this->blogid)) $ok=false;
\r
28 if (!$manager->existsBlogID($this->blogid)) $ok=false;
\r
31 $this->oPluginAdmin->start();
\r
32 echo '<p>' . _ERROR_DISALLOWED . '</p>';
\r
33 $this->oPluginAdmin->end();
\r
37 // If some data is/are posted, check the ticket.
\r
38 // Therefore, POST method must be used to change important parameter(s).
\r
39 if (count($_POST) && !$manager->checkTicket()) {
\r
40 $this->oPluginAdmin->start();
\r
41 echo '<p class="error">Error: ' . _ERROR_BADTICKET . '</p>';
\r
42 $this->oPluginAdmin->end();
\r
47 if (!($action=postVar('action'))) {
\r
48 if (!($action=getVar('action'))) $action='searchform';
\r
52 // All the method that starts from a-z can be action.
\r
53 // Method that starts from _ is private method.
\r
54 $this->oPluginAdmin->start();
\r
55 switch(getVar('action')) {
\r
56 case 'manuscriptlist':
\r
57 echo '<h2><a href="'.$this->plugin->getAdminURL().
\r
58 '?action=manuscriptlist">' .
\r
59 'Manuscript management' . "</a></h2>\n";
\r
62 echo '<h2><a href="'.$this->plugin->getAdminURL().'?blogid='.
\r
63 (int)$this->blogid.'">' .
\r
64 'PubMed search' . "</a></h2>\n";
\r
66 call_user_func(array(&$this,"action_$action"));
\r
67 $this->oPluginAdmin->end();
\r
70 * Getenal parse routines follow
\r
72 private $contents=array();
\r
73 private function _getTemplate($name,$type='body'){
\r
75 if (!isset($templates)) {
\r
76 // Prepare template data
\r
77 $xml=simplexml_load_file(dirname(__FILE__).'/index.xml');
\r
79 foreach($xml->template as $obj) {
\r
80 $templates[(string)$obj->name]==array();
\r
81 foreach($obj as $key=>$value) $templates[(string)$obj->name][$key]=(string)$value;
\r
84 if ($type=='array') return $templates[$name];
\r
85 elseif (isset($templates[$name][$type])) return $templates[$name][$type];
\r
88 private function _parse($template){
\r
90 if (!isset($parser)){
\r
91 $actions=array('note','blogid','ticket','hsc','stg','int','raw','conf',
\r
92 'postvar','getvar','self',
\r
93 'if','ifnot','else','elseif','elseifnot','endif');
\r
94 $parser =& new PARSER($actions, $this);
\r
96 $parser->parse($template);
\r
98 private function template_parse($tempname,$data=false,$type='body'){
\r
99 $template=$this->_getTemplate($tempname,'array');
\r
100 $contents=$this->contents;
\r
101 if ($data) $this->contents=$data;
\r
102 $this->_parse($template[$type]);
\r
103 $this->contents=$contents;
\r
105 private function _showUsingArray($tempname,$array){
\r
106 $this->template_parse($tempname,false,'head');
\r
107 foreach($array as $row) $this->template_parse($tempname,$row);
\r
108 $this->template_parse($tempname,false,'foot');
\r
110 public function parse_note(){
\r
111 // Don't do anythig.
\r
113 public function parse_blogid(){
\r
114 echo (int)$this->blogid;
\r
116 public function parse_ticket(){
\r
118 $manager->addTicketHidden();
\r
120 public function parse_hsc($key){
\r
121 self::_hsc($this->contents[$key]);
\r
123 public function parse_stg($key){
\r
124 self::_hsc(strip_tags($this->contents[$key]));
\r
126 public function parse_int($key){
\r
127 echo (int)$this->contents[$key];
\r
129 public function parse_raw($key){
\r
130 echo $this->contents[$key];
\r
132 public function parse_conf($key){
\r
134 self::_hsc($CONF[$key]);
\r
136 public function parse_getvar($key){
\r
137 self::_hsc(getVar($key));
\r
139 public function parse_postvar($key){
\r
140 self::_hsc(postVar($key));
\r
142 public function parse_self(){
\r
143 self::_hsc($this->plugin->getAdminURL());
\r
145 static private function _hsc($text){
\r
146 echo htmlspecialchars($text,ENT_QUOTES,_CHARSET);
\r
148 protected function checkCondition($key,$value=false){
\r
149 if ($value===false) return $this->contents[$key] ? 1 : 0;
\r
150 else return $this->contents[$key]==$value ? 1 : 0;
\r
152 /* Pubmed Search */
\r
153 private function action_searchform(){
\r
154 $this->template_parse('searchform');
\r
156 private function action_searchquery(){
\r
157 global $manager,$CONF;
\r
158 $this->action_searchform();
\r
159 // Get PubMed ids as the result
\r
160 $start=intPostVar('retstart');
\r
161 if (!($max=intPostVar('retmax'))) $max=20;
\r
162 $fhandle=$this->_url_open('http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?'.
\r
163 'db=pubmed&retmode=xml'.
\r
164 '&retstart='.(int)$start.'&retmax='.(int)$max.
\r
165 '&term='.urlencode(postVar('query')));
\r
166 if (!$fhandle) exit('Error: '.__LINE__);
\r
169 $data = fread($fhandle, 8192);
\r
170 if (!strlen($data)) break;
\r
171 $contents .= $data;
\r
174 // Get query results
\r
176 $result['max']=$this->_getXmlData($contents,'RetMax');
\r
177 $result['start']=$this->_getXmlData($contents,'RetStart');
\r
178 $result['count']=$this->_getXmlData($contents,'Count');
\r
179 $result['querykey']=$this->_getXmlData($contents,'QueryKey');
\r
180 $result['webenv']=$this->_getXmlData($contents,'WebEnv');
\r
181 // Get id information
\r
182 $contents=$this->_getNestedXmlData($contents,'IdList','');
\r
183 if (!strstr($contents,'<Id>')) {
\r
184 $this->template_parse('noresult');
\r
187 $contents=explode('<Id>',$contents);
\r
190 foreach($contents as $value){
\r
191 if (!($value=(int)$value)) continue;
\r
192 if (!$ids) $ids='&id='.$value;
\r
193 else $ids.=','.$value;
\r
194 $likes.=' OR ibody LIKE "%<!--PMID: '.(int)$value.'-->%"';
\r
196 // Check if there are records for the articles
\r
197 $dataexists=array();
\r
198 $res=sql_query('SELECT ibody,inumber FROM '.sql_table('item').
\r
199 ' WHERE (0 '.$likes.') AND iblog='.(int)$this->blogid);//$likes is clean (see few lines above).
\r
200 while ($row=mysql_fetch_assoc($res)){
\r
201 if (!preg_match('/<!\-\-PMID:[\s]*([0-9]+)\-\->/i',$row['ibody'],$matches)) continue;
\r
202 $dataexists[(int)$matches[1]]=(int)$row['inumber'];
\r
206 $fhandle=$this->_url_open('http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?'.
\r
208 if (!$fhandle) exit('Error: '.__LINE__);
\r
211 $data = fread($fhandle, 8192);
\r
212 if (!strlen($data)) break;
\r
213 $contents .= $data;
\r
219 foreach($result as $key=>$value) $result[$key]=htmlspecialchars($value,ENT_QUOTES);
\r
223 $this->template_parse('searchresultth',array(
\r
224 'start'=>$result['start'],
\r
225 'nextexists'=>$result['start']+$max<=$result['count'],
\r
226 'prev'=>$result['start']-$max,
\r
227 'next'=>$result['start']+$max,
\r
229 'page'=>(int)(1+($result['start']/$max)),
\r
230 'pagemax'=>(int)(1+($result['count']-1)/$max) ));
\r
231 $tableth=ob_get_contents(); // Will be used later to show the same th navigation bar.
\r
234 // Prepare select tag for category selection.
\r
235 $defcatid=(int)cookieVar($CONF['CookiePrefix'] . 'NP_PubMed_defcatid');
\r
236 if (!$defcatid) $defcatid=quickQuery('SELECT bdefcat as result FROM '.sql_table('blog').' WHERE bnumber='.(int)$CONF['DefaultBlog']);
\r
237 $res=sql_query('SELECT * FROM '.sql_table('category').
\r
238 ' WHERE cblog='.(int)$this->blogid.' ORDER BY cname ASC');
\r
240 while($row=mysql_fetch_assoc($res)){
\r
241 $row['selected']=($row['catid']==$defcatid);
\r
245 $this->_showUsingArray('selectcategory',$array);
\r
246 $categories=ob_get_contents();
\r
249 // Show the results
\r
250 if (!($contents=$this->_getNestedXmlData($contents,'eSummaryResult',''))) exit('Error: '.__LINE__);
\r
251 $contents=explode('<DocSum>',$contents);
\r
253 foreach($contents as $summary){
\r
254 if (strpos($summary,'</DocSum>')===false) continue;
\r
256 $row['date']=$this->_getXmlData($summary,'Item','???','Name="PubDate"');
\r
257 $row['journal']=$this->_getXmlData($summary,'Item','???','Name="Source"');
\r
258 $row['title']=$this->_getXmlData($summary,'Item','???','Name="Title"');
\r
259 $row['volume']=$this->_getXmlData($summary,'Item','???','Name="Volume"');
\r
260 $row['pages']=$this->_getXmlData($summary,'Item','???','Name="Pages"');
\r
261 $row['pmid']=$this->_getXmlData($summary,'Id','???');
\r
262 $row['authors']='???';
\r
263 if ($num=preg_match_all('!<Item[\s]+Name="Author"[^>]*>([^<]+)</Item>!',$summary,$matches,PREG_SET_ORDER)){
\r
264 for ($i=0;$i<$num;$i++) {
\r
267 $row['authors']=htmlspecialchars($matches[$i][1]);
\r
269 case 1:case 2:case 3:case 4:
\r
271 $row['authors'].=', '.htmlspecialchars($matches[$i][1]);
\r
274 $row['authors'].=', ... ';
\r
280 if (array_key_exists((int)$row['pmid'],$dataexists)) {
\r
281 $row['addbutton']=0;
\r
282 $row['itemurl']=createItemLink($dataexists[(int)$row['pmid']], '');
\r
284 $row['addbutton']=1;
\r
285 $row['categories']=$categories;
\r
289 $this->_showUsingArray('searchresulttd',$array);
\r
291 // Navigation bar and Footer
\r
295 private function _getXmlData(&$xml,$tag,$default='???',$extra=''){
\r
296 if (preg_match('!<'.$tag.'[^>]*'.$extra.'[^>]*>([^<]+)</'.$tag.'>!',$xml,$matches)){
\r
297 return $matches[1];
\r
298 } else return $default;
\r
300 private function _getNestedXmlData(&$xml,$tag,$default='???'){
\r
301 if (preg_match('!<'.$tag.'[^>]*>([\s\S]+)</'.$tag.'>!',$xml,$matches)){
\r
302 return $matches[1];
\r
303 } else return $default;
\r
305 private function _url_open($url){
\r
306 return $this->oPluginAdmin->plugin->_url_open($url);
\r
309 /* Manunscript Management */
\r
310 private function action_manuscriptlist(){
\r
312 $res=sql_query('SELECT * FROM '.sql_table('plugin_pubmed_manuscripts').
\r
313 ' WHERE userid='.(int)$member->getID());
\r
315 while($row=mysql_fetch_assoc($res)) $array[]=$row;
\r
316 $this->_showUsingArray('manuscriptlist',$array);
\r
320 private function action_deletemanuscript(){
\r
321 global $member,$manager;
\r
322 $mid=$member->getID();
\r
323 $manuscriptid=intPostVar('manuscriptid');
\r
324 $mname=quickQuery('SELECT manuscriptname as result FROM '.sql_table('plugin_pubmed_manuscripts').
\r
325 ' WHERE manuscriptid='.(int)$manuscriptid.
\r
326 ' AND userid='.(int)$mid);
\r
327 if (!$mname) exit('Invalid manuscriptid!');
\r
328 if (postVar('sure')=='yes') {
\r
329 sql_query('DELETE r.* FROM '.sql_table('plugin_pubmed_references').' as r, '.
\r
330 sql_table('plugin_pubmed_manuscripts').' as m'.
\r
331 ' WHERE m.manuscriptid='.(int)$manuscriptid.
\r
332 ' AND m.userid='.(int)$mid.
\r
333 ' AND m.manuscriptid=r.manuscriptid');
\r
334 sql_query('DELETE FROM '.sql_table('plugin_pubmed_manuscripts').
\r
335 ' WHERE manuscriptid='.(int)$manuscriptid.
\r
336 ' AND userid='.(int)$mid);
\r
337 $this->template_parse('deletemanuscript',array('mname'=>$mname),'notice');
\r
338 return $this->action_manuscriptlist();
\r
340 $this->template_parse('deletemanuscript',array('mid'=>$manuscriptid,'mname'=>$mname));
\r
343 private function action_createmanuscript(){
\r
344 global $member,$manager;
\r
345 $mid=$member->getID();
\r
346 $mname=$this->_checkmanuscriptname(postVar('manuscriptname'));
\r
347 if ($mname) sql_query('INSERT INTO '.sql_table('plugin_pubmed_manuscripts').' SET'.
\r
348 ' userid='.(int)$mid.','.
\r
349 ' manuscriptname="'.addslashes($mname).'"');
\r
350 return $this->action_manuscriptlist();
\r
352 private function _getSortMethod($tempname){
\r
353 // Note that $tempname is valid once.
\r
355 if (isset($ret)) return $ret;
\r
356 require_once(dirname(__FILE__).'/template.php');
\r
357 $tobj=PUBMED_TEMPLATE_BASE::getTemplate($tempname);
\r
358 if (!$tobj) return false;
\r
359 $tobj->setSortText('');
\r
360 $tobj->sortPapers();
\r
361 if ($tobj->getSortText()=='authorname') $ret='authorname';
\r
362 else $ret='manual';
\r
365 private function _checkmanuscriptname($mname,$id=0){
\r
367 $mid=$member->getID();
\r
368 $mname=preg_replace('/[^0-9a-zA-Z\._\-]+/','',$mname);
\r
369 $mname=preg_replace('/[\s]+/',' ',$mname);
\r
370 $query='SELECT COUNT(*) as result FROM '.sql_table('plugin_pubmed_manuscripts').
\r
371 ' WHERE userid='.(int)$mid.
\r
372 ' AND manuscriptname="'.addslashes($mname).'"';
\r
373 if ($id) $query.=' AND NOT (manuscriptid='.(int)$id.')';
\r
374 if (!$mname) echo "<b>Manuscript name is empty.</b><br />\n";
\r
375 elseif (quickQuery($query)) echo "<b>The same manuscript exists.</b><br />\n";
\r
376 else return $mname;
\r
380 private function action_editmanuscript(){
\r
381 global $member,$manager;
\r
382 $mid=$member->getID();
\r
383 $manuscriptid=intPostVar('manuscriptid');
\r
384 $res=sql_query('SELECT * FROM '.sql_table('plugin_pubmed_manuscripts').
\r
385 ' WHERE manuscriptid='.(int)$manuscriptid.
\r
386 ' AND userid='.(int)$mid.
\r
388 $row=mysql_fetch_assoc($res);
\r
389 if (!$row) exit('Invalid manuscriptid!');
\r
390 $mname=postVar('manuscriptname');
\r
391 if (!$mname) $mname=$row['manuscriptname'];
\r
392 $mname=$this->_checkmanuscriptname($mname,$manuscriptid);
\r
393 if (!$mname) return $this->manuscriptlist();
\r
394 $template=$row['templatename'];
\r
395 if (postVar('sure')=='yes') {
\r
396 $template=postVar('templatename');
\r
397 $sorttext=postVar('sorttext');
\r
398 $sortmethod=$this->_getSortMethod($template);
\r
400 if ($sortmethod=='authorname') $sorttext='authorname';
\r
401 sql_query('UPDATE '.sql_table('plugin_pubmed_manuscripts').' SET'.
\r
402 ' manuscriptname="'.addslashes($mname).'",'.
\r
403 ' templatename="'.addslashes($template).'",'.
\r
404 ' sorttext="'.addslashes($sorttext).'"'.
\r
405 ' WHERE manuscriptid='.(int)$manuscriptid.
\r
406 ' AND userid='.(int)$mid);
\r
407 $this->template_parse('editmanuscript',array('mname'=>$mname),'notice');
\r
409 echo "<b>The template '".htmlspecialchars($template)."' does not exist.</b>";
\r
411 return $this->action_manuscriptlist();
\r
413 // Get template files
\r
414 $templates=array();
\r
415 $d=dir(dirname(__FILE__).'/templates/');
\r
416 while (false !== ($entry = $d->read())) {
\r
417 if (!preg_match('/^(.+)\.php$/',$entry,$m)) continue;
\r
418 if ($m[1]=='edit' || $m[1]=='default') continue;
\r
419 $templates[]=$m[1];
\r
422 array_unshift($templates,'default');
\r
425 // Show using array
\r
427 foreach($templates as $temp) $array[]=array('template'=>$temp,'selected'=>$template==$temp);
\r
428 $this->contents=array('mid'=>$manuscriptid,'mname'=>$mname);
\r
429 $this->_showUsingArray('editmanuscript',$array);
\r
431 function action_addmanually(){
\r
433 if (count($_POST)) {
\r
434 // Add item with the defined PMID
\r
435 $pmid=intPostVar('pmid');
\r
436 // Determine author list
\r
437 $author=requestArray('author');
\r
438 $authorf=requestArray('authorf');
\r
439 $authorm=requestArray('authorm');
\r
441 foreach($author as $key=>$value){
\r
442 if (!strlen($value)) break;
\r
446 $i=substr($f,0,1).substr($m,0,1);
\r
447 $authors[$key]=array(
\r
453 // Construct Article
\r
454 if (($year=intPostVar('year'))==0) $year='???';
\r
455 if (strlen($journalname=postVar('journal'))==0) $journalname='???';
\r
456 if (strlen($volume=postVar('volume'))==0) $volume='???';
\r
457 if (strlen($pages=postVar('pages'))==0) $pages='???';
\r
458 if (strlen($title=postVar('title'))==0) $title='???';
\r
459 if (strlen($abstract=postVar('abstract'))==0) $abstract='???';
\r
461 'ISOAbbreviation'=>$journalname,
\r
462 'JournalIssue'=>array(
\r
464 'PubDate'=>array('Year'=>$year)
\r
468 'Journal'=>$journal,
\r
469 'ArticleTitle'=>$title,
\r
470 'Pagination'=>array('MedlinePgn'=>$pages),
\r
471 'AuthorList'=>array('Author'=>$authors)
\r
473 // Construct XML data as more
\r
476 'Article'=>$article
\r
478 $more='<span class="np_pubmed_abstract">'.htmlspecialchars($abstract).'</span>';
\r
479 $more.="<span style=\"display:none;\"><![CDATA[\n";
\r
480 $more.=$this->_convert2xml('MedlineCitation',$medline);
\r
481 $more.=']]></span>';
\r
483 $body="<!--$year--><!--PMID: $pmid-->PMID: $pmid\n";
\r
484 $body.='<span class="np_pubmed_authors">';
\r
485 $n=count($authors);
\r
486 for ($i=1;$i<=$n;$i++) {
\r
489 if ($i==$n) $body.='and ';
\r
491 $body.=htmlspecialchars($authors[$i]['LastName']);
\r
493 $body.=" ($year)</span>\n";
\r
494 $body.='<span class="np_pubmed_article"><i>'.htmlspecialchars($journalname).
\r
495 '</i> <b>'.htmlspecialchars($volume).
\r
496 '</b> '.htmlspecialchars($pages)."</span>\n";
\r
497 $body.='<span class="np_pubmed_title">'.htmlspecialchars($title).'</span>';
\r
501 $title=$authors[1]['LastName'];
\r
504 $title=$authors[1]['LastName'].' and '.$authors[2]['LastName'];
\r
507 $title=$authors[1]['LastName'].' et al.';
\r
510 $title=htmlspecialchars($title." ($year) $journalname");
\r
511 // Construct category options
\r
512 $defcatid=(int)cookieVar($CONF['CookiePrefix'] . 'NP_PubMed_defcatid');
\r
514 $blog=$manager->getBlog($this->blogid);
\r
515 $defcatid=$blog->getDefaultCategory();
\r
517 $res=sql_query('SELECT * FROM '.sql_table('category').
\r
518 ' WHERE cblog='.(int)$this->blogid.' ORDER BY cname ASC');
\r
520 while($row=mysql_fetch_assoc($res)){
\r
521 $row['selected']= ($row['catid']==$defcatid);
\r
525 $this->contents=array('title'=>$title,'body'=>$body,'more'=>$more);
\r
526 $this->_showUsingArray('addmanuallyconfirm',$array);
\r
530 $pmid=1+$this->plugin->getOption('lastmanualpmid');
\r
531 if ($pmid<1000000000) $pmid=1000000001;
\r
533 while(quickQuery('SELECT count(*) as result from '.sql_table('item').
\r
534 ' WHERE iblog='.(int)$this->blogid.
\r
535 ' AND ibody LIKE "%'.(int)$pmid.'%"') ){
\r
536 $this->plugin->setOption('lastmanualpmid',$pmid);
\r
540 // Get the number of authors
\r
541 $numauthor=intGetVar('numauthor');
\r
542 if (!$numauthor) $numauthor=3;
\r
544 for ($i=1;$i<=$numauthor;$i++) {
\r
545 $array[]=array('i'=>$i);
\r
548 $this->contents=array('pmid'=>$pmid,'i'=>$numauthor,'numauthor'=>$numauthor*2);
\r
549 $this->_showUsingArray('addmanually',$array);
\r
551 function _convert2xml($key,$value,$nest=0){
\r
552 if (!preg_match('/^[a-zA-Z0-9_]+$/',$key)) exit;
\r
553 if (!is_array($value)) {
\r
554 $value=str_replace(array('<','>'),array('>','<'),$value);
\r
555 return str_repeat(' ',$nest)."<$key>$value</$key>\n";
\r
558 foreach ($value as $k=>$v) {
\r
559 if (is_numeric($k)) $xml.=$this->_convert2xml($key,$v,$nest+1);
\r
561 if ($xml=='') $xml=str_repeat(' ',$nest)."<$key>\n";
\r
562 $xml.=$this->_convert2xml($k,$v,$nest+1);
\r
565 if (!is_numeric($k)) $xml.=str_repeat(' ',$nest)."</$key>\n";
\r