Beispiel #1
0
 /**
  * Match a url to our regexp.
  *
  * While the regexp might match, this operation isn't
  * guaranteed as there's other factors that can cause a match to fail
  * even though the regexp succeeds (Default that was relied on wasn't
  * given, requirement regexp doesn't pass, etc.).
  *
  * Therefore the calling function shouldn't assume this will return a
  * valid dict, the other possible return is False if a match doesn't work
  * out.
  *
  * @param  string  $url  URL to match
  * @param  array         Keyword arguments
  * @return null|array    Array of match data if matched, Null otherwise
  */
 public function match($url, $kargs = array())
 {
     $defaultKargs = array('environ' => array(), 'subDomains' => false, 'subDomainsIgnore' => array(), 'domainMatch' => '');
     $kargs = array_merge($defaultKargs, $kargs);
     // Static routes don't match, they generate only
     if ($this->static) {
         return false;
     }
     if (substr($url, -1) == '/' && strlen($url) > 1) {
         $url = substr($url, 0, -1);
     }
     // Match the regexps we generated
     $match = preg_match('@' . str_replace('@', '\\@', $this->regexp) . '@', $url, $matches);
     if ($match == 0) {
         return false;
     }
     $host = isset($kargs['environ']['HTTP_HOST']) ? $kargs['environ']['HTTP_HOST'] : null;
     if ($host !== null && !empty($kargs['subDomains'])) {
         $host = substr($host, 0, strpos(':', $host));
         $subMatch = '@^(.+?)\\.' . $kargs['domainMatch'] . '$';
         $subdomain = preg_replace($subMatch, '$1', $host);
         if (!in_array($subdomain, $kargs['subDomainsIgnore']) && $host != $subdomain) {
             $subDomain = $subdomain;
         }
     }
     if (!empty($this->conditions)) {
         if (isset($this->conditions['method'])) {
             if (empty($kargs['environ']['REQUEST_METHOD'])) {
                 return false;
             }
             if (!in_array($kargs['environ']['REQUEST_METHOD'], $this->conditions['method'])) {
                 return false;
             }
         }
         // Check sub-domains?
         $use_sd = isset($this->conditions['subDomain']) ? $this->conditions['subDomain'] : null;
         if (!empty($use_sd) && empty($subDomain)) {
             return false;
         }
         if (is_array($use_sd) && !in_array($subDomain, $use_sd)) {
             return false;
         }
     }
     $matchDict = $matches;
     // Clear out int keys as PHP gives us both the named subgroups and numbered subgroups
     foreach ($matchDict as $key => $val) {
         if (is_int($key)) {
             unset($matchDict[$key]);
         }
     }
     $result = array();
     $extras = Horde_Routes_Utils::arraySubtract(array_keys($this->defaults), array_keys($matchDict));
     foreach ($matchDict as $key => $val) {
         // TODO: character set decoding
         if ($key != 'path_info' && $this->encoding) {
             $val = urldecode($val);
         }
         if (empty($val) && array_key_exists($key, $this->defaults) && !empty($this->defaults[$key])) {
             $result[$key] = $this->defaults[$key];
         } else {
             $result[$key] = $val;
         }
     }
     foreach ($extras as $key) {
         $result[$key] = $this->defaults[$key];
     }
     // Add the sub-domain if there is one
     if (!empty($kargs['subDomains'])) {
         $result['subDomain'] = $subDomain;
     }
     // If there's a function, call it with environ and expire if it
     // returns False
     if (!empty($this->conditions) && array_key_exists('function', $this->conditions) && !call_user_func_array($this->conditions['function'], array($kargs['environ'], $result))) {
         return false;
     }
     return $result;
 }
Beispiel #2
0
 /**
  * Generates the URL from a given set of keywords
  * Returns the URL text, or null if no URL could be generated.
  *
  * Usage:
  *   $m->generate(array('controller' => 'content', 'action' => 'view', 'id' => 10));
  *
  * @param   array        $routeArgs  Optional explicit route list
  * @param   array        $kargs      Keyword arguments (key/value pairs)
  * @return  null|string              URL text or null
  */
 public function generate($first = null, $second = null)
 {
     if ($second) {
         $routeArgs = $first;
         $kargs = is_null($second) ? array() : $second;
     } else {
         $routeArgs = array();
         $kargs = is_null($first) ? array() : $first;
     }
     // Generate ourself if we haven't already
     if (!$this->_createdGens) {
         $this->_createGens();
     }
     if ($this->appendSlash) {
         $kargs['_appendSlash'] = true;
     }
     if (!$this->explicit) {
         if (!in_array('controller', array_keys($kargs))) {
             $kargs['controller'] = 'content';
         }
         if (!in_array('action', array_keys($kargs))) {
             $kargs['action'] = 'index';
         }
     }
     $environ = $this->environ;
     $controller = isset($kargs['controller']) ? $kargs['controller'] : null;
     $action = isset($kargs['action']) ? $kargs['action'] : null;
     // If the URL didn't depend on the SCRIPT_NAME, we'll cache it
     // keyed by just the $kargs; otherwise we need to cache it with
     // both SCRIPT_NAME and $kargs:
     $cacheKey = $kargs;
     if (!empty($environ['SCRIPT_NAME'])) {
         $cacheKeyScriptName = sprintf('%s:%s', $environ['SCRIPT_NAME'], $cacheKey);
     } else {
         $cacheKeyScriptName = $cacheKey;
     }
     // Check the URL cache to see if it exists, use it if it does.
     foreach (array($cacheKey, $cacheKeyScriptName) as $key) {
         if (in_array($key, array_keys($this->urlCache))) {
             return $this->urlCache[$key];
         }
     }
     if ($routeArgs) {
         $keyList = $routeArgs;
     } else {
         $actionList = isset($this->_gendict[$controller]) ? $this->_gendict[$controller] : $this->_gendict['*'];
         list($keyList, $sortCache) = isset($actionList[$action]) ? $actionList[$action] : (isset($actionList['*']) ? $actionList['*'] : array(null, null));
         if ($keyList === null) {
             return null;
         }
     }
     $keys = array_keys($kargs);
     // necessary to pass $keys to _keysort() callback used by PHP's usort()
     $this->_keysortTmp = $keys;
     $newList = array();
     foreach ($keyList as $route) {
         $tmp = Horde_Routes_Utils::arraySubtract($route->minKeys, $keys);
         if (count($tmp) == 0) {
             $newList[] = $route;
         }
     }
     $keyList = $newList;
     // inline python function keysort() moved below as _keycmp()
     $this->_keysort($keyList);
     foreach ($keyList as $route) {
         $fail = false;
         foreach ($route->hardCoded as $key) {
             $kval = isset($kargs[$key]) ? $kargs[$key] : null;
             if ($kval == null) {
                 continue;
             }
             if ($kval != $route->defaults[$key]) {
                 $fail = true;
                 break;
             }
         }
         if ($fail) {
             continue;
         }
         $path = $route->generate($kargs);
         if ($path) {
             if ($this->prefix) {
                 $path = $this->prefix . $path;
             }
             if (!empty($environ['SCRIPT_NAME']) && !$route->absolute) {
                 $path = $environ['SCRIPT_NAME'] . $path;
                 $key = $cacheKeyScriptName;
             } else {
                 $key = $cacheKey;
             }
             if ($this->urlCache != null) {
                 $this->urlCache[$key] = $path;
             }
             return $path;
         } else {
             continue;
         }
     }
     return null;
 }