dmBridge PHP API
DMInternalURI.php
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", "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       $tmp1 = $this->getParamComponents();
00334 
00335       $dxp = new DOMXPath(self::getRoutesXML());
00336       $result = $dxp->query("//route/@path");
00337 
00338       // look for built-in routes
00339       foreach ($result as $route) {
00340          $tmp2 = explode("/", $route->value);
00341 
00342          $count1 = count($tmp1);
00343          $count2 = count($tmp2);
00344          if ($count1 == $count2) {
00345             for ($i = 0; $i < $count1; $i++) {
00346                if ($i + 1 == $count1) { // match
00347                   $r = self::getRouteMatchingParamsFromRoutesFile(
00348                         $this->getParams());
00349                   if ($r) {
00350                      return $r;
00351                   }
00352                }
00353             }
00354          }
00355       }
00356       return $this->getModuleRoute();
00357    }
00358 
00364    public function setString($str) {
00365       $tmp = parse_url($str);
00366 
00367       if (!is_array($tmp)) {
00368          throw new DMIllegalArgumentException(
00369                DMLocalizedString::getString("INVALID_URL"));
00370       }
00371 
00372       if (array_key_exists("scheme", $tmp)) {
00373          $this->setScheme($tmp['scheme']);
00374       }
00375       if (array_key_exists("host", $tmp)) {
00376          $this->setHost($tmp['host']);
00377       }
00378       if (array_key_exists("port", $tmp)) {
00379          $this->setPort($tmp['port']);
00380       }
00381       if (array_key_exists("user", $tmp)) {
00382          $this->setUser($tmp['user']);
00383       }
00384       if (array_key_exists("pass", $tmp)) {
00385          $this->setPassword($tmp['pass']);
00386       }
00387       if (array_key_exists("path", $tmp)) {
00388          $tmp2 = explode(".", $tmp['path']);
00389          $last_part = $tmp2[count($tmp2)-1];
00390          if (in_array($last_part, self::getAllowedExtensions())) {
00391             $this->setExtension(array_pop($tmp2));
00392             $path = implode(".", $tmp2);
00393             $this->setPath($path);
00394          } else {
00395             $this->setPath($tmp['path']);
00396          }
00397       }
00398       $this->unsetQuery();
00399       if (array_key_exists("query", $tmp)) {
00400          $q = explode("&", $tmp['query']);
00401          foreach ($q as $kv) {
00402             $parts = explode("=", $kv);
00403             if (count($parts) == 2) {
00404                $this->addQueryValue(
00405                      urldecode($parts[0]), urldecode($parts[1]));
00406             }
00407          }
00408       }
00409       if (array_key_exists("fragment", $tmp)) {
00410          $this->setFragment($tmp['fragment']);
00411       }
00412    }
00413 
00417    public function isTemplateEngine() {
00418       $components = $this->getParamComponents();
00419       return (bool) count($components) && $components[0] == "objects";
00420    }
00421 
00428    public function getVersion() {
00429       $parts = $this->getParamComponents();
00430       if (count($parts) > 1 && is_numeric($parts[1])) {
00431          return $parts[1];
00432       }
00433       return null;
00434    }
00435 
00436 }
 All Data Structures Functions Variables