Exemplo n.º 1
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;
 }
Exemplo n.º 2
0
 /**
  * Generate a URL from ourself given a set of keyword arguments
  *
  * @param  array  $kargs   Keyword arguments
  * @param  null|string     Null if generation failed, URL otherwise
  */
 public function generate($kargs)
 {
     $defaultKargs = array('_ignoreReqList' => false, '_appendSlash' => false);
     $kargs = array_merge($defaultKargs, $kargs);
     $_appendSlash = $kargs['_appendSlash'];
     unset($kargs['_appendSlash']);
     $_ignoreReqList = $kargs['_ignoreReqList'];
     unset($kargs['_ignoreReqList']);
     // Verify that our args pass any regexp requirements
     if (!$_ignoreReqList) {
         foreach ($this->reqs as $key => $v) {
             $value = isset($kargs[$key]) ? $kargs[$key] : null;
             if (!empty($value) && !preg_match($this->_reqRegs[$key], $value)) {
                 return null;
             }
         }
     }
     // Verify that if we have a method arg, it's in the method accept list.
     // Also, method will be changed to _method for route generation.
     $meth = isset($kargs['method']) ? $kargs['method'] : null;
     if ($meth) {
         if ($this->conditions && isset($this->conditions['method']) && !in_array(Horde_String::upper($meth), $this->conditions['method'])) {
             return null;
         }
         unset($kargs['method']);
     }
     $routeList = $this->_routeBackwards;
     $urlList = array();
     $gaps = false;
     foreach ($routeList as $part) {
         if (is_array($part) && $part['type'] == ':') {
             $arg = $part['name'];
             // For efficiency, check these just once
             $hasArg = array_key_exists($arg, $kargs);
             $hasDefault = array_key_exists($arg, $this->defaults);
             // Determine if we can leave this part off
             // First check if the default exists and wasn't provided in the
             // call (also no gaps)
             if ($hasDefault && !$hasArg && !$gaps) {
                 continue;
             }
             // Now check to see if there's a default and it matches the
             // incoming call arg
             if ($hasDefault && $hasArg && $kargs[$arg] == $this->defaults[$arg] && !$gaps) {
                 continue;
             }
             // We need to pull the value to append, if the arg is NULL and
             // we have a default, use that
             if ($hasArg && $kargs[$arg] === null && $hasDefault && !$gaps) {
                 continue;
                 // Otherwise if we do have an arg, use that
             } elseif ($hasArg) {
                 $val = $kargs[$arg] === null ? 'null' : $kargs[$arg];
             } elseif ($hasDefault && $this->defaults[$arg] != null) {
                 $val = $this->defaults[$arg];
                 // No arg at all? This won't work
             } else {
                 return null;
             }
             $urlList[] = Horde_Routes_Utils::urlQuote($val, $this->encoding);
             if ($hasArg) {
                 unset($kargs[$arg]);
             }
             $gaps = true;
         } elseif (is_array($part) && $part['type'] == '*') {
             $arg = $part['name'];
             $kar = isset($kargs[$arg]) ? $kargs[$arg] : null;
             if ($kar != null) {
                 $urlList[] = Horde_Routes_Utils::urlQuote($kar, $this->encoding);
                 $gaps = true;
             }
         } elseif (!empty($part) && in_array(substr($part, -1), $this->_splitChars)) {
             if (!$gaps && in_array($part, $this->_splitChars)) {
                 continue;
             } elseif (!$gaps) {
                 $gaps = true;
                 $urlList[] = substr($part, 0, -1);
             } else {
                 $gaps = true;
                 $urlList[] = $part;
             }
         } else {
             $gaps = true;
             $urlList[] = $part;
         }
     }
     $urlList = array_reverse($urlList);
     $url = implode('', $urlList);
     if (substr($url, 0, 1) != '/') {
         $url = '/' . $url;
     }
     $extras = $kargs;
     foreach ($this->maxKeys as $key) {
         unset($extras[$key]);
     }
     $extras = array_keys($extras);
     if (!empty($extras)) {
         if ($_appendSlash && substr($url, -1) != '/') {
             $url .= '/';
         }
         $url .= '?';
         $newExtras = array();
         foreach ($kargs as $key => $value) {
             if (in_array($key, $extras) && ($key != 'action' || $key != 'controller')) {
                 $newExtras[$key] = $value;
             }
         }
         $url .= http_build_query($newExtras);
     } elseif ($_appendSlash && substr($url, -1) != '/') {
         $url .= '/';
     }
     return $url;
 }
Exemplo n.º 3
0
 public function testControllerScan()
 {
     $hereDir = __DIR__;
     $controllerDir = "{$hereDir}/fixtures/controllers";
     $controllers = Horde_Routes_Utils::controllerScan($controllerDir);
     $this->assertEquals(3, count($controllers));
     $this->assertEquals('admin/users', $controllers[0]);
     $this->assertEquals('content', $controllers[1]);
     $this->assertEquals('users', $controllers[2]);
 }