diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index aa8714f9a..15735df17 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1410,7 +1410,7 @@ class Model extends Object implements CakeEventListener { list($model, $column) = explode('.', $column); } - if ($model != $this->alias && isset($this->{$model})) { + if (isset($model) && $model != $this->alias && isset($this->{$model})) { return $this->{$model}->getColumnType($column); } diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index cc9b0ff73..74595c400 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -173,6 +173,10 @@ class CakeRoute { foreach ($this->keys as $key) { unset($this->defaults[$key]); } + + $keys = $this->keys; + sort($keys); + $this->keys = array_reverse($keys); } /** @@ -420,7 +424,6 @@ class CakeRoute { $named = $pass = array(); foreach ($url as $key => $value) { - // keys that exist in the defaults and have different values is a match failure. $defaultExists = array_key_exists($key, $defaults); if ($defaultExists && $defaults[$key] != $value) { @@ -517,18 +520,21 @@ class CakeRoute { } $out = $this->template; - $search = $replace = array(); - foreach ($this->keys as $key) { - $string = null; - if (isset($params[$key])) { - $string = $params[$key]; - } elseif (strpos($out, $key) != strlen($out) - strlen($key)) { - $key .= '/'; + if (!empty($this->keys)) { + $search = $replace = array(); + + foreach ($this->keys as $key) { + $string = null; + if (isset($params[$key])) { + $string = $params[$key]; + } elseif (strpos($out, $key) != strlen($out) - strlen($key)) { + $key .= '/'; + } + $search[] = ':' . $key; + $replace[] = $string; } - $search[] = ':' . $key; - $replace[] = $string; + $out = str_replace($search, $replace, $out); } - $out = str_replace($search, $replace, $out); if (strpos($this->template, '*')) { $out = str_replace('*', $params['pass'], $out); diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index 1f0e283ca..375cf4d59 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -118,7 +118,7 @@ class CakeRouteTest extends CakeTestCase { $this->assertRegExp($result, '/posts/view/518098'); $this->assertNotRegExp($result, '/posts/edit/name-of-post'); $this->assertNotRegExp($result, '/posts/edit/4/other:param'); - $this->assertEquals(array('controller', 'action', 'id'), $route->keys); + $this->assertEquals(array('id', 'controller', 'action'), $route->keys); $route = new CakeRoute( '/:lang/:controller/:action/:id', @@ -130,7 +130,7 @@ class CakeRouteTest extends CakeTestCase { $this->assertRegExp($result, '/cze/articles/view/1'); $this->assertNotRegExp($result, '/language/articles/view/2'); $this->assertNotRegExp($result, '/eng/articles/view/name-of-article'); - $this->assertEquals(array('lang', 'controller', 'action', 'id'), $route->keys); + $this->assertEquals(array('lang', 'id', 'controller', 'action'), $route->keys); foreach (array(':', '@', ';', '$', '-') as $delim) { $route = new CakeRoute('/posts/:id' . $delim . ':title'); @@ -141,7 +141,7 @@ class CakeRouteTest extends CakeTestCase { $this->assertNotRegExp($result, '/posts/11!nameofarticle'); $this->assertNotRegExp($result, '/posts/11'); - $this->assertEquals(array('id', 'title'), $route->keys); + $this->assertEquals(array('title', 'id'), $route->keys); } $route = new CakeRoute( @@ -155,7 +155,7 @@ class CakeRouteTest extends CakeTestCase { $this->assertNotRegExp($result, '/posts/hey_now:nameofarticle'); $this->assertNotRegExp($result, '/posts/:nameofarticle/2009'); $this->assertNotRegExp($result, '/posts/:nameofarticle/01'); - $this->assertEquals(array('id', 'title', 'year'), $route->keys); + $this->assertEquals(array('year', 'title', 'id'), $route->keys); $route = new CakeRoute( '/posts/:url_title-(uuid::id)', @@ -204,7 +204,7 @@ class CakeRouteTest extends CakeTestCase { $this->assertRegExp($result, '/some_extra/page/this_is_the_slug'); $this->assertRegExp($result, '/page/this_is_the_slug'); - $this->assertEquals(array('extra', 'slug'), $route->keys); + $this->assertEquals(array('slug', 'extra'), $route->keys); $this->assertEquals(array('extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view'), $route->options); $expected = array( 'controller' => 'pages', @@ -855,6 +855,24 @@ class CakeRouteTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * Test matching of parameters where one parameter name starts with another parameter name + * + * @return void + */ + public function testMatchSimilarParameters() { + $route = new CakeRoute('/:thisParam/:thisParamIsLonger'); + + $url = array( + 'thisParamIsLonger' => 'bar', + 'thisParam' => 'foo', + ); + + $result = $route->match($url); + $expected = '/foo/bar'; + $this->assertEquals($expected, $result); + } + /** * test restructuring args with pass key * @@ -941,4 +959,5 @@ class CakeRouteTest extends CakeTestCase { $expected = array('section' => 'weblog', 'plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index', 'pass' => array(), 'named' => array()); $this->assertEquals($expected, $result); } + } diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php index 9c57dc570..8c6bf3c17 100644 --- a/lib/Cake/Utility/Set.php +++ b/lib/Cake/Utility/Set.php @@ -307,7 +307,7 @@ class Set { * @param string $path An absolute XPath 2.0 path * @param array $data An array of data to extract from * @param array $options Currently only supports 'flatten' which can be disabled for higher XPath-ness - * @return array An array of matched items + * @return mixed An array of matched items or the content of a single selected item or null in any of these cases: $path or $data are null, no items found. * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::extract */ public static function extract($path, $data = null, $options = array()) { @@ -532,7 +532,7 @@ class Set { * * @param array $data Array from where to extract * @param string|array $path As an array, or as a dot-separated string. - * @return array|null Extracted data or null when $data or $path are empty. + * @return mixed An array of matched items or the content of a single selected item or null in any of these cases: $path or $data are null, no items found. * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::classicExtract */ public static function classicExtract($data, $path = null) { diff --git a/lib/Cake/View/Helper/TimeHelper.php b/lib/Cake/View/Helper/TimeHelper.php index dfbfe0778..fe81bccd8 100644 --- a/lib/Cake/View/Helper/TimeHelper.php +++ b/lib/Cake/View/Helper/TimeHelper.php @@ -184,7 +184,7 @@ class TimeHelper extends AppHelper { * * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object - * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used + * @param string $format The format to use. If null, `CakeTime::$niceFormat` is used * @return string Formatted date string * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting */