|
dmBridge PHP API
|
00001 <?php 00002 # 00003 # dmBridge: a data access framework for CONTENTdm(R) 00004 # 00005 # Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher 00006 # Education, on behalf of the University of Nevada, Las Vegas 00007 # 00008 00024 class DMInternalURI extends DMURI { 00025 00030 private static $routes_xml; 00031 00035 private $extension; 00036 00040 private static function getAllowedExtensions() { 00041 return array_merge(DMMediaType::getKnownExtensions(), 00042 array("xml", "json", "jsonp", "atom", "html", "sitemap")); 00043 } 00044 00049 private static function getPathMinusExtension($path) { 00050 $tmp = explode(".", $path); 00051 if (count($tmp) > 1) { 00052 $ext = $tmp[count($tmp) - 1]; 00053 if (in_array($ext, DMMediaType::getKnownExtensions())) { 00054 array_pop($tmp); 00055 return implode(".", $tmp); 00056 } 00057 } 00058 return $path; 00059 } 00060 00071 public static function getResourceURI($component, 00072 $params, $representation = null) { 00073 $prefix = ""; 00074 switch ($component) { 00075 case DMBridgeComponent::HTTPAPI: 00076 $prefix = "api/1/"; 00077 break; 00078 default: 00079 break; 00080 } 00081 00082 return self::getURIWithParams($prefix . $params, array(), 00083 $representation == "html" ? null : $representation); 00084 } 00085 00092 private static function getRouteMatchingParamsFromRoutesFile( 00093 $params, $path = null) { 00094 // parse routes XML 00095 if ($path == null) { 00096 $routes_xml = self::getRoutesXML(); 00097 } else { 00098 if (file_exists($path)) { 00099 $routes_xml = new DOMDocument("1.0", "utf-8"); 00100 $routes_xml->load($path); 00101 } else { 00102 return null; 00103 } 00104 } 00105 00106 // parse the URI 00107 $uri_parts = explode("/", $params); 00108 $uri_count = count($uri_parts); 00109 00110 $version = 1; // default resource version; may be overridden below 00111 $xml_route_parts = array(); 00112 $props = array( 00113 'ctrlr' => null, 00114 'method' => null, 00115 'parameters' => null 00116 ); 00117 $representations = array(); 00118 foreach ($routes_xml->getElementsByTagName("route") as $xml_route) { 00119 $xml_route_parts = explode("/", $xml_route->getAttribute("path")); 00120 $xml_route_count = count($xml_route_parts); 00121 if ($uri_count != $xml_route_count) { // not a match 00122 continue; 00123 } 00124 $parameters = array(); 00125 for ($i = 0; $i < $uri_count; $i++) { 00126 if ($xml_route_parts[$i] != $uri_parts[$i] 00127 && strpos($xml_route_parts[$i], ":") !== 0) { 00128 break; // not a match 00129 } 00130 if (strpos($xml_route_parts[$i], ":") === 0) { 00131 $parameters[] = $uri_parts[$i]; 00132 if ($xml_route_parts[$i] == ":int") { 00133 if ((string) $uri_parts[$i] != (string) round($uri_parts[$i])) { 00134 break; // not a match 00135 } 00136 } 00137 } 00138 00139 if ($i == $uri_count - 1) { // successful match 00140 $invocation = $xml_route 00141 ->getElementsByTagName("invocation")->item(0); 00142 $props['ctrlr'] = $invocation 00143 ->getElementsByTagName("class")->item(0)->nodeValue; 00144 $props['method'] = $invocation 00145 ->getElementsByTagName("method")->item(0)->nodeValue; 00146 $props['parameters'] = implode(",", $parameters); 00147 $xml_representations = $xml_route 00148 ->getElementsByTagName("representations")->item(0); 00149 foreach ($xml_representations->getElementsByTagName( 00150 "representation") as $rep) { 00151 $representations[$rep->getAttribute("ext")] 00152 = DMMediaType::getTypeForString($rep->nodeValue); 00153 } 00154 $version = (int) $xml_route 00155 ->getElementsByTagName("resourceVersion")->item(0) 00156 ->nodeValue; 00157 break(2); 00158 } 00159 } 00160 } 00161 00162 if ($props['ctrlr'] && $props['method']) { 00163 $route = new DMRoute($props['ctrlr'], $props['method']); 00164 if ($props['parameters']) { 00165 $route->setParameters($props['parameters']); 00166 } 00167 $route->setAvailableRepresentations($representations); 00168 00169 return $route; 00170 } 00171 return null; 00172 } 00173 00177 private static function getRoutesXML() { 00178 if (!self::$routes_xml) { 00179 $path = dirname(__FILE__) . "/../../includes/routes.xml"; 00180 self::$routes_xml = new DOMDocument("1.0", "utf-8"); 00181 self::$routes_xml->load($path); 00182 } 00183 return self::$routes_xml; 00184 } 00185 00196 public static function getURIWithParams($params, array $query = array(), 00197 $representation = null) { 00198 $path = DMConfigIni::getInstance()->getString("dmbridge.base_uri_path"); 00199 $uri = clone DMHTTPRequest::getCurrent()->getURI(); 00200 $uri->unsetQuery(); 00201 $uri->setPath($path); 00202 $uri->setParams($params); 00203 $uri->setExtension($representation); 00204 00205 if (array_key_exists("r", $query) && !$params) { 00206 $uri->setParams($query['r']); 00207 } 00208 00209 foreach ($query as $k => $v) { 00210 $uri->addQueryValue($k, $v); 00211 } 00212 return $uri; 00213 } 00214 00220 public function getAbsoluteURIAsString() { 00221 if (!$this->getScheme() || !$this->getHost()) { 00222 return null; 00223 } 00224 00225 $clone = clone $this; 00226 $uri = $clone->getScheme() . "://"; 00227 if ($clone->getUser()) { 00228 $uri .= $clone->getUser(); 00229 } 00230 if ($clone->getPassword()) { 00231 $uri .= ":" . $clone->getPassword(); 00232 } 00233 if ($clone->getUser() || $clone->getPassword()) { 00234 $uri .= "@"; 00235 } 00236 $uri .= $clone->getHost(); 00237 if ($clone->getPort() != 80) { 00238 $uri .= ":" . $clone->getPort(); 00239 } 00240 $uri .= $clone->getPath(); 00241 if ($clone->getExtension() && !($clone->isTemplateEngine() 00242 && $clone->getExtension() == "html")) { 00243 $uri .= "." . $clone->getExtension(); 00244 } 00245 $clone->unsetQueryKey("r"); 00246 if (count($clone->getQuery())) { 00247 $uri .= "?" . $clone->getQueryString(); 00248 } 00249 if ($clone->getFragment()) { 00250 $uri .= "#" . $clone->getFragment(); 00251 } 00252 return $uri; 00253 } 00254 00258 public function isControlPanel() { 00259 $components = $this->getParamComponents(); 00260 return (bool) count($components) && $components[0] == "admin"; 00261 } 00262 00266 public function getExtension() { 00267 return $this->extension; 00268 } 00269 00273 public function setExtension($ext) { 00274 $this->extension = $ext; 00275 } 00276 00280 public function isHTTPAPI() { 00281 $components = $this->getParamComponents(); 00282 return (bool) count($components) && $components[0] == "api"; 00283 } 00284 00288 private function getModuleRoute() { 00289 $mm = DMModuleManager::getInstance(); 00290 foreach ($mm->getEnabledModules() as $module) { 00291 $route = self::getRouteMatchingParamsFromRoutesFile( 00292 $this->getParams(), 00293 $module->getAbsolutePathname() . "/routes.xml"); 00294 if ($route) { 00295 $route->setModuleRoute(true); 00296 return $route; 00297 } 00298 } 00299 return null; 00300 } 00301 00306 public function getParams() { 00307 $path = DMConfigIni::getInstance()->getString("dmbridge.base_uri_path"); 00308 return trim(str_replace($path, "", 00309 self::getPathMinusExtension($this->getPath())), "/"); 00310 } 00311 00315 public function setParams($params) { 00316 $path = DMConfigIni::getInstance()->getString("dmbridge.base_uri_path"); 00317 $this->setPath($path . "/" . $params); 00318 } 00319 00324 public function getParamComponents() { 00325 return explode("/", $this->getParams()); 00326 } 00327 00332 public function getRoute() { 00333 $r = $this->getModuleRoute(); 00334 if ($r) { 00335 return $r; 00336 } 00337 00338 $tmp1 = $this->getParamComponents(); 00339 00340 $dxp = new DOMXPath(self::getRoutesXML()); 00341 $result = $dxp->query("//route/@path"); 00342 00343 // look for built-in routes 00344 foreach ($result as $route) { 00345 $tmp2 = explode("/", $route->value); 00346 00347 $count1 = count($tmp1); 00348 $count2 = count($tmp2); 00349 if ($count1 == $count2) { 00350 for ($i = 0; $i < $count1; $i++) { 00351 if ($i + 1 == $count1) { // match 00352 $r = self::getRouteMatchingParamsFromRoutesFile( 00353 $this->getParams()); 00354 if ($r) { 00355 return $r; 00356 } 00357 } 00358 } 00359 } 00360 } 00361 } 00362 00368 public function setString($str) { 00369 $tmp = parse_url($str); 00370 00371 if (!is_array($tmp)) { 00372 throw new DMIllegalArgumentException( 00373 DMLocalizedString::getString("INVALID_URL")); 00374 } 00375 00376 if (array_key_exists("scheme", $tmp)) { 00377 $this->setScheme($tmp['scheme']); 00378 } 00379 if (array_key_exists("host", $tmp)) { 00380 $this->setHost($tmp['host']); 00381 } 00382 if (array_key_exists("port", $tmp)) { 00383 $this->setPort($tmp['port']); 00384 } 00385 if (array_key_exists("user", $tmp)) { 00386 $this->setUser($tmp['user']); 00387 } 00388 if (array_key_exists("pass", $tmp)) { 00389 $this->setPassword($tmp['pass']); 00390 } 00391 if (array_key_exists("path", $tmp)) { 00392 $tmp2 = explode(".", $tmp['path']); 00393 $last_part = $tmp2[count($tmp2)-1]; 00394 if (in_array($last_part, self::getAllowedExtensions())) { 00395 $this->setExtension(array_pop($tmp2)); 00396 $path = implode(".", $tmp2); 00397 $this->setPath($path); 00398 } else { 00399 $this->setPath($tmp['path']); 00400 } 00401 } 00402 $this->unsetQuery(); 00403 if (array_key_exists("query", $tmp)) { 00404 $q = explode("&", $tmp['query']); 00405 foreach ($q as $kv) { 00406 $parts = explode("=", $kv); 00407 if (count($parts) == 2) { 00408 $this->addQueryValue( 00409 urldecode($parts[0]), urldecode($parts[1])); 00410 } 00411 } 00412 } 00413 if (array_key_exists("fragment", $tmp)) { 00414 $this->setFragment($tmp['fragment']); 00415 } 00416 } 00417 00421 public function isTemplateEngine() { 00422 $components = $this->getParamComponents(); 00423 return (bool) count($components) && $components[0] == "objects"; 00424 } 00425 00432 public function getVersion() { 00433 $parts = $this->getParamComponents(); 00434 if (count($parts) > 1 && is_numeric($parts[1])) { 00435 return $parts[1]; 00436 } 00437 return null; 00438 } 00439 00440 }