5871d4a58e14bbf28534e9987ec4c758ca5aff25
[jalviewjs.git] / site / php / jsmol.php
1 <?php\r
2 \r
3 // jsmol.php\r
4 // Bob Hanson hansonr@stolaf.edu 1/11/2013\r
5 //\r
6 // 23 Mar 2015 -- checking for missing :// in queries\r
7 // 2 Feb 2014 -- stripped of any exec calls and image options-- this was for JSmol image option - abandoned\r
8 // 30 Oct 2013 -- saveFile should not convert " to _\r
9 // 30 Sep 2013 -- adjusted error handling to only report E_ERROR not E_WARNING\r
10 // 7 Sep 2013 -- adding PHP error handling\r
11 //\r
12 //////// note to administrators:\r
13 //\r
14 // from http://us3.php.net/file_get_contents: \r
15 //\r
16 // A URL can be used as a filename with this function if the fopen wrappers \r
17 // have been enabled. See fopen() for more details on how to specify the \r
18 // filename. See the Supported Protocols and Wrappers for links to information \r
19 // about what abilities the various wrappers have, notes on their usage, and \r
20 // information on any predefined variables they may provide.\r
21 ///////\r
22 //\r
23 // Server-side Jmol delivers:\r
24 //   simple relay for cross-domain files\r
25 //\r
26 //   options:\r
27 //\r
28 //   call\r
29 //         "saveFile"\r
30 //             returns posted data in "data=" with mime type "mimetype=" to file name "filename="\r
31 //         "getInfoFromDatabase" \r
32 //             returns XML data\r
33 //             requires database="=" (RCSB REST service)\r
34 //         "getRawDataFromDatabase"\r
35 //               "_" \r
36 //                  just use $query\r
37 //               (anything else)\r
38 //                  use $database.$query\r
39 //\r
40 //   encoding\r
41 //         ""        no encoding (default)\r
42 //         "base64"  BASE64-encoded binary files for Chrome synchronous AJAX\r
43 //                      prepends ";base64," to encoded output  \r
44 //\r
45 // simple server tests:\r
46 //\r
47 // http://foo.wherever/jsmol.php?call=getRawDataFromDatabase&database=_&query=http://chemapps.stolaf.edu/jmol/data/t.pdb.gz\r
48 // http://goo.wherever/jsmol.php?call=getRawDataFromDatabase&database=_&query=http://chemapps.stolaf.edu/jmol/data/t.pdb.gz&encoding=base64\r
49 \r
50 \r
51 $myerror = "";\r
52 \r
53 function handleError($severity, $msg, $filename, $linenum) {\r
54   global $myerror;\r
55   switch($severity) {\r
56   case E_ERROR:\r
57     $myerror = "PHP error:$severity $msg $filename $linenum";\r
58     break;\r
59   }\r
60   return true;\r
61 }\r
62 \r
63 set_error_handler("handleError");\r
64 \r
65 function getValueSimple($json, $key, $default) {\r
66  if ($json == "") {\r
67         $val = $_REQUEST[$key];\r
68  } else {\r
69  // just do a crude check for "key"..."value"  -- nothing more than that;\r
70  // only for very simple key/value pairs; mostly because we don't have the JSON\r
71  // module set up for our server.\r
72 \r
73         list($junk,$info) = explode('"'.$key.'"', $json, 2);\r
74         list($junk,$val) = explode('"', $info, 3);\r
75         if ($val == "") {\r
76                 $val = str_replace('"','_',$_REQUEST[$key]);\r
77         }\r
78  }\r
79  if ($val == "") {\r
80    $val = $default;\r
81  }\r
82  return $val;\r
83 }\r
84 \r
85 if ($_GET['isform']=="true") {\r
86         $values = "";\r
87 } else {\r
88         $values= file_get_contents("php://input");\r
89 }\r
90 $encoding = getValueSimple($values, "encoding", "");\r
91 $call = getValueSimple($values, "call", "getRawDataFromDatabase");\r
92 $query = getValueSimple($values, "query", "http://cactus.nci.nih.gov/chemical/structure/ethanol/file?format=sdf&get3d=True");\r
93 $database = getValueSimple($values, "database", "_");\r
94 \r
95 $imagedata = "";\r
96 $contentType = "";\r
97 $output = "";\r
98 $isBinary = false;\r
99 $filename = "";\r
100 \r
101 if ($call == "getInfoFromDatabase") {\r
102   // TODO: add PDBe annotation business here\r
103         if ($database == '=') {\r
104                 $restQueryUrl = "http://www.pdb.org/pdb/rest/search";\r
105                 $restReportUrl = "http://www.pdb.org/pdb/rest/customReport";\r
106                 $xml = "<orgPdbQuery><queryType>org.pdb.query.simple.AdvancedKeywordQuery</queryType><description>Text Search</description><keywords>$query</keywords></orgPdbQuery>";\r
107                 $context = stream_context_create(array('http' => array(\r
108                         'method' => 'POST',\r
109                         'header' => 'Content-Type: application/x-www-form-urlencoded',\r
110                         'content' => $xml))\r
111                 );\r
112                 $output = file_get_contents($restQueryUrl, false, $context);\r
113                 $n = strlen($output)/5;\r
114                 if ($n == 0) {\r
115                         $output = "ERROR: \"$query\" not found";\r
116                 } else {\r
117                         if (strlen($query) == 4 && $n != 1) {\r
118                                 $QQQQ = strtoupper($query);\r
119                                 if (strpos("123456789", substr($QQQQ, 0, 1)) == 0 && strpos($output, $QQQQ) > 0) {\r
120                                         $output = "$QQQQ\n".$output.str_replace("$QQQQ\n", "",$output);\r
121                                 }                 \r
122                         }\r
123                         if ($n > 50) {\r
124                                 $output = substr($output, 0, 250);\r
125                         }\r
126                         $output = str_replace("\n",",",$output);\r
127                         //http://www.rcsb.org/pdb/rest/customReport?pdbids=1crn,1d66,1blu,&customReportColumns=structureId,structureTitle\r
128                         $output = $restReportUrl."?pdbids=".$output."&customReportColumns=structureId,structureTitle";\r
129                         $output = "<result query=\"$query\" count=\"$n\">".file_get_contents($output)."</result>";\r
130                 }\r
131         } else {\r
132           $myerror = "jsmol.php cannot use $call with $database";\r
133         }\r
134         \r
135 } else if ($call == "getRawDataFromDatabase") {\r
136         $isBinary = (strpos(".gz", $query) >= 0);\r
137                 if ($database != "_")\r
138                         $query = $database.$query;\r
139                 if (strpos($query, '://') == 0) {\r
140       $output = "";\r
141     } else if (strpos($query, '?POST?') > 0) {\r
142                         list($query,$data) = explode('?POST?', $query, 2);\r
143                         $context = stream_context_create(array('http' => array(\r
144                                 'method' => 'POST',\r
145                                 'header' => 'Content-Type: application/x-www-form-urlencoded',\r
146                                 'content' => $data))\r
147                         );\r
148                         $output = file_get_contents($query, false, $context);\r
149                 } else {\r
150                         $output = file_get_contents($query);\r
151                 }\r
152 } else if ($call == "saveFile") {\r
153         $imagedata = $_REQUEST["data"];//getValueSimple($values, "data", ""); don't want to convert " to _ here\r
154         $filename = getValueSimple($values, "filename", "");\r
155         $contentType = getValueSimple($values, "mimetype", "application/octet-stream");\r
156         if ($encoding == "base64") {\r
157                 $imagedata = base64_decode($imagedata);\r
158                 $encoding = "";\r
159         }\r
160 } else {\r
161         $myerror = "jsmol.php unrecognized call: $call";\r
162 }\r
163 \r
164 ob_start();\r
165 \r
166  if ($myerror != "") {\r
167    $output = $myerror;\r
168  } else { \r
169    if ($imagedata != "") {\r
170         $output = $imagedata;\r
171         header('Content-Type: '.$contentType);\r
172         if ($filename != "") {\r
173           header('Content-Description: File Transfer');\r
174                 header("Content-Disposition: attachment; filename=\"$filename\"");\r
175       header('Content-Transfer-Encoding: binary');\r
176       header('Expires: 0');\r
177       header('Cache-Control: must-revalidate');\r
178       header('Pragma: public');\r
179         }\r
180    } else {\r
181         header('Access-Control-Allow-Origin: *');\r
182         if ($isBinary) {\r
183                 header('Content-Type: text/plain; charset=x-user-defined');\r
184         } else {\r
185                 header('Content-Type: application/json');\r
186         }\r
187    }\r
188    if ($encoding == "base64") {\r
189          $output = ";base64,".base64_encode($output);\r
190    }\r
191  } \r
192  header('Last-Modified: '.date('r'));\r
193  header('Accept-Ranges: bytes');\r
194  header('Content-Length: '.strlen($output));\r
195  print($output);\r
196 ob_end_flush();\r
197 ?>\r
198 \r