Skip to content

Commit

Permalink
Adding a basic entity route class
Browse files Browse the repository at this point in the history
  • Loading branch information
burzum committed Oct 8, 2017
1 parent 5dc8e31 commit 37b33de
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/Routing/Route/EntityRoute.php
@@ -0,0 +1,69 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.6.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Routing\Route;

use Cake\Datasource\EntityInterface;
use RuntimeException;

/**
* Matches entities to routes
*/
class EntityRoute extends Route
{
/**
* Match by entity and map its fields to the URL pattern by comparing the
* field names with the template vars
*
* @param array $url Array of parameters to convert to a string.
* @param array $context An array of the current request context.
* Contains information such as the current host, scheme, port, and base
* directory.
* @return bool|string Either false or a string URL.
*/
public function match(array $url, array $context = [])
{
if (isset($url['_entity'])) {
$this->_checkEntity($url['_entity']);

$entity = $url['_entity'];
preg_match_all('@:(\w+)@', $this->template, $matches);

foreach($matches[1] as $field) {
$url[$field] = $entity[$field];
}
}

return parent::match($url, $context);
}

/**
* Checks that we really deal with an entity object
*
* @throws \RuntimeException
* @param mixed $entity
* @return void
*/
protected function _checkEntity($entity)
{
if (!$entity instanceof EntityInterface) {
throw new RuntimeException(sprintf(
'Route `%s` expects the URL option `_entity` to be `%s`, but `%s` passed.',
$this->template,
EntityInterface::class,
is_object($entity) ? get_class($entity) : gettype($entity)
));
}
}
}
57 changes: 57 additions & 0 deletions tests/TestCase/Routing/Route/EntityRouteTest.php
@@ -0,0 +1,57 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.6.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Test\TestCase\Routing\Route;

use Cake\Routing\Route\EntityRoute;
use Cake\TestSuite\TestCase;
use TestApp\Model\Entity\Article;

/**
* Test case for EntityRoute
*/
class EntityRouteTest extends TestCase
{
/**
* test that routes match their pattern.
*
* @return void
*/
public function testMatchBasic()
{
$entity = new Article([
'category_id' => 2,
'slug' => 'article-slug'
]);

$route = $route = new EntityRoute(
'/articles/:category_id/:slug',
[
'_name' => 'articlesView',
'_entity' => $entity,
'controller' => 'articles',
'action' => 'view'
]
);

$result = $route->match([
'_entity' => $entity,
'_name' => 'articlesView',
'controller' => 'articles',
'action' => 'view'
]);

$this->assertEquals('/articles/2/article-slug', $result);
}
}

0 comments on commit 37b33de

Please sign in to comment.