Development

Changeset 11794

You must first sign up to be able to contribute.

Changeset 11794

Show
Ignore:
Timestamp:
09/26/08 11:05:48 (6 years ago)
Author:
fabien
Message:

[1.2] changed the way routes work, objects are not injected automatically anymore in the request attributes (closes #4395)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.2/UPGRADE_TO_1_2

    r11783 r11794  
    945945    $routing->connect('foo_bar', $route); 
    946946 
     947When a request comes in, the matching route object is stored as an attribute of the 
     948request and you can get it from an action via the `getRoute()` method: 
     949 
     950    [php] 
     951    public function executeIndex() 
     952    { 
     953      $route = $this->getRoute(); 
     954    } 
     955 
    947956The `sfRoute` constructor takes an array of options as its last argument to 
    948957allow the customization of each route. In the `routing.yml` configuration file, 
     
    10381047objects, related to the route. 
    10391048 
    1040 The object or the collection of objects will be available in your actions 
    1041 via a request attribute: 
    1042  
    10431049    [yml] 
    10441050    article: 
    10451051      url:     /article/:id 
    10461052      class:   sfObjectRoute 
    1047       options: { model: Article, object: article, method: getById } 
    1048  
    1049 When an incoming URL matches the route, the `sfObjectRoute` will get the 
    1050 related object by calling the `Article::getById()` method and will inject 
    1051 the result into the request attributes (under the `article` key)
     1053      options: { model: Article, type: object, method: getById } 
     1054 
     1055When an incoming URL matches the route, the `sfObjectRoute::getObject()` 
     1056method will get the related object by calling the `Article::getById()` 
     1057method
    10521058 
    10531059The same goes for a collection of objects: 
     
    10571063      url:     /articles/newest 
    10581064      class:   sfObjectRoute 
    1059       options: { model: Article, list: articles, method: getNewest } 
     1065      options: { model: Article, type: list, method: getNewest } 
    10601066 
    10611067`sfPropelRoute` extends `sfObjectRoute` to bind a route to a Propel model. 
     1068 
     1069In your actions, you can retrieve the related object or collection of objects 
     1070by using the `sfObjectRoute::getObject()` and `sfObjectRoute::getObjects()` 
     1071methods: 
     1072 
     1073    [php] 
     1074    public function executeList($request) 
     1075    { 
     1076      $this->articles = $this->getRoute()->getObjects(); 
     1077    } 
     1078 
     1079    public function executeShow($request) 
     1080    { 
     1081      $this->article = $this->getRoute()->getObject(); 
     1082    } 
    10621083 
    10631084Here is an example for an `Article` Propel object: 
     
    10681089      param:   { module: article, action: show } 
    10691090      class:   sfPropelRoute 
    1070       options: { model: Article, object: article
     1091      options: { model: Article, type: object
    10711092 
    10721093    articles: 
     
    10741095      param:   { module: article, action: list } 
    10751096      class:   sfPropelRoute 
    1076       options: { model: Article, list: articles, method: getPublishedArticleCriteria } 
     1097      options: { model: Article, type: list, method: getPublishedArticleCriteria } 
    10771098 
    10781099If you don't define a method, `sfPropelRoute` will retrieve the object 
    1079 by building a Criteria object based on the available route variables. 
     1100by building a `Criteria` object based on the available route variables. 
    10801101 
    10811102The `sfPropelRoute` has two main advantages over `sfRoute`: 
    10821103 
    1083   * When a request comes in and the route matches the URL, `sfPropelRoute` 
    1084     will automatically inject the related `Article` object with a name of `article`. 
     1104  * When a request comes in and the route matches the URL, the matching `sfPropelRoute` 
     1105    object will be available in your actions, and the related `Article` object 
     1106    will be available by calling the `getObject()` method. 
    10851107    Moreover, if the object does not exist in the database, it will automatically 
    10861108    redirect the user to a 404 error page. This means less boiler-plate code in 
     
    11201142      param:   { module: article, action: show } 
    11211143      class:   sfPropelRoute 
    1122       options: { model: Article, object: article
     1144      options: { model: Article, type: object
    11231145 
    11241146But sometimes, you want to put in the pattern some information that does not 
     
    11301152      param:   { module: article, action: show } 
    11311153      class:   sfPropelRoute 
    1132       options: { model: Article, object: article, method: getObjectForRoute } 
     1154      options: { model: Article, type: object, method: getObjectForRoute } 
    11331155 
    11341156The `getObjectForRoute()` receives an array of parameters as its first 
  • branches/1.2/lib/action/sfAction.class.php

    r11783 r11794  
    536536  } 
    537537 
     538  public function getRoute() 
     539  { 
     540    return $this->getRequest()->getAttribute('sf_route'); 
     541  } 
     542 
    538543  /** 
    539544   * Returns a formatted message for a 404 error. 
  • branches/1.2/lib/request/sfWebRequest.class.php

    r11784 r11794  
    830830  protected function fixParameters() 
    831831  { 
    832     // arguments that come from the routing 
    833     if ($this->getParameter('_arguments')) 
    834     { 
    835       $this->getAttributeHolder()->add($this->getParameter('_arguments')); 
    836       $this->getParameterHolder()->remove('_arguments'); 
    837     } 
    838  
    839832    // move symfony parameters to attributes (parameters prefixed with _sf_) 
    840833    foreach ($this->parameterHolder->getAll() as $key => $value) 
     
    843836      { 
    844837        $this->parameterHolder->remove($key); 
    845         $this->setAttribute($key, $value); 
     838        $this->setAttribute(substr($key, 1), $value); 
    846839      } 
    847840    } 
  • branches/1.2/lib/routing/sfObjectRoute.class.php

    r11600 r11794  
    3535    if (!isset($options['model'])) 
    3636    { 
    37       throw new InvalidArgumentException('You must pass a "model" option for a sfObjectRoute object.'); 
    38     } 
    39  
    40     if (!isset($options['object']) && !isset($options['list'])) 
    41     { 
    42       throw new InvalidArgumentException('You must pass an "object" or a "list" option for a sfObjectRoute object.'); 
    43     } 
     37      throw new InvalidArgumentException(sprintf('You must pass a "model" option for a sfObjectRoute object (%s).', $pattern)); 
     38    } 
     39 
     40    if (!isset($options['type'])) 
     41    { 
     42      throw new InvalidArgumentException(sprintf('You must pass a "type" option for a sfObjectRoute object (%s).', $pattern)); 
     43    } 
     44 
     45    if (!in_array($options['type'], array('object', 'list'))) 
     46    { 
     47      throw new InvalidArgumentException(sprintf('The "type" option can only be "object" or "list", "%s" given (%s).', $options['type'], $pattern)); 
     48      } 
    4449 
    4550    parent::__construct($pattern, $defaults, $requirements, $options); 
     
    4752 
    4853  /** 
    49    * Returns true if the URL matches this route, false otherwise. 
    50    * 
    51    * @param  string  $url     The URL 
    52    * @param  array   $context The context 
    53    * 
    54    * @return array   An array composed of an array of parameters and an array of extra parameters 
    55    */ 
    56   public function matchesUrl($url, $context = array()) 
    57   { 
    58     if (false === $parameters = parent::matchesUrl($url, $context)) 
    59     { 
    60       return false; 
    61     } 
    62  
    63     if (isset($this->options['object'])) 
    64     { 
    65       // check the related object 
    66       if (is_null($object = $this->getObjectForParameters($parameters[0])) && (!isset($this->options['allow_empty']) || !$this->options['allow_empty'])) 
    67       { 
    68         throw new sfError404Exception(sprintf('Unable to find the %s object with the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($parameters[0]), true)))); 
    69       } 
    70  
    71       return array($parameters[0], array_merge($parameters[1], array($this->options['object'] => false === $object ? null : $object))); 
    72     } 
    73     else 
    74     { 
    75       // object list 
    76       $objects = $this->getObjectsForParameters($parameters[0]); 
    77  
    78       if (is_array($objects) && !count($objects) && isset($this->options['allow_empty']) && !$this->options['allow_empty']) 
    79       { 
    80         throw new sfError404Exception(sprintf('No %s object found for the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($parameters[0]), true)))); 
    81       } 
    82  
    83       return array($parameters[0], array_merge($parameters[1], array($this->options['list'] => false === $objects ? array() : $objects))); 
    84     } 
    85   } 
    86  
    87   /** 
    8854   * Returns true if the parameters matches this route, false otherwise. 
    8955   * 
    90    * @param  mixed  $params The parameters 
     56   * @param  mixed  $params The parameters 
    9157   * @param  array  $context The context 
    9258   * 
     
    9561  public function matchesParameters($params, $context = array()) 
    9662  { 
    97     return parent::matchesParameters(isset($this->options['object']) ? $this->convertObjectToArray($params) : $params); 
     63    return parent::matchesParameters('object' == $this->options['type'] ? $this->convertObjectToArray($params) : $params); 
    9864  } 
    9965 
     
    10975  public function generate($params, $context = array(), $absolute = false) 
    11076  { 
    111     return parent::generate(isset($this->options['object']) ? $this->convertObjectToArray($params) : $params, $absolute); 
     77    return parent::generate('object' == $this->options['type'] ? $this->convertObjectToArray($params) : $params, $absolute); 
     78  } 
     79 
     80  /** 
     81   * Gets the object related to the current route and parameters. 
     82   * 
     83   * This method is only accessible if the route is bound and of type "object". 
     84   * 
     85   * @return Object The related object 
     86   */ 
     87  public function getObject() 
     88  { 
     89    if (!$this->isBound()) 
     90    { 
     91      throw new LogicException('The route is not bound.'); 
     92    } 
     93 
     94    if ('object' != $this->options['type']) 
     95    { 
     96      throw new LogicException('The route type must be "object".'); 
     97    } 
     98 
     99    // check the related object 
     100    if (is_null($object = $this->getObjectForParameters($this->parameters)) && (!isset($this->options['allow_empty']) || !$this->options['allow_empty'])) 
     101    { 
     102      throw new sfError404Exception(sprintf('Unable to find the %s object with the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($this->parameters), true)))); 
     103    } 
     104 
     105    return $object; 
     106  } 
     107 
     108  /** 
     109   * Gets the list of objects related to the current route and parameters. 
     110   * 
     111   * This method is only accessible if the route is bound and of type "list". 
     112   * 
     113   * @return array And array of related objects 
     114   */ 
     115  public function getObjects() 
     116  { 
     117    if (!$this->isBound()) 
     118    { 
     119      throw new LogicException('The route is not bound.'); 
     120    } 
     121 
     122    if ('list' != $this->options['type']) 
     123    { 
     124      throw new LogicException('The route type must be "list".'); 
     125    } 
     126 
     127    $objects = $this->getObjectsForParameters($this->parameters); 
     128 
     129    if (is_array($objects) && !count($objects) && isset($this->options['allow_empty']) && !$this->options['allow_empty']) 
     130    { 
     131      throw new sfError404Exception(sprintf('No %s object found for the following parameters "%s").', $this->options['model'], str_replace("\n", '', var_export($this->filterParameters($this->parameters), true)))); 
     132    } 
     133 
     134    return $objects; 
    112135  } 
    113136 
  • branches/1.2/lib/routing/sfObjectRouteCollection.class.php

    r11525 r11794  
    3737 
    3838    $this->options = array_merge(array( 
    39       'plural'         => $this->options['name'], 
    40       'singular'       => substr($this->options['name'], 0, -1), 
    41       'actions'        => false, 
    42       'module'         => $this->options['name'], 
    43       'prefix_path'    => '/'.$this->options['name'], 
    44       'column'         => 'id', 
    45       'with_show'      => true, 
    46       'segment_names'  => array('edit' => 'edit', 'new' => 'new'), 
    47       'model_methods'  => array(), 
     39      'actions'       => false, 
     40      'module'        => $this->options['name'], 
     41      'prefix_path'   => '/'.$this->options['name'], 
     42      'column'        => 'id', 
     43      'with_show'     => true, 
     44      'segment_names' => array('edit' => 'edit', 'new' => 'new'), 
     45      'model_methods' => array(), 
    4846    ), $this->options); 
    4947 
     
    8078      array('module' => $this->options['module'], 'action' => $this->getActionMethod('list'), 'sf_format' => 'html'), 
    8179      array_merge($this->options['requirements'], array('sf_method' => 'get')), 
    82       array('model' => $this->options['model'], 'list' => $this->options['plural'], 'method' => $this->options['model_methods']['list']) 
     80      array('model' => $this->options['model'], 'type' => 'list', 'method' => $this->options['model_methods']['list']) 
    8381    ); 
    8482  } 
     
    9088      array('module' => $this->options['module'], 'action' => $this->getActionMethod('new'), 'sf_format' => 'html'), 
    9189      array_merge($this->options['requirements'], array('sf_method' => 'get')), 
    92       array('model' => $this->options['model'], 'object' => $this->options['singular']
     90      array('model' => $this->options['model'], 'type' => 'object'
    9391    ); 
    9492  } 
     
    10098      array('module' => $this->options['module'], 'action' => $this->getActionMethod('create'), 'sf_format' => 'html'), 
    10199      array_merge($this->options['requirements'], array('sf_method' => 'post')), 
    102       array('model' => $this->options['model'], 'object' => $this->options['singular']
     100      array('model' => $this->options['model'], 'type' => 'object'
    103101    ); 
    104102  } 
     
    110108      array('module' => $this->options['module'], 'action' => $this->getActionMethod('show'), 'sf_format' => 'html'), 
    111109      array_merge($this->options['requirements'], array('sf_method' => 'get')), 
    112       array('model' => $this->options['model'], 'object' => $this->options['singular'], 'method' => $this->options['model_methods']['object']) 
     110      array('model' => $this->options['model'], 'type' => 'object', 'method' => $this->options['model_methods']['object']) 
    113111    ); 
    114112  } 
     
    120118      array('module' => $this->options['module'], 'action' => $this->getActionMethod('edit'), 'sf_format' => 'html'), 
    121119      array_merge($this->options['requirements'], array('sf_method' => 'get')), 
    122       array('model' => $this->options['model'], 'object' => $this->options['singular'], 'method' => $this->options['model_methods']['object']) 
     120      array('model' => $this->options['model'], 'type' => 'object', 'method' => $this->options['model_methods']['object']) 
    123121    ); 
    124122  } 
     
    130128      array('module' => $this->options['module'], 'action' => $this->getActionMethod('update'), 'sf_format' => 'html'), 
    131129      array_merge($this->options['requirements'], array('sf_method' => 'put')), 
    132       array('model' => $this->options['model'], 'object' => $this->options['singular'], 'method' => $this->options['model_methods']['object']) 
     130      array('model' => $this->options['model'], 'type' => 'object', 'method' => $this->options['model_methods']['object']) 
    133131    ); 
    134132  } 
     
    140138      array('module' => $this->options['module'], 'action' => $this->getActionMethod('delete'), 'sf_format' => 'html'), 
    141139      array('sf_method' => 'delete'), 
    142       array('model' => $this->options['model'], 'object' => $this->options['singular'], 'method' => $this->options['model_methods']['object']) 
     140      array('model' => $this->options['model'], 'type' => 'object', 'method' => $this->options['model_methods']['object']) 
    143141    ); 
    144142  } 
  • branches/1.2/lib/routing/sfPatternRouting.class.php

    r11765 r11794  
    350350    } 
    351351 
     352    if ($this->options['logging']) 
     353    { 
     354      $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Match route "%s" (%s) for %s with parameters %s', $info['name'], $info['pattern'], $url, str_replace("\n", '', var_export($info['parameters'], true)))))); 
     355    } 
     356 
     357    // store the current internal URI 
     358    $this->updateCurrentInternalUri($info['name'], $info['parameters']); 
     359 
     360    $route = $this->routes[$info['name']]; 
     361    $route->bind($this->options['context'], $info['parameters']); 
     362    $info['parameters']['_sf_route'] = $route; 
     363 
     364    return $info['parameters']; 
     365  } 
     366 
     367  protected function updateCurrentInternalUri($name, array $parameters) 
     368  { 
    352369    // store the route name 
    353     $this->currentRouteName   = $info['name']; 
    354     $this->currentInternalUri = array(); 
    355  
    356     if ($this->options['logging']) 
    357     { 
    358       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Match route "%s" (%s) for %s with parameters %s', $info['name'], $info['pattern'], $url, str_replace("\n", '', var_export($info['parameters'], true)))))); 
    359     } 
    360  
    361     // store the current internal URI 
    362     $parameters = $info['parameters']; 
     370    $this->currentRouteName = $name; 
     371 
    363372    $internalUri = array('@'.$this->currentRouteName, $parameters['module'].'/'.$parameters['action']); 
    364373    unset($parameters['module'], $parameters['action']); 
     
    376385 
    377386    $this->currentInternalUri = array($internalUri[0].$params, $internalUri[1].$params); 
    378  
    379     if ($info['extra_parameters']) 
    380     { 
    381       return array_merge($info['parameters'], array('_arguments' => $info['extra_parameters'])); 
    382     } 
    383     else 
    384     { 
    385       return $info['parameters']; 
    386     } 
    387387  } 
    388388 
     
    418418    $info = $this->getRouteThatMatchesUrl($url); 
    419419 
    420     // store in cache only if there is no extra parameters 
    421     if (!is_null($this->cache) && !count($info['extra_parameters'])
     420    // store in cache 
     421    if (!is_null($this->cache)
    422422    { 
    423423      $this->cacheChanged = true; 
     
    455455      } 
    456456 
    457       return array('name' => $name, 'pattern' => $route->getPattern(), 'parameters' => $parameters[0], 'extra_parameters' => $parameters[1]); 
     457      return array('name' => $name, 'pattern' => $route->getPattern(), 'parameters' => $parameters); 
    458458    } 
    459459 
  • branches/1.2/lib/routing/sfRequestRoute.class.php

    r11575 r11794  
    2727   * @param  array   $context The context 
    2828   * 
    29    * @return array   An array composed of an array of parameters and an array of extra parameters 
     29   * @return array   An array of parameters 
    3030   */ 
    3131  public function matchesUrl($url, $context = array()) 
  • branches/1.2/lib/routing/sfRoute.class.php

    r11763 r11794  
    2020{ 
    2121  protected 
     22    $isBound           = false, 
     23    $context           = null, 
     24    $parameters        = null, 
    2225    $defaultParameters = array(), 
    2326    $defaultOptions    = array(), 
     
    5659 
    5760  /** 
     61   * Binds the current route for a given context and parameters. 
     62   * 
     63   * @param array $context    The context 
     64   * @param array $parameters The parameters 
     65   */ 
     66  public function bind($context, $parameters) 
     67  { 
     68    $this->isBound    = true; 
     69    $this->context    = $context; 
     70    $this->parameters = $parameters; 
     71  } 
     72 
     73  /** 
     74   * Returns true if the form is bound to input values. 
     75   * 
     76   * @return Boolean true if the form is bound to input values, false otherwise 
     77   */ 
     78  public function isBound() 
     79  { 
     80    return $this->isBound; 
     81  } 
     82 
     83  /** 
    5884   * Returns true if the URL matches this route, false otherwise. 
    5985   * 
     
    6187   * @param  array   $context The context 
    6288   * 
    63    * @return array   An array composed of an array of parameters and an array of extra parameters 
     89   * @return array   An array of parameters 
    6490   */ 
    6591  public function matchesUrl($url, $context = array()) 
     
    97123    } 
    98124 
    99     return array($parameters, array())
     125    return $parameters
    100126  } 
    101127 
  • branches/1.2/lib/routing/sfRouting.class.php

    r11765 r11794  
    243243   * Listens to the request.filter_parameters event. 
    244244   * 
    245    * @param sfEvent $event       An sfEvent instance 
    246    * @param array   $parameters  An array of parameters for the event 
    247    * 
     245   * @param sfEvent $event       An sfEvent instance 
     246   * 
     247   * @return array   $parameters  An array of parameters for the event 
    248248   */ 
    249249  public function filterParametersEvent(sfEvent $event, $parameters) 
  • branches/1.2/lib/view/sfViewCacheManager.class.php

    r11783 r11794  
    435435  { 
    436436    // ignore cache parameter? (only available in debug mode) 
    437     if (sfConfig::get('sf_debug') && $this->context->getRequest()->getAttribute('_sf_ignore_cache')) 
     437    if (sfConfig::get('sf_debug') && $this->context->getRequest()->getAttribute('sf_ignore_cache')) 
    438438    { 
    439439      if (sfConfig::get('sf_logging_enabled')) 
  • branches/1.2/test/unit/routing/sfPatternRoutingTest.php

    r11511 r11794  
    1515class sfPatternRoutingTest extends sfPatternRouting 
    1616{ 
     17  public function parse($url) 
     18  { 
     19    $parameters = parent::parse($url); 
     20    unset($parameters['_sf_route']); 
     21 
     22    return $parameters; 
     23  } 
     24 
    1725  public function getCurrentRouteName() 
    1826  { 
     
    472480$parameters = $rCached->findRoute('/test'); 
    473481$t->is($parameters, 
    474        array('name' => 'test', 'pattern' => '/:module', 'parameters' => array('action' => 'index', 'module' => 'test'), 'extra_parameters' => array()), 
     482       array('name' => 'test', 'pattern' => '/:module', 'parameters' => array('action' => 'index', 'module' => 'test')), 
    475483       '->findRoute() returns information about matching route'); 
    476484$t->is($rCached->getCurrentInternalUri(), 'default/index', '->findRoute() does not change the internal URI of sfPatternRouting'); 
  • branches/1.2/test/unit/routing/sfRouteTest.php

    r11313 r11794  
    1616$t->diag('->matchesUrl()'); 
    1717$route = new sfRoute('/'); 
    18 $t->is($route->matchesUrl('/'), array(array(), array()), '->matchesUrl() takes a URL as its first argument'); 
     18$t->is($route->matchesUrl('/'), array(), '->matchesUrl() takes a URL as its first argument'); 
    1919$t->is($route->matchesUrl('/foo'), false, '->matchesUrl() returns false if the route does not match'); 
    2020 
    2121$route = new sfRoute('/', array('foo' => 'bar')); 
    22 $t->is($route->matchesUrl('/'), array(array('foo' => 'bar'), array()), '->matchesUrl() returns default values for parameters not in the route'); 
     22$t->is($route->matchesUrl('/'), array('foo' => 'bar'), '->matchesUrl() returns default values for parameters not in the route'); 
    2323 
    2424$route = new sfRoute('/:bar', array('foo' => 'bar')); 
    25 $t->is($route->matchesUrl('/foobar'), array(array('foo' => 'bar', 'bar' => 'foobar'), array()), '->matchesUrl() returns variables from the pattern'); 
     25$t->is($route->matchesUrl('/foobar'), array('foo' => 'bar', 'bar' => 'foobar'), '->matchesUrl() returns variables from the pattern'); 
    2626 
    2727$route = new sfRoute('/:foo', array('foo' => 'bar')); 
    28 $t->is($route->matchesUrl('/foobar'), array(array('foo' => 'foobar'), array()), '->matchesUrl() overrides default value with pattern value'); 
     28$t->is($route->matchesUrl('/foobar'), array('foo' => 'foobar'), '->matchesUrl() overrides default value with pattern value'); 
    2929 
    3030$route = new sfRoute('/:foo', array('foo' => 'bar')); 
    31 $t->is($route->matchesUrl('/'), array(array('foo' => 'bar'), array()), '->matchesUrl() matches routes with an optional parameter at the end'); 
     31$t->is($route->matchesUrl('/'), array('foo' => 'bar'), '->matchesUrl() matches routes with an optional parameter at the end'); 
    3232 
    3333$route = new sfRoute('/foo/:foo/bar/:bar', array('foo' => 'bar', 'bar' => 'foo')); 
    34 $t->is($route->matchesUrl('/foo/bar/bar'), array(array('foo' => 'bar', 'bar' => 'foo'), array()), '->matchesUrl() matches routes with an optional parameter at the end'); 
     34$t->is($route->matchesUrl('/foo/bar/bar'), array('foo' => 'bar', 'bar' => 'foo'), '->matchesUrl() matches routes with an optional parameter at the end'); 
    3535 
    3636$route = new sfRoute('/:foo/:bar', array('foo' => 'bar', 'bar' => 'foo')); 
    37 $t->is($route->matchesUrl('/'), array(array('foo' => 'bar', 'bar' => 'foo'), array()), '->matchesUrl() matches routes with multiple optionals parameters at the end'); 
     37$t->is($route->matchesUrl('/'), array('foo' => 'bar', 'bar' => 'foo'), '->matchesUrl() matches routes with multiple optionals parameters at the end'); 
    3838 
    3939$route = new sfRoute('/', array()); 
    4040$route->setDefaultParameters(array('foo' => 'bar')); 
    41 $t->is($route->matchesUrl('/'), array(array('foo' => 'bar'), array()), '->matchesUrl() gets default parameters from the routing object if it exists'); 
     41$t->is($route->matchesUrl('/'), array('foo' => 'bar'), '->matchesUrl() gets default parameters from the routing object if it exists'); 
    4242 
    4343$route = new sfRoute('/', array('foo' => 'foobar')); 
    4444$route->setDefaultParameters(array('foo' => 'bar')); 
    45 $t->is($route->matchesUrl('/'), array(array('foo' => 'foobar'), array()), '->matchesUrl() overrides routing default parameters with route default parameters'); 
     45$t->is($route->matchesUrl('/'), array('foo' => 'foobar'), '->matchesUrl() overrides routing default parameters with route default parameters'); 
    4646 
    4747$route = new sfRoute('/:foo', array('foo' => 'foobar')); 
    4848$route->setDefaultParameters(array('foo' => 'bar')); 
    49 $t->is($route->matchesUrl('/barfoo'), array(array('foo' => 'barfoo'), array()), '->matchesUrl() overrides routing default parameters with pattern parameters'); 
     49$t->is($route->matchesUrl('/barfoo'), array('foo' => 'barfoo'), '->matchesUrl() overrides routing default parameters with pattern parameters'); 
    5050 
    5151$route = new sfRoute('/:foo', array(), array('foo' => '\d+')); 
     
    5353 
    5454$route = new sfRoute('/:foo', array(), array('foo' => '\w+')); 
    55 $t->is($route->matchesUrl('/bar'), array(array('foo' => 'bar'), array()), '->matchesUrl() enforces requirements'); 
     55$t->is($route->matchesUrl('/bar'), array('foo' => 'bar'), '->matchesUrl() enforces requirements'); 
    5656 
    5757// ->matchesParameters() 
     
    130130$t->diag('->parseStarParameter()'); 
    131131$route = new sfRoute('/foo/*'); 
    132 $t->is($route->matchesUrl('/foo/foo/bar/bar/foo'), array(array('foo' => 'bar', 'bar' => 'foo'), array()), '->parseStarParameter() parses * as key/value pairs'); 
    133 $t->is($route->matchesUrl('/foo/foo/foo.bar'), array(array('foo' => 'foo.bar'), array()), '->parseStarParameter() uses / as the key/value separator'); 
    134 $t->is($route->matchesUrl('/foo'), array(array(), array()), '->parseStarParameter() returns no additional parameters if the * value is empty'); 
     132$t->is($route->matchesUrl('/foo/foo/bar/bar/foo'), array('foo' => 'bar', 'bar' => 'foo'), '->parseStarParameter() parses * as key/value pairs'); 
     133$t->is($route->matchesUrl('/foo/foo/foo.bar'), array('foo' => 'foo.bar'), '->parseStarParameter() uses / as the key/value separator'); 
     134$t->is($route->matchesUrl('/foo'), array(), '->parseStarParameter() returns no additional parameters if the * value is empty'); 
    135135 
    136136$route = new sfRoute('/foo/*', array('module' => 'foo')); 
    137 $t->is($route->matchesUrl('/foo/foo/bar/module/barbar'), array(array('foo' => 'bar', 'module' => 'foo'), array()), '->parseStarParameter() cannot override a default value'); 
     137$t->is($route->matchesUrl('/foo/foo/bar/module/barbar'), array('foo' => 'bar', 'module' => 'foo'), '->parseStarParameter() cannot override a default value'); 
    138138 
    139139$route = new sfRoute('/:foo/*'); 
    140 $t->is($route->matchesUrl('/bar/foo/barbar'), array(array('foo' => 'bar'), array()), '->parseStarParameter() cannot override pattern variables'); 
     140$t->is($route->matchesUrl('/bar/foo/barbar'), array('foo' => 'bar'), '->parseStarParameter() cannot override pattern variables'); 
    141141 
    142142$route = new sfRoute('/foo/*/bar'); 
    143 $t->is($route->matchesUrl('/foo/foo/bar/bar'), array(array('foo' => 'bar'), array()), '->parseStarParameter() is able to parse a star in the middle of a rule'); 
    144 $t->is($route->matchesUrl('/foo/bar'), array(array(), array()), '->parseStarParameter() is able to parse a star if it is empty'); 
     143$t->is($route->matchesUrl('/foo/foo/bar/bar'), array('foo' => 'bar'), '->parseStarParameter() is able to parse a star in the middle of a rule'); 
     144$t->is($route->matchesUrl('/foo/bar'), array(), '->parseStarParameter() is able to parse a star if it is empty'); 
    145145 
    146146// ->generateStarParameter()