1<?php
2if(!defined('DOKU_INC')) die();
3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4require_once(DOKU_PLUGIN.'syntax.php');
5
6class syntax_plugin_pdb extends DokuWiki_Syntax_Plugin {
7  var $ncbi;
8  var $rcsb;
9  var $imgCache;
10  var $xmlCache;
11  var $searchBox;
12  var $imageW    = array();
13
14  function syntax_plugin_pdb(){
15    global $conf;
16    $this->name = 'pdb';
17    if (!class_exists('plugin_cache'))
18        @require_once(DOKU_PLUGIN.$this->name.'/classes/cache.php');
19    if (!class_exists('rcsb')||!class_exists('ncbi')||!class_exists('xml'))
20        @require_once(DOKU_PLUGIN.$this->name.'/classes/sciencedb.php');
21
22    $this->ncbi     = new ncbi();
23    $this->rcsb     = new rcsb();
24    $this->xmlCache = new plugin_cache("ncbi_esummary","structure","xml.gz");
25    $this->imgCache = new plugin_cache("rcsb_image",'',"jpg");
26    $this->searchBox= DOKU_PLUGIN.'pdb/pdb_search_box.htm';
27    $this->imageW['small']  =  80;
28    $this->imageW['medium'] = 250;
29    $this->imageW['large']  = 500;
30  }
31
32  function getType(){ return 'substition'; }
33  function getSort(){ return 158; }
34  function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{pdb>[^}]*\}\}',$mode,'plugin_pdb'); }
35
36 /**
37  * Handle the match
38  */
39  function handle($match, $state, $pos, Doku_Handler $handler){
40    $match = substr($match,6,-2);
41    return array($state,explode(':',$match));
42  }
43
44 /**
45  * Create output
46  */
47  function render($mode, Doku_Renderer $renderer, $data){
48    if($mode != 'xhtml'){return false;}
49    list($state, $query) = $data;
50    list($cmd,$pdbid) = $query;
51    $pdbid = urlencode($pdbid);
52    $cmd   = strtolower($cmd);
53
54    if ($cmd=='small' || $cmd=='medium' || $cmd=='large'){
55      $filename = $this->imgCache->GetMediaPath($pdbid);
56      if ($this->rcsb->DownloadImage($pdbid,$filename)!==false)
57        $renderer->doc.= $this->getImageHtml($pdbid,$cmd).NL;
58      else
59        $renderer->doc.= $this->getLang('pdb_no_image').NL;
60      return true;
61
62    }else if($cmd=='short'||$cmd=='long'){
63      $summaryXML = $this->getSummaryXML($pdbid);
64      if(!empty($summaryXML))
65        $renderer->doc.= $this->getTextHtml($pdbid,$cmd,$summaryXML);
66      else
67        $renderer->doc.= $this->getLang('pdb_no_summary').NL;
68      return true;
69
70    }else if($cmd=='fullsmall'){
71      $filename = $this->imgCache->GetMediaPath($pdbid);
72      if ($this->rcsb->DownloadImage($pdbid,$filename)!==false)
73        $imageHtml = $this->getImageHtml($pdbid,"small").NL;
74      else
75        $imageHtml = $this->getLang('pdb_no_image').NL;
76      $renderer->doc.='<div class="pdb_full_left">'.$imageHtml.'</div>'.NL;
77
78
79      $summaryXML = $this->getSummaryXML($pdbid);
80      if(!empty($summaryXML))
81        $textHtml = $this->getTextHtml($pdbid,"long",$summaryXML);
82      else
83        $renderer->doc.= $this->getLang('pdb_no_summary').NL;
84      $renderer->doc.='<div class="pdb_full_right">'.$textHtml.'</div>'.NL;
85
86      $renderer->doc.='<div style="clear:both"></div>'.NL;
87      return true;
88    }
89
90    switch($cmd){
91      case 'searchbox':
92        $renderer->doc .= file_get_contents($this->searchBox);
93        return true;
94
95      case 'link':
96        $renderer->doc .= $this->rcsb->ExplorerLink($pdbid);
97        return true;
98
99      case 'summaryxml':
100        $summaryXML = $this->getSummaryXML($pdbid);
101        $renderer->doc.="<pre>".htmlspecialchars($summaryXML)."</pre>";
102        return true;
103
104      case 'structureid':
105        $summaryXML = $this->getSummaryXML($pdbid);
106        $sid = $this->ncbi->GetSearchItem("Id",$summaryXML);
107        if (!empty($sid)){
108        $renderer->doc.="StructureID:".$sid;
109        }else{
110        $renderer->doc.=$pdbid." was not found.";
111        }
112        return true;
113
114      case 'clear_summary':
115        $renderer->doc.="Summary cleared.";
116        $this->xmlCache->ClearCache();
117        return true;
118
119      case 'clear_image':
120        $renderer->doc.="Image cleared.";
121        $this->imgCache->ClearCache();
122        return true;
123
124      case 'remove_dir':
125        $renderer->doc.="Directory removed";
126        $this->xmlCache->RemoveDir();
127        $this->imgCache->RemoveDir();
128        return true;
129
130      default:
131        // Command was not found..
132        $renderer->doc.='<div class="pdb_plugin">'.sprintf($this->getLang('plugin_cmd_not_found'),$cmd).'</div>';
133        $renderer->doc.='<div class="pdb_plugin_text">'.$this->getLang('pdb_available_cmd').'</div>';
134        return true;
135    }
136  }
137
138 /**
139  * Get renderered Html of Image
140  */
141  function getImageHtml($pdbid,$type){
142    $pdbid = $this->rcsb->PDBformat($pdbid);
143    if ($pdbid===false) return NULL;
144    $url = $this->imgCache->GetMediaLink($pdbid);
145    $w = $this->imageW[$type];
146    $html = '<a href="'.$this->rcsb->ExplorerURL($pdbid).'"><div class="pdb_image'.$w.'">';
147    $html.= '<img src="'.$url.'" alt="PDB image" title="'.$pdbid.'" width="'.$w.'"/>';
148    $html.= '</div></a>';
149    return $html;
150  }
151
152 /**
153  * Get renderered Html of Texts
154  */
155  function getTextHtml($pdbid,$type,$summaryXML){
156    $PdbAcc   = $this->ncbi->GetSummaryItem("PdbAcc"  ,$summaryXML);
157    $PdbClass = $this->ncbi->GetSummaryItem("PdbClass",$summaryXML);
158    $PdbDescr = $this->ncbi->GetSummaryItem("PdbDescr",$summaryXML);
159    $LigCode  = $this->ncbi->GetSummaryItem("LigCode" ,$summaryXML);
160
161    if (empty($PdbAcc)) return false;
162    $html ='<div class="pdb_plugin"><a href="'.$this->rcsb->ExplorerURL($pdbid).'">';
163    $html.='<span class="pdb_plugin_acc">'.$PdbAcc.'</span>';
164    $html.='&nbsp;-&nbsp;'.$PdbClass.'</a>';
165    if ($type=='long'){
166        $html.='<div class="pdb_plugin_text">'.$PdbDescr.'</div>';
167        if (!empty($LigCode)){
168          $html.='<div class="pdb_plugin_ligand">';
169          $ss = (strpos("|",$LigCode)===false)?
170            $this->getLang('pdb_ligand'):$this->getlang('pdb_ligands');
171          $html.=$ss.$LigCode.'</div>';
172        }
173    }
174    $html.='</div>'.NL;
175    return $html;
176  }
177
178 /**
179  * Get summary XML from cache or NCBI
180  */
181  function getSummaryXml($pdbAcc){
182    global $conf;
183    $cachedXml = $this->xmlCache->GetMediaText($pdbAcc);
184    if ($cachedXml!==false){ return $cachedXml; }
185
186    // convert PDB ID to Structure ID
187    $eSearchXml = $this->ncbi->SearchXml('structure',$pdbAcc);
188    $ids = $this->ncbi->GetSearchItems("Id",$eSearchXml);
189    $id=0;
190    for ($i=0;$i<count($ids);$i++){
191        $tmpXml   = $this->ncbi->SummaryXML('structure',$ids[$i]);
192        $tmpPdbId = $this->ncbi->GetSummaryItem("PdbAcc",$tmpXml);
193        if (strtolower($pdbAcc)==strtolower($tmpPdbId)){
194            $id = $ids[$i];
195        }
196    }
197    if ($id==0) return NULL;
198
199    // Get summary XML
200    $summary = $this->ncbi->SummaryXml('structure',$id);
201
202    if (!empty($summary)){
203      $cachePath = $this->xmlCache->GetMediaPath($pdbAcc);
204      if(io_saveFile($cachePath,$summary)){
205        chmod($cachePath,$conf['fmode']);
206      }
207    }
208    return $summary;
209  }
210  /*
211   * Convert PDB ID to Structure ID
212  */
213  function PDBtoStructureID($pdbAcc){
214
215      $xml = $this->SearchXml('structure',$pdbAcc);
216      $ids = $this->GetSearchItems("Id",$xml);
217      for ($i=0;$i<count($ids);$i++){
218          $tmpXml   = $this->SummaryXML('structure',$ids[$i]);
219          $tmpPdbId = $this->GetSummaryItem("PdbAcc",$tmpXml);
220          if (strtolower($pdbAcc)==strtolower($tmpPdbId)){
221              return $ids[$i];
222          }
223      }
224      return 0;
225  }
226}
227?>
228