Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
This will match:
$url = Router::match(array('controller' => 'users', 'action' => 'login'));
returns /login
For URLs templates with no insert parameters (i.e. elements like {:id} that are replaced
with a value), all parameters must match exactly as they appear in the route parameters.
Alternatively to using a full array, you can specify routes using a more compact syntax. The
above example can be written as:
$url = Router::match('Users::login'); // still returns /login
You can combine this with more complicated routes; for example:
Router::connect('/posts/{:id:\d+}', array('controller' => 'posts', 'action' => 'view'));
This will match:
$url = Router::match(array('controller' => 'posts', 'action' => 'view', 'id' => '1138'));
returns /posts/1138
Again, you can specify the same URL with a more compact syntax, as in the following:
$url = Router::match(array('Posts::view', 'id' => '1138'));
again, returns /posts/1138
You can use either syntax anywhere an URL is accepted, i.e. when redirecting
or creating links using the Html helper.
public static match ( array | string $url = [], |
||
$url | array | string | An array of parameters to match, or paremeters in their shorthand form (i.e. `'Posts::view'`). Also takes non-routed, manually generated URL strings. |
$context | This supplies the context for any persistent parameters, as well as the base URL for the application. | |
$options | array | Options for the generation of the matched URL. Currently accepted values are: - `'absolute'` _boolean_: Indicates whether or not the returned URL should be an absolute path (i.e. including scheme and host name). - `'host'` _string_: If `'absolute'` is `true`, sets the host name to be used, or overrides the one provided in `$context`. - `'scheme'` _string_: If `'absolute'` is `true`, sets the URL scheme to be used, or overrides the one provided in `$context`. - `'scope'` _string_: Optionnal scope name. |
return | string | Returns a generated URL, based on the URL template of the matched route, and prefixed with the base URL of the application. |
/** * Create navigation link compatible with `Twitter Bootstrap` markup. * Instead of plain `<a/>` output this method wrap anchor in `<li/>`. If current url is url of * wrapped `<a/>` add `active` class to `<li/>` wrapper. * For example: * {{{ * $this->backend->nav('Test', '/'); * // outputs: * // <li><a href="/">Test</a></li> * // if current url is url of anchor: * // <li class="active"><a href="/">Test</a></li> * }}} * * @param $title * @param mixed $url * @param array $options Add following options to link: * - `'wrapper-options'` _array_: Options that will be passed to `'nav-link'` * - `'return'` _string_: Define would you like `'html'` output or `'array'` that contains two * keys `'active'` _boolean_ and `'html'` used by `dropdown` method for example to know when * to add `'active'` class to parent. * * @return array|string * * @see lithium\template\helper\Html::link() */ public function nav($title, $url = null, array $options = array()) { $defaults = array('wrapper-options' => array(), 'return' => 'html'); list($scope, $options) = $this->_options($defaults, $options); $request = $this->_context->request(); $currentUrl = $request->env('base') . $request->url; $matchedUrl = Router::match($url, $request); $active = false; if ($currentUrl === $matchedUrl || $currentUrl === $matchedUrl . '/index') { $active = true; if (isset($scope['wrapper-options']['class'])) { $scope['wrapper-options']['class'] .= ' active'; } else { $scope['wrapper-options']['class'] = 'active'; } } $link = $this->link($title, $url, $options); $html = $this->_render(__METHOD__, 'nav-link', array('options' => $scope['wrapper-options'], 'link' => $link)); if ($scope['return'] === 'html') { return $html; } if ($scope['return'] === 'array') { return compact('active', 'html'); } }
/** * Fetch data for current path * On first access return HTML * Next time you fetch via AJAX return just JSON that we render client side * * html:method GET */ public function index() { $path = $this->request->args ? join('/', $this->request->args) : null; $data = Location::ls($path); if ($data === false) { return $this->redirect($this->_link); } $breadcrumb = array(array('Index', 'url' => Router::match($this->_link, $this->request, array('absolute' => true)))); $args = array(); foreach ($this->request->args as $arg) { $args[] = $arg; $this->_link += array('args' => $args); $breadcrumb[] = array($arg, 'url' => Router::match($this->_link, $this->request, array('absolute' => true))); } $breadcrumb[count($breadcrumb) - 1]['url'] = null; if ($this->request->is('ajax')) { return $this->render(array('json' => compact('data', 'breadcrumb'))); } return compact('data', 'breadcrumb'); }
/** * Prepare data to display and calculate the current node. * @param array $menu The menu description. * @param array $options Options. * @return array Calulated menu. */ protected function _prepare(array $menu, array $options = array()) { $return = array(); $active = false; $current = array_filter($this->request->params); foreach ($menu as $label => $mask) { $link = array('url' => null, 'label' => is_string($label) ? $label : null, 'class' => null, 'active' => null, 'mask' => null); if (is_string($mask)) { $link['url'] = $mask; } elseif (array_intersect_key($mask, array('class' => true))) { $link = $mask + $link; } else { $link['url'] = $mask; } if (!is_string($link['url'])) { $link['url'] = Router::match($link['url']); } if (!$active) { if ($link['active']) { // Force the value $link['active'] = 'active'; } else { if ($link['mask']) { // We have a mask. Easy. $compare = array_filter($link['mask']); } else { // Only do this if we haven't found any active link yet and we haven't any mask to compare ! $request = new Request(); $request->url = $link['url']; $compare = array_filter(Router::parse($request)->params); } $link['active'] = Url::match($current, $compare) ? 'active' : ''; } $active = !empty($link['active']); } $return[] = $link; } return $return; }
public function upload() { if (!$this->request->is('ajax')) { return array(); } $model = $this->model; $this->_render['type'] = 'json'; $allowed = '*'; $file = $this->_upload(compact('allowed')); if ($file['error'] !== UPLOAD_ERR_OK) { return $file; } $result = $model::init($file); if (!empty($result['asset'])) { $result['message'] = !empty($result['success']) ? 'upload successful' : 'file already present'; $result['url'] = Router::match(array('library' => 'radium', 'controller' => 'assets', 'action' => 'view', 'id' => $result['asset']->id()), $this->request, array('absolute' => true)); // unset($result['asset']); } // if ($result['success']) { // unset($result['asset']); // } return $result; }
public function addAction() { $success = false; $url = ""; $errors = array(); if (!Auth::check('default')) { $errors['login'] = '******'; } else { if (!$this->request->is('post')) { $errors['call'] = 'This action can only be called with post'; } else { if ($this->request->data) { $post = Posts::create($this->request->data); if ($success = $post->save()) { $url = "http://" . $_SERVER['HTTP_HOST'] . Router::match(array('controller' => 'posts', 'action' => 'view', 'id' => $post->id)); } else { $errors = $post->errors(); } } } } return compact('success', 'errors', 'url'); }
/** * Renders and returns the generated html for the targeted item and its element and children * * @param mixed $source String or Array target notations * @param array $options * @options 'class' > <ul class="?"><li><ul>..</li></ul> * @options 'id' > <ul id="?"><li><ul>..</li></ul> * @options 'ul' > string:class || array('class','style') * @options 'div' > string:class || boolean:use || array('id','class','style') * @options 'active'> array('tag' => string(span,strong,etc), 'attributes' => array(htmlAttributes), 'strict' => boolean(true|false))) * * @example echo $menu->generate('context', array('active' => array('tag' => 'link','attributes' => array('style' => 'color:red;','id'=>'current')))); * @return mixed string generated html or false if target doesnt exist */ function generate($source = 'main', $options = array()) { $out = ''; $list = ''; if (isset($options['ul'])) $ulAttributes = $options['ul']; else $ulAttributes = array(); // DOM class attribute for outer UL if (isset($options['class'])) { $ulAttributes['class'] = $options['class']; } else { if (is_array($source)) { $ulAttributes['class'] = 'menu_' . $source[count($source) - 1]; } else { $ulAttributes['class'] = 'menu_' . $source; } } // DOM element id for outer UL if (isset($options['id'])) { $ulAttributes['id'] = $options['id']; } $menu = array(); // Find source menu if (is_array($source)) { $depth = count($source); $menu = &$this->items; for ($i = 0; $i < $depth; $i++) { if (!empty($menu) && array_key_exists($source[$i], $menu)) { $menu = &$menu[$source[$i]]; } else { if (!isset($options['force']) || (isset($options['force']) && !$options['force'])) return false; } } } else { if (!isset($this->items[$source])) { if (!isset($options['force']) || (isset($options['force']) && !$options['force'])) return false; } else { $menu = &$this->items[$source]; } } if (isset($options['reverse']) && $options['reverse'] == true) { unset($options['reverse']); $menu = array_reverse($menu); } $requestObj = $this->_context->request(); if (isset($options['active']['strict']) && !$options['active']['strict']) { $requestParams = $requestObj->params; $here = trim(Router::match(array( 'controller' => $requestParams['controller'], 'action' => $requestParams['action'] ), $requestObj), "/"); } else { $here = $requestObj->url; } // Generate menu items foreach ($menu as $key => $item) { $liAttributes = array(); $aAttributes = array(); if (isset($item[1]['li'])) { $liAttributes = $item[1]['li']; } if (isset($item[0]) && $item[0] === true) { $menusource = $source; if (!is_array($menusource)) { $menusource = array($menusource); } $menusource[] = $key; // Don't set DOM element id on sub menus */ if (isset($options['id'])) { unset($options['id']); } $listitem = $this->generate($menusource, $options); if (empty($listitem)) { continue; } } elseif (isset($item[0])) { if (!isset($item[0][2]['title'])) { $item[0][2]['title'] = $item[0][0]; } $active = ($here == trim(Router::match($item[0][1], $requestObj), "/")); if ( isset($options['active']) && $active) { if (is_array($options['active'])) { $tagOptions = array(); foreach ($options['active'] as $a => $v) { if ($a == 'tag' || $a == 'strict' || $a == 'options') continue; if ($a == 'title') $tagOptions[$v] = $item[0][1]; elseif ($a == 'url') $tagOptions[$v] = $item[0][0]; } if (empty($tagOptions)) $tagOptions['content'] = $item[0][0]; $tag = isset($options['active']['tag'])?$options['active']['tag']:'span'; } else { $tag = 'span'; $tagOptions['content'] = $item[0][0]; } $tagOptions['options'] = isset($options['active']['options'])? $options['active']['options']: array(); $listitem = $this->tag($tag, $tagOptions); } else { if ($active) { if (is_array($item[0][2])) { if (isset($item[0][2]['class'])) { $item[0][2]['class'] .= ' active'; } else { $item[0][2]['class'] = 'active'; } } else { $item[0][2] = array('class' => 'active'); } } $listitem = $this->tag('link', array( 'title' => $item[0][0], 'url' => $item[0][1], 'options' => $item[0][2] )); } } elseif (isset($item[2])) { $listitem = $item[2]; } else { continue; } if (isset($item[1]['div']) && $item[1]['div'] !== false) { $divOptions = array(); if (is_array($item[1]['div'])) { $divOptions = $item[1]['div']; } $listitem = $this->tag('block', array('content' => $listitem,'options' => $divOptions)); } if (substr($listitem,0,3) == '<ul') { $list .= $listitem; } else { $list .= $this->tag('list-item', array('content' => $listitem,'options' => $liAttributes)); } } // Generate menu $out .= $this->tag('list', array('content' => $list, 'options' => $ulAttributes)); // Add optional outer div if (isset($options['div']) && $options['div'] !== false) { $divOptions = array(); if (is_array($options['div'])) { $divOptions = $options['div']; } $out = $this->tag('block', array('content' => $out, 'options' => $divOptions)); } return $out; }
/** * Generates the url * * @param array $params Query params to force * @return string Full url */ protected function _url(array $params = []) { $current = !empty($this->_request->params) ? $this->_request->params : []; $query = !empty($this->_request->query) ? $this->_request->query : []; if (!empty($query['url'])) { unset($query['url']); } $query = $params + $query; return Router::match(!empty($query) ? ['?' => $query] + $current : $current, $this->_request, ['absolute' => true]); }
$cacheKey = $params['request']->params['controller'] . 'Controller::' . $params['request']->params['action']; if (isset($response->varnish) && !empty($response->varnish)) { $cache = Varnish::cache($cacheKey, true); if (is_array($response->varnish)) { $cache += $response->varnish; } } else { $cache = Varnish::cache($cacheKey); } if (!empty($cache)) { $varnishHeaders = Varnish::headers($cache); foreach ($varnishHeaders as $key => $val) { $response->headers($key, $val); } } return $response; }); // filter to set esi includes around partials Media::applyFilter('view', function ($self, $params, $chain) { $view = $chain->next($self, $params, $chain); $view->applyFilter('_step', function ($self, $params, $chain) { $content = $chain->next($self, $params, $chain); if (isset($params['options']['esi']) && $params['options']['esi'] == true) { if (!empty($content)) { $content = \lithium\util\String::insert(Varnish::config('template'), array('url' => Router::match(array('controller' => 'Esi', 'action' => 'show', 'type' => $params['step']['path'], 'name' => $params['options']['template'])), 'content' => $content)); } } return $content; }); return $view; });
<?php use lithium\net\http\Router; $url = Router::match(array('library' => 'radium', 'controller' => 'assets', 'action' => 'show', 'id' => $this->scaffold->object->id()), $this->request(), array('absolute' => true)); ?> <div class="plaintext"><pre><?php echo $url; ?> </pre></div> <audio controls><source src="<?php echo $url; ?> " type="<?php echo $this->scaffold->object['mime']; ?> "></audio> <hr /> <?php unset($this->scaffold->object['file']); echo $this->scaffold->render('data', array('data' => \lithium\util\Set::flatten($this->scaffold->object->data())));
/** * Generates absolute URL to the webroot folder via reverse routing. * * @return string Absolute URL to webroot */ protected static function _url() { $request = new Request(); return Router::match('/', $request, ['absolute' => true]); }
/** * Creates the individual numeric page links, with the current link in the middle. * * @see li3_paginate\extensions\helper\Paginator::paginate() * @return string Markup of the numeric page links. */ public function numbers(array $options = array()) { if (!empty($options)) { $this->config($options); } $maxNumbers = $this->_config['maxNumbers']; $addOne = false; if ($maxNumbers % 2 > 0) { $addOne = true; $maxNumbers--; } $minNumbersBefore = $maxNumbers / 2; $maxNumbersAfter = $minNumbersBefore; if ($addOne) { $maxNumbers++; } $start = $this->_page - $minNumbersBefore; $end = ceil($this->_total / $this->_limit); if ($this->_page <= $minNumbersBefore) { $start = 1; } if ($this->_page + $maxNumbersAfter < $end) { $end = $this->_page + $maxNumbersAfter; } $buffer = ""; $url = array('controller' => $this->_controller, 'action' => $this->_action); true; if (!empty($this->_library)) { $url['library'] = $this->_library; } for ($i = $start; $i <= $end; $i++) { $config = array('page' => $i) + $this->_query(); $url = \lithium\net\http\Router::match($config + $this->_context->_config['request']->params, $this->_context->_config['request'], array('absolute' => true)); if ($this->_page == $i) { $buffer .= $this->_config['activeOpenTag'] . $this->_context->html->link($i, $url) . $this->_config['closeTag']; } else { $buffer .= $this->_config['openTag'] . $this->_context->html->link($i, $url) . $this->_config['closeTag']; } } return $buffer; }
public function testLibraryBasedRoute() { $route = Router::connect('/{:library}/{:controller}/{:action}', array('library' => 'app'), array('persist' => array('library'))); $expected = '/app/hello/world'; $result = Router::match(array('controller' => 'hello', 'action' => 'world')); $this->assertEqual($expected, $result); $expected = '/myapp/hello/world'; $result = Router::match(array('library' => 'myapp', 'controller' => 'hello', 'action' => 'world')); $this->assertEqual($expected, $result); }
Dispatcher::applyFilter('_callable', function ($self, $params, $chain) { // Run other filters first. This allows this one to not exactly be overwritten or excluded...But it does allow for a different login action to be used... // TODO: Perhaps allow this to be skipped... $next = $chain->next($self, $params, $chain); $request = $params['request']; $action = $request->action; $user = Auth::check('li3b_user'); // Protect all admin methods except for login and logout. if ($request->admin === true && $action != 'login' && $action != 'logout') { $action_access = Access::check('default', $user, $request, array('rules' => array('allowManagers'))); if (!empty($action_access)) { FlashMessage::write($action_access['message'], 'default'); if ($user) { header('Location: ' . Router::match($action_access['redirect'])); } else { header('Location: ' . Router::match(array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'login'))); } // None shall pass. exit; } } // Sets the current user in each request for convenience. $params['request']->user = $user; return $next; // return $chain->next($self, $params, $chain); }); Access::config(array('default' => array('adapter' => 'Rules', 'filters' => array()))); // Set some basic rules to be used from anywhere // Allow access for users with a role of "administrator" or "content_editor" Access::adapter('default')->add('allowManagers', function ($user, $request, $options) { if ($user && ($user['role'] == 'administrator' || $user['role'] == 'content_editor')) {
/** * _init() * * Setup the php library */ public function _init() { parent::_init(); //var_dump(getBaseUrl()); static::$_uploadHandler = new UploadHandler(array('script_url' => Router::match(array('Uploads::deleteAction', 'type' => 'json')), 'upload_dir' => LITHIUM_APP_PATH . '/webroot/upload/files/', 'upload_url' => '/upload/files/', 'param_name' => 'files', 'delete_type' => 'DELETE', 'max_file_size' => null, 'min_file_size' => 1, 'accept_file_types' => '/.+$/i', 'max_number_of_files' => null, 'max_width' => null, 'max_height' => null, 'min_width' => 1, 'min_height' => 1, 'discard_aborted_uploads' => true, 'orient_image' => false, 'image_versions' => array('thumbnail' => array('upload_dir' => LITHIUM_APP_PATH . '/webroot/upload/thumbnails/', 'upload_url' => '/upload/thumbnails/', 'max_width' => 80, 'max_height' => 80)))); }
public function testScopeBase() { $request = new Request(array('base' => 'lithium/app')); Router::connect('/{:controller}/{:action}'); $url = array('controller' => 'HelloWorld'); $expected = '/lithium/app/hello_world'; $this->assertEqual($expected, Router::match($url, $request)); Router::attach(false, array('base' => 'lithium')); $expected = '/lithium/hello_world'; $this->assertEqual($expected, Router::match($url, $request)); Router::attach(false, array('base' => '')); $expected = '/hello_world'; $this->assertEqual($expected, Router::match($url, $request)); }
/** * Renders and returns the generated html for the targeted item and its element and children * * @param mixed $source String or Array target notations * @param array $options * @options 'class' > <ul class="?"><li><ul>..</li></ul> * @options 'id' > <ul id="?"><li><ul>..</li></ul> * @options 'ul' > string:class || array('class','style') * @options 'div' > string:class || boolean:use || array('id','class','style') * @options 'active'> array('tag' => string(span,strong,etc), 'attributes' => array(htmlAttributes), 'strict' => boolean(true|false))) * * @example echo $this->lists->generate('context', array('active' => array('tag' => 'link','attributes' => array('style' => 'color:red;','id'=>'current')))); * @return mixed string generated html or false if target doesnt exist */ function generate($source = 'main', $options = array()) { $out = ''; $list = ''; if (isset($options['ul'])) { $ulAttributes = $options['ul']; } else { $ulAttributes = array(); } // DOM class attribute for outer UL if (isset($options['class'])) { $ulAttributes['class'] = $options['class']; } else { if (is_array($source)) { $ulAttributes['class'] = 'menu_' . $source[count($source) - 1]; } else { $ulAttributes['class'] = 'menu_' . $source; } } // DOM element id for outer UL if (isset($options['id'])) { $ulAttributes['id'] = $options['id']; } $menu = $this->findSource($source, $options); if ($menu === false) { return false; } if (isset($options['reverse']) && $options['reverse'] == true) { unset($options['reverse']); $menu = array_reverse($menu); } $requestObj = $this->_context->request(); if (isset($options['active']['strict']) && !$options['active']['strict']) { $requestParams = $requestObj->params; $here = trim(Router::match(array('controller' => $requestParams['controller'], 'action' => $requestParams['action']), $requestObj), "/"); } else { $here = $requestObj->url; } $base = Router::match('/', $requestObj); if ($base == '/') { $baseOffset = 1; } else { $baseOffset = strlen($base); } // Generate menu items foreach ($menu as $key => $item) { $liAttributes = array(); $aAttributes = array(); if (isset($item[1]['li'])) { $liAttributes = $item[1]['li']; } if (isset($item[0]) && $item[0] === true) { $menusource = $source; if (!is_array($menusource)) { $menusource = array($menusource); } $menusource[] = $key; // Don't set DOM element id on sub menus */ if (isset($options['id'])) { unset($options['id']); } $listitem = $this->generate($menusource, $options); if (empty($listitem)) { continue; } } elseif (isset($item[0])) { if (!isset($item[0][2]['title'])) { $item[0][2]['title'] = $item[0][0]; } $routeUrl = Router::match($item[0][1], $requestObj); if ($baseOffset) { $routeUrl = substr($routeUrl, $baseOffset); } $active = $here == $routeUrl || $here == '/' && empty($routeUrl); if (isset($options['active']) && $options['active'] && $active) { if (isset($options['active']['li']) && is_array($options['active']['li'])) { $liAttributes += $options['active']['li']; } if (is_array($options['active'])) { $tagOptions = array(); foreach ($options['active'] as $a => $v) { if ($a == 'tag' || $a == 'strict' || $a == 'options') { continue; } if ($a == 'title') { $tagOptions[$v] = $item[0][1]; } elseif ($a == 'url') { $tagOptions[$v] = $item[0][0]; } } if (empty($tagOptions)) { $tagOptions['content'] = $item[0][0]; } $tag = isset($options['active']['tag']) ? $options['active']['tag'] : 'span'; } else { $tag = 'span'; $tagOptions['content'] = $item[0][0]; } $tagOptions['options'] = isset($options['active']['options']) ? $options['active']['options'] : array(); $listitem = $this->tag($tag, $tagOptions); } else { $listitem = $this->tag('link', array('title' => $item[0][0], 'url' => $item[0][1], 'options' => $item[0][2])); } } elseif (isset($item[2])) { $listitem = $item[2]; } else { continue; } if (isset($item[1]['div']) && $item[1]['div'] !== false) { $divOptions = array(); if (is_array($item[1]['div'])) { $divOptions = $item[1]['div']; } $listitem = $this->tag('block', array('content' => $listitem, 'options' => $divOptions)); } if (substr($listitem, 0, 3) == '<ul') { $list .= $listitem; } else { $list .= $this->tag('list-item', array('content' => $listitem, 'options' => $liAttributes)); } } // Generate menu $out .= $this->tag('list', array('content' => $list, 'options' => $ulAttributes)); // Add optional outer div if (isset($options['div']) && $options['div'] !== false) { $divOptions = array(); if (is_array($options['div'])) { $divOptions = $options['div']; } $out = $this->tag('block', array('content' => $out, 'options' => $divOptions)); } return $out; }
/** * This renders a menu for use with Twitter Bootstrap * CSS and JS for Twitter Bootstrap style drop down menus. * * Note: No need to pass class names, etc. unless they are different * than what Twitter Bootstrap requires. * * @param string $name The menu name * @param array $options * @return string HTML code for the menu */ public function render($name = null, $options = array()) { $defaults = array('cache' => false, 'menuId' => '', 'menuClass' => '', 'activeClass' => 'active'); $options += $defaults; if (empty($name) || !is_string($name)) { return ''; } // Get the current URL (false excludes the domain) $here = $this->_context->html->here(false); // set the cache key for the menu $cache_key = empty($name) ? 'li3b_menus.all' : 'li3b_menus.' . $name; $menu = false; // if told to use the menu from cache (note: filters will not be applied for this call because Menu::staticMenu() should not be called provided there's a copy in cache) if (!empty($options['cache'])) { $menu = Cache::read('default', $cache_key); } // if the menu hasn't been set in cache or it was empty for some reason, get a fresh copy of its data if (empty($menu)) { $menu = Menu::staticMenu($name); } // if using cache, write the menu data to the cache key if (!empty($options['cache'])) { Cache::write('default', $cache_key, $menu, $options['cache']); } // Format the HTML for the menu // option for additional custom menu class $menuClass = ' ' . $options['menuClass']; $activeClassName = ' ' . $options['activeClass']; $string = "\n"; $string .= '<ul class="nav nav-pills ' . $name . '_menu' . $menuClass . '" id="' . $options['menuId'] . '">'; $string .= "\n"; if (is_array($menu)) { $i = 1; $total = count($menu); foreach ($menu as $parent) { $title = isset($parent['title']) && !empty($parent['title']) ? $parent['title'] : false; $url = isset($parent['url']) && !empty($parent['url']) ? $parent['url'] : false; $activeIf = isset($parent['activeIf']) && !empty($parent['activeIf']) ? $parent['activeIf'] : array(); $options = isset($parent['options']) && is_array($parent['options']) ? $parent['options'] : array(); $sub_items = isset($parent['subItems']) && is_array($parent['subItems']) ? $parent['subItems'] : array(); if ($parent == 'separator' || $parent == 'spacer' || $parent == 'divider') { $string .= '<li class="divider-vertical"></li>'; } else { if ($title && $url) { $string .= "\t"; $matched_route = false; try { $matched_route = Router::match($url); } catch (\Exception $e) { } // /admin is of course admin_ prefix actions $activeClass = $matched_route == $here || strstr($here, '/admin' . $matched_route) ? $activeClassName : ''; // This plus the Router::match() above really needs some love. // Less if statements...Should be some shorter/nicer way to write it. if (!empty($activeIf)) { if (isset($activeIf['library']) && isset($this->_context->request()->params['library'])) { if ($activeIf['library'] == $this->_context->request()->params['library']) { $activeClass = $activeClassName; } } elseif (isset($this->_context->request()->params['controller']) && (isset($activeIf['controller']) && $activeIf['controller'] == $this->_context->request()->params['controller'])) { $activeClass = $activeClassName; } elseif (isset($activeIf['url']) && $activeIf['url'] == $this->_context->request()->url) { $activeClass = $activeClassName; } } $string .= '<li class="dropdown ' . $activeClass . '">' . $this->_context->html->link($title, $url, $options += array('class' => 'dropdown-toggle', 'data-toggle' => 'dropdown')); // sub menu items if (count($sub_items) > 0) { $string .= "\n\t"; $string .= '<ul class="dropdown-menu">'; $string .= "\n"; foreach ($sub_items as $child) { // let any of these do it if ($child == 'separator' || $child == 'spacer' || $child == 'divider') { $string .= '<li class="divider"></li>'; } else { $title = isset($child['title']) && !empty($child['title']) ? $child['title'] : false; $url = isset($child['url']) && !empty($child['url']) ? $child['url'] : false; $options = isset($child['options']) && is_array($child['options']) ? $child['options'] : array(); if ($title && $url) { $string .= "\t\t"; $string .= '<li>' . $this->_context->html->link($title, $url, $options) . '</li>'; $string .= "\n"; } } } $string .= "\t"; $string .= '</ul>'; $string .= "\n"; } $string .= '</li>'; $string .= "\n"; } } $i++; } } $string .= '</ul>'; $string .= "\n"; return $string; }
/** * Tests that routes can be connected and correctly match based on HTTP headers or method verbs. * * @return void */ public function testHttpMethodBasedRouting() { Router::connect('/{:controller}/{:id:[0-9]+}', array('http:method' => 'GET', 'action' => 'view')); Router::connect('/{:controller}/{:id:[0-9]+}', array('http:method' => 'PUT', 'action' => 'edit')); $request = new Request(array('url' => '/posts/13', 'env' => array('REQUEST_METHOD' => 'GET'))); $params = Router::process($request)->params; $expected = array('controller' => 'posts', 'action' => 'view', 'id' => '13'); $this->assertEqual($expected, $params); $this->assertEqual('/posts/13', Router::match($params)); $request = new Request(array('url' => '/posts/13', 'env' => array('REQUEST_METHOD' => 'PUT'))); $params = Router::process($request)->params; $expected = array('controller' => 'posts', 'action' => 'edit', 'id' => '13'); $this->assertEqual($expected, $params); $request = new Request(array('url' => '/posts/13', 'env' => array('REQUEST_METHOD' => 'POST'))); $params = Router::process($request)->params; $this->assertFalse($params); }
/** * Logic to request password reset for user * * @param array $conditions * @return int */ public static function requestPasswordReset(array $conditions = array()) { $self = static::_object(); if ($user = $self::first(compact('conditions'))) { $time = new \DateTime(); $reset = PasswordResets::first(array('conditions' => array('user_id' => $user->id))); if ($reset) { $expires = new \DateTime($reset->expires); if ($expires <= $time) { $reset->delete(); } else { return PasswordResets::RESET_TOKEN_EXISTS; } } if (!$reset || !$reset->exists()) { $expires = clone $time; $expires->modify(LI3_UM_PasswordResetExpires); $token = Token::generate($user->email); $reset = PasswordResets::create(array('user_id' => $user->id, 'expires' => $expires->format('Y-m-d H:i:s'), 'token' => $token)); if ($reset->save()) { $link = Router::match(array('li3_usermanager.Users::resetPassword', 'id' => $user->id, 'token' => $token), $self::$request, array('absolute' => true)); Mailer::$_data['subject'] = 'Your password reset link!'; Mailer::$_data['from'] = LI3_UM_PasswordResetEmailFrom; Mailer::$_data['to'] = $user->email; Mailer::$_data['body'] = 'This is your password reset link:' . "\n" . $link; return PasswordResets::GENERATED_NEW_RESET_TOKEN; } } } }
<?php use lithium\net\http\Router; // Get the current URL (false excludes the domain) $here = $this->html->here(false); ?> <div class="well sidebar-nav"> <ul class="nav nav-list"> <li class="nav-header">All About You</li> <?php $discover_menu_items = $this->bootstrapMenu->static_menu('user', array('return_data' => true)); foreach ($discover_menu_items as $item) { $matched_route = Router::match($item['url']); $active = $matched_route == $here ? 'active' : ''; echo '<li class="' . $active . '">' . $this->html->link($item['title'], $item['url']) . '</li>'; } ?> <li class="nav-header">Discover</li> <?php $discover_menu_items = $this->bootstrapMenu->static_menu('user_discover', array('return_data' => true)); foreach ($discover_menu_items as $item) { $matched_route = Router::match($item['url']); $active = $matched_route == $here ? 'active' : ''; echo '<li class="' . $active . '">' . $this->html->link($item['title'], $item['url']) . '</li>'; } ?> </ul> </div><!--/.well -->
public function testWithWildcardArray() { Router::connect('/add/{:args}', array('controller' => 'tests', 'action' => 'add')); $expected = '/add'; $result = Router::match(array('controller' => 'tests', 'action' => 'add')); $this->assertEqual($expected, $result); $expected = '/add/alke'; $result = Router::match(array('controller' => 'tests', 'action' => 'add', 'args' => array('alke'))); $this->assertEqual($expected, $result); $expected = '/add/alke/php'; $result = Router::match(array('controller' => 'tests', 'action' => 'add', 'args' => array('alke', 'php'))); $this->assertEqual($expected, $result); }
public function testMatchWithScopeAndWithoutController() { Router::scope('app', function () { Router::connect('/{:id}', 'Posts::index'); }); $request = new Request(array('url' => '/1', 'base' => '')); MockDispatcher::run($request); $result = Router::match(array('id' => 2), $request); $this->assertEqual('/2', $result); }
} ?> <?php if ($paypal_config['success_route']) { ?> <input type="hidden" name="return" value="<?php echo Router::match($paypal_config['success_route'], $this->request(), array('absolute' => true)); ?> "> <?php } ?> <?php if ($paypal_config['success_route']) { ?> <input type="hidden" name="cancel_return" value="<?php echo Router::match($paypal_config['cancel_route'], $this->request(), array('absolute' => true)); ?> "> <?php } ?> <input type="hidden" name="no_shipping" value="1"> <input type="hidden" name="no_note" value="1"> <input type="hidden" name="currency_code" value="USD"> <input type="hidden" name="bn" value="AFDC_ShoppingCart_WPS_US"> <button class="btn btn-primary btn-large" type="submit">Proceed to PayPal</button> </form> </div>
/** * Generates different variations of the configured $this->model property name * * If no model is configured (i.e. `null`) - it automatically detects the corresponding * model for this Controller via Inflection and `Libraries::locate()`. * * @see lithium\core\Libraries::locate() * @param string $field defines, what variation of the default you want to have * available are 'class', 'model', 'singular', 'plural' and 'table' and 'human'. * if omitted, returns array containing all of them. * @return array|string **/ protected function _scaffold($field = null) { if (is_null($this->model)) { $this->model = (string) Libraries::locate('models', $this->request->controller); } if (is_null($this->scaffold)) { $class = basename(str_replace('\\', '/', $this->model)); $base = !empty($this->library) ? array('controller' => $this->controller, 'library' => $this->library) : array('controller' => $this->controller); $this->scaffold = array('base' => Router::match($base, $this->request), 'controller' => strtolower($this->controller), 'library' => $this->library, 'class' => $class, 'model' => $this->model, 'slug' => Inflector::underscore($class), 'singular' => Inflector::singularize($class), 'plural' => Inflector::pluralize($class), 'table' => Inflector::tableize($class), 'human' => Inflector::humanize($class)); } if (!is_null($field)) { return isset($this->scaffold[$field]) ? $this->scaffold[$field] : false; } Environment::set(true, array('scaffold' => $this->scaffold)); return $this->scaffold; }
/** * Tests that multiple continuation routes can be applied to the same URL. */ public function testStackedContinuationRoutes() { Router::connect('/admin/{:args}', array('admin' => true), array('continue' => true)); Router::connect('/{:locale:en|de|it|jp}/{:args}', array(), array('continue' => true)); Router::connect('/{:controller}/{:action}/{:id:[0-9]+}', array('id' => null)); $request = new Request(array('url' => '/en/foo/bar/5')); $expected = array('controller' => 'foo', 'action' => 'bar', 'id' => '5', 'locale' => 'en'); $this->assertEqual($expected, Router::process($request)->params); $request = new Request(array('url' => '/admin/foo/bar/5')); $expected = array('controller' => 'foo', 'action' => 'bar', 'id' => '5', 'admin' => true); $this->assertEqual($expected, Router::process($request)->params); $request = new Request(array('url' => '/admin/de/foo/bar/5')); $expected = array('controller' => 'foo', 'action' => 'bar', 'id' => '5', 'locale' => 'de', 'admin' => true); $this->assertEqual($expected, Router::process($request)->params); $request = new Request(array('url' => '/en/admin/foo/bar/5')); $this->assertFalse(Router::process($request)->params); $result = Router::match(array('Foo::bar', 'id' => 5)); $this->assertEqual('/foo/bar/5', $result); $result = Router::match(array('Foo::bar', 'id' => 5, 'admin' => true)); $this->assertEqual('/admin/foo/bar/5', $result); $result = Router::match(array('Foo::bar', 'id' => 5, 'admin' => true, 'locale' => 'jp')); $this->assertEqual('/admin/jp/foo/bar/5', $result); }
/** * Tests that continuations can be used for route suffixes. */ public function testSuffixContinuation() { Router::connect("/{:args}.{:type}", array(), array('continue' => true)); Router::connect('/{:controller}/{:id:[0-9]+}', array('action' => 'view')); $result = Router::match(array('controller' => 'versions', 'action' => 'view', 'id' => 13, 'type' => 'jsonp')); $this->assertEqual('/versions/13.jsonp', $result); $result = Router::match(array('controller' => 'versions', 'action' => 'view', 'id' => 13)); $this->assertEqual('/versions/13', $result); }
Dispatcher::applyFilter('run', function ($self, $params, $chain) { // Do something before $result = $chain->next($self, $params, $chain); // Do something after return $result; }); // Filter GET request Dispatcher::applyFilter('run', function ($self, $params, $chain) { if ($params['request']->method == 'GET') { // Do something before } $result = $chain->next($self, $params, $chain); if ($params['request']->method == 'GET') { // Do something after } return $result; }); // Protect some routes from unauthorized user Dispatcher::applyFilter('run', function ($self, $params, $chain) { // First, define our list of protected actions $blacklist = array('/users/report', '/users/home'); // Inspect the request to get the URL for the route the request matches $matches = in_array(Router::match($params['request']->params, $params['request']), $blacklist); // If this is a match, check it against an Auth configuration. if ($matches && !Auth::check('default', $params['request'])) { // If the Auth check can't verify the user, redirect. return new Response(array('location' => '/users/login')); } // Important: return the results of the next filter in the chain. return $chain->next($self, $params, $chain); });