Permalink
Browse files

Refactor routing to allow regex routes using named subpattern

Now exact matches are done using 'uri', and regex matches are done with 'regex'.
Because ini parser(s) seesm to escape (), {} is used instead and replaced before use.
  • Loading branch information...
1 parent f4ca05d commit 6d67a7664923546584474daa40f22bd8f79697d6 @andrerom committed Apr 2, 2012
@@ -1,65 +0,0 @@
-<?php
-/**
- * CRUD Controller Interface
- *
- * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
- * @copyright Copyright (C) 2009-2012 github.com/andrerom. All rights reserved.
- * @license http://www.gnu.org/licenses/gpl-3.0.txt GNU General Public License v3
- * @version //autogentag//
- */
-
-namespace HiMVC\API\MVC;
-
-/**
- * @see http://www.parleys.com/#id=1397&sl=31&st=5
- *
- * Should only be Get, Put, Post & Delete according to slides
- * meaning there should be an index controller for /orders/
- * and an item controller for /orders/{id}
- */
-
-interface CRUDControllable
-{
- /**
- * Add new item in collection ( ie POST /orders/ )
- *
- * @return \HiMVC\API\MVC\Values\Result
- */
- public function doCreate();
-
- /**
- * Get item in collection ( ie GET /orders/{id}/{view} )
- *
- * @todo Use 'read' instead of 'retrieve' for simplicity and to avoid people using the http typo?
- *
- * @param mixed $id
- * @param string $view
- * @return \HiMVC\API\MVC\Values\Result
- */
- public function doRead( $id, $view = 'full' );
-
- /**
- * Update item in collection ( ie PUT /orders/{id} )
- *
- * @param mixed $id
- * @return \HiMVC\API\MVC\Values\Result
- */
- public function doUpdate( $id );
-
- /**
- * Delete item in collection ( ie DELETE /orders/{id} )
- * Or 'Cancel order'
- *
- * @param mixed $id
- * @return \HiMVC\API\MVC\Values\Result
- */
- public function doDelete( $id );
-
- /**
- * List items in collection ( ie GET /orders/ )
- *
- * @return \HiMVC\API\MVC\Values\Result
- */
- public function doIndex();
-}
-
@@ -9,8 +9,7 @@
*/
namespace HiMVC\Core\Content;
-use HiMVC\API\MVC\CRUDControllable,
- HiMVC\API\MVC\Values\Request,
+use HiMVC\API\MVC\Values\Request,
HiMVC\Core\MVC\View\ViewDispatcher,
eZ\Publish\API\Repository\Repository,
HiMVC\API\MVC\Values\ResultItem,
@@ -19,9 +18,9 @@
eZ\Publish\API\Repository\Values\Content\Query\Criterion\ParentLocationId;
/**
- * Example controller, does no chnages to data atm
+ * Example content controller, does no changes to data atm
*/
-class Controller implements CRUDControllable
+class Controller
{
/**
* @var \HiMVC\API\MVC\Values\Request
@@ -99,6 +98,7 @@ public function doDelete( $id )
/**
* List items in collection ( ie GET /content/ )
*
+ * @todo This should probably not list items by location, but just list of content sorted by creation
* @return \HiMVC\API\MVC\Values\Result
*/
public function doIndex()
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Content Location Controller
+ *
+ * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
+ * @copyright Copyright (C) 2009-2012 github.com/andrerom. All rights reserved.
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt GNU General Public License v3
+ * @version //autogentag//
+ */
+
+namespace HiMVC\Core\Content;
+use HiMVC\API\MVC\Values\Request,
+ HiMVC\Core\MVC\View\ViewDispatcher,
+ eZ\Publish\API\Repository\Repository,
+ HiMVC\API\MVC\Values\ResultItem,
+ HiMVC\API\MVC\Values\ResultList,
+ eZ\Publish\API\Repository\Values\Content\Query,
+ eZ\Publish\API\Repository\Values\Content\Query\Criterion\ParentLocationId;
+
+/**
+ * Example cotnent location controller, does no changes to data atm
+ */
+class LocationController
+{
+ /**
+ * @var \HiMVC\API\MVC\Values\Request
+ */
+ protected $request;
+
+ /**
+ * @var \eZ\Publish\API\Repository\Repository
+ */
+ protected $repository;
+
+ /**
+ * @param \HiMVC\API\MVC\Values\Request $request
+ * @param \eZ\Publish\API\Repository\Repository $reposiotry
+ */
+ public function __construct( Request $request, Repository $reposiotry )
+ {
+ $this->request = $request;
+ $this->repository = $reposiotry;
+ }
+
+ /**
+ * Add new item in collection ( ie POST /content/locations/ )
+ *
+ * @return \HiMVC\API\MVC\Values\Result
+ */
+ public function doCreate()
+ {
+ return __METHOD__ . "()";
+ }
+
+ /**
+ * Get item in collection ( ie GET /content/location/{id} )
+ *
+ * @param mixed $id
+ * @param string $view
+ * @return \HiMVC\API\MVC\Values\Result
+ */
+ public function doRead( $id, $view = 'full' )
+ {
+ $model = $this->repository->getLocationService()->loadLocation( $id );
+
+ return new ResultItem( array(
+ 'model' => $model,
+ 'module' => 'content/location',
+ 'action' => 'read',
+ 'view' => $view,
+ 'uri' => "content/location/{$id}",
+ ) );
+ }
+
+ /**
+ * Update item in collection ( ie PUT /content/location/{id} )
+ *
+ * @param mixed $id
+ * @return \HiMVC\API\MVC\Values\Result
+ */
+ public function doUpdate( $id )
+ {
+ return __METHOD__ . "( $id )";
+ }
+
+ /**
+ * Delete item in collection ( ie DELETE /content/location/{id} )
+ * Or 'Cancel order'
+ *
+ * @param mixed $id
+ * @return \HiMVC\API\MVC\Values\Result
+ */
+ public function doDelete( $id )
+ {
+ return __METHOD__ . "( $id )";
+ }
+
+ /**
+ * List items in collection ( ie GET /content/location/ )
+ *
+ * @return \HiMVC\API\MVC\Values\Result
+ */
+ public function doIndex()
+ {
+ return $this->doList( 1 );
+ }
+
+ /**
+ * List items in collection ( ie GET /content/locations/{$parentId} )
+ *
+ * @param mixed $parentId
+ * @param int $offset
+ * @param int $limit
+ * @return \HiMVC\API\MVC\Values\Result
+ *
+ * @todo Add global (injected) setting to specify max limits
+ */
+ public function doList( $parentId, $offset = 0, $limit = -1 )
+ {
+ $locationService = $this->repository->getLocationService();
+ $location = $locationService->loadLocation( $parentId );
+ $children = $locationService->loadLocationChildren( $location, $offset, $limit );
+
+ $resultHash = array(
+ 'items' => array(),
+ 'count' => $location->childCount,
+ 'module' => 'content/location',
+ 'action' => 'list',
+ 'uri' => "content/locations/{$parentId}",
+ );
+
+ foreach ( $children as $model )
+ {
+ $resultHash['items'][] = new ResultItem( array(
+ 'model' => $model,
+ 'module' => 'content/location',
+ 'action' => 'read',
+ 'view' => 'line',
+ 'uri' => "content/location/{$model->id}",
+ ) );
+ }
+
+ return new ResultList( $resultHash );
+ }
+}
+
@@ -0,0 +1,3 @@
+{% for resultItem in result.items %}
+ {{ view( request, resultItem ) }}
+{% endfor %}
@@ -0,0 +1,5 @@
+{{ dispatch( request.createChild( 'content/' ~ result.model.contentInfo.contentId ) ) }}
+
+Children:
+
+{{ dispatch( request.createChild( 'content/locations/' ~ result.model.id ) ) }}
@@ -0,0 +1,5 @@
+<h4><a href="{{ link( request, result ) }}">Name: {{ result.model.contentInfo.name }}</a></h4>
+
+
+Line view twig template got Location object with id: {{ result.model.id }}
+<a href="{{ link( request, result, true ) }}">Read more</a>
@@ -2,25 +2,35 @@
[router]
# @todo Way to much routing to be able to do CRUD
-arguments[routes][content][item][uri]=content/
-arguments[routes][content][item][params][id]=\d+
-arguments[routes][content][item][params][view]=\w+
-arguments[routes][content][item][optional][view]=true
+arguments[routes][content][item][regex]=content/{?<id>\d+}{/{?<view>\w+}}?
arguments[routes][content][item][methods][GET]=doRead
arguments[routes][content][item][methods][PUT]=doUpdate
arguments[routes][content][item][methods][DELETE]=doDelete
-arguments[routes][content][item][controller]=%contentItem-controller
+arguments[routes][content][item][controller]=%content-controller
-arguments[routes][content][list][uri]=content
-arguments[routes][content][list][method]=GET
-arguments[routes][content][list][function]=%contentItem-controller::doIndex
-#arguments[routes][content][list][methods][GET]=doIndex
-#arguments[routes][content][list][controller]=%contentItem-controller
+arguments[routes][contents][create][uri]=contents
+arguments[routes][contents][create][methods][GET]=doIndex
+arguments[routes][contents][create][methods][POST]=doCreat
+arguments[routes][contents][create][controller]=%content-controller
-arguments[routes][content][create][uri]=content
-arguments[routes][content][create][methods][POST]=doCreat
-arguments[routes][content][create][controller]=%contentItem-controller
+arguments[routes][content][location_item][regex]=content/location/{?<id>\d+}{/{?<view>\w+}}?
+arguments[routes][content][location_item][methods][GET]=doRead
+arguments[routes][content][location_item][methods][PUT]=doUpdate
+arguments[routes][content][location_item][methods][DELETE]=doDelete
+arguments[routes][content][location_item][controller]=%contentLocation-controller
+arguments[routes][content][location_create][uri]=content/locations
+arguments[routes][content][location_create][methods][POST]=doCreat
+arguments[routes][content][location_create][methods][GET]=doIndex
+arguments[routes][content][location_create][controller]=%contentLocation-controller
-[contentItem-controller]
-class=HiMVC\Core\Content\Controller
+arguments[routes][content][location_list][regex]=content/locations/{?<id>\d+}
+arguments[routes][content][location_list][method]=GET
+arguments[routes][content][location_list][function]=%contentLocation-controller::doList
+
+
+[content-controller]
+class=HiMVC\Core\Content\Controller
+
+[contentLocation-controller]
+class=HiMVC\Core\Content\LocationController
@@ -1,6 +1,6 @@
<?php
/**
- * Content Controller
+ * Hello World Controller
*
* @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
* @copyright Copyright (C) 2009-2012 github.com/andrerom. All rights reserved.
@@ -13,9 +13,9 @@
use HiMVC\API\MVC\Values\Request as APIRequest;
/**
- * Example controller, does no chnages to data atm
+ * Example Hello World controller
*/
-class Hello
+class HelloController
{
/**
* @var \HiMVC\API\MVC\Values\Request
View
@@ -55,30 +55,25 @@ public function route( APIRequest $request )
if ( isset( $route['methods'] ) && !isset( $route['methods'][$request->method] ) )
continue;// No match: next route
- if ( isset( $route['uri'] ) && $uri !== $route['uri'] && strpos( $uri, $route['uri'] ) !== 0 )
+ if ( isset( $route['uri'] ) && $uri !== $route['uri'] )
continue;// No match: next route
$uriParams = array();
- if ( isset( $route['params'] ) )
+ if ( isset( $route['regex'] ) )
{
- $pos = substr_count( $route['uri'], '/' );
- foreach ( $route['params'] as $uriParam => $uriParamRegex )
+ $regex = str_replace( array( '{', '}' ), array( '(', ')' ), $route['regex'] );
+ if ( !preg_match( "@^{$regex}$@", $uri, $matches ) )
{
- if ( !isset( $uriArray[ $pos ] ) )
- {
- if ( isset( $route['optional'][$uriParam] ) && $route['optional'][$uriParam] )
- {
- break;// Still a match: As you can not have non optional params after a optional one
- }
- continue 2;// No match: next route
- }
-
- if ( preg_match( "/^({$uriParamRegex})$/", $uriArray[ $pos ] ) !== 1 )
- continue 2;
+ continue;
+ }
- $uriParams[$uriParam] = $uriArray[ $pos ];
- $pos++;// No match: next route
+ $i = 0;// Remove all indexes that has numeric keys, the once we care about have string keys
+ while ( isset( $matches[$i] ) )
+ {
+ unset( $matches[$i] );
+ ++$i;
}
+ $uriParams = $matches;
}
if ( isset( $route['function'] ) )
@@ -29,7 +29,7 @@ arguments[conditions][]
#### Core\MVC\Hello example Hello World Controller ####
[Hello-controller]
-class=HiMVC\Core\MVC\Hello
+class=HiMVC\Core\MVC\HelloController
arguments[request]=@request

0 comments on commit 6d67a76

Please sign in to comment.