Skip to content

Commit

Permalink
Begin switching to sf router
Browse files Browse the repository at this point in the history
  • Loading branch information
flack committed Jul 14, 2018
1 parent 94b6d69 commit 3b0b8b6
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 52 deletions.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -48,6 +48,7 @@
"symfony/http-foundation": "~2.8.29 | ~3.4 | ^4.0",
"symfony/intl": "~3.4 | ^4.0",
"symfony/options-resolver": "~3.4 | ^4.0",
"symfony/routing": "~3.4 | ^4.0",
"symfony/security-csrf": "~2.5 | ~3.4 | ^4.0",
"symfony/translation": "~2.3 | ~3.4 | ^4.0",
"symfony/validator": "~2.8 | ~3.4 | ^4.0"
Expand Down
72 changes: 20 additions & 52 deletions lib/midcom/baseclasses/components/request.php
Expand Up @@ -6,6 +6,10 @@
* @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
*/

use Symfony\Component\Routing\Router;
use midcom\routing\loader;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

/**
* Base class to encapsulate the component's routing, instantiated by the MidCOM
* component interface.
Expand Down Expand Up @@ -344,15 +348,21 @@ public function can_handle(array $argv)

$this->_prepare_request_switch($routes);

foreach ($routes as $key => $request) {
if ($this->_validate_route($request, $argv)) {
// Prepare the handler object
$this->_prepare_handler($key, $request, $argv);
return true;
}
$loader = new loader();
$router = new Router($loader, $routes);
if (empty($argv)) {
$url = '/';
} else {
$url = '/' . implode('/', $argv) . '/';
}
try {
$result = $router->match($url);
$this->_prepare_handler($result, $argv);
return true;
} catch (ResourceNotFoundException $e) {
// No match
return false;
}
// No match
return false;
}

/**
Expand All @@ -377,59 +387,17 @@ private function _prepare_request_switch(array &$routes)
}
}

private function _validate_route(array $request, array $argv)
{
$fixed_args_count = count($request['fixed_args']);
$variable_args_count = $request['variable_args'];
$total_args_count = $fixed_args_count + $variable_args_count;

if ( (count($argv) != $total_args_count && ($variable_args_count >= 0))
|| $fixed_args_count > count($argv)) {
return false;
}

// Check the static parts
if (array_slice($argv, 0, $fixed_args_count) != $request['fixed_args']) {
return false;
}

// Validation for variable args
for ($i = 0; $i < $variable_args_count; $i++) {
// rule exists?
if (!empty($request['validation'][$i])) {
$param = $argv[$fixed_args_count + $i];
// by default we use an OR condition
// so as long as one rules succeeds, we are ok..
$success = false;
foreach ($request['validation'][$i] as $rule) {
// rule is a callable function, like mgd_is_guid or is_int
if ( is_callable($rule)
&& $success = call_user_func($rule, $param)) {
break;
}
}
// validation failed, we can stop here
if (!$success) {
return false;
}
}
}

return true;
}

/**
* Prepares the handler callback for execution.
* This will create the handler class instance if required.
*
* @param mixed $key
* @param array $request
* @param array $argv
* @throws midcom_error
*/
private function _prepare_handler($key, array $request, array $argv = [])
private function _prepare_handler(array $request, array $argv = [])
{
$request['id'] = $key;
$request['id'] = $request['_route'];
$request['args'] = array_slice($argv, count($request['fixed_args']));

if (is_string($request['handler'])) {
Expand Down
72 changes: 72 additions & 0 deletions src/midcom/routing/loader.php
@@ -0,0 +1,72 @@
<?php
/**
* @package midcom.routing
* @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
* @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License
*/

namespace midcom\routing;

use Symfony\Component\Config\Loader\Loader as base;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

/**
* @package midcom.routing
*/
class loader extends base
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Config\Loader\LoaderInterface::load()
*/
public function load($array, $type = null)
{
$collection = new RouteCollection();

foreach ($array as $name => $config) {
$path = '/';
$requirements = [];
if (!empty($config['fixed_args'])) {
$path = '/' . implode('/', $config['fixed_args']) . '/';
}
for ($i = 0; $i < $config['variable_args']; $i++) {
$path .= '{args_' . $i . '}/';
if (!empty($config['validation'][$i])) {
$requirements['args_' . $i] = $this->translate_validation($config['validation'][$i]);
}
}
$route = new Route($path, $config, $requirements);
$collection->add($name, $route);
}

return $collection;
}

/**
* Small transitory helper for old-style route validation configs
*
* @param array $input
* @return string
*/
private function translate_validation(array $input)
{
foreach ($input as &$value) {
if ($value == 'is_numeric' || $value == 'is_int') {
$value = '\d+';
} elseif ($value == 'mgd_is_guid') {
$value = '[0-9a-f]{21,80}';
}
}
return implode('|', $input);
}

/**
* {@inheritdoc}
*/
public function supports($resource, $type = null)
{
return is_array($resource) && (!$type || 'array' === $type);
}
}

0 comments on commit 3b0b8b6

Please sign in to comment.