Skip to content

Commit

Permalink
Added Grav\Framework\Route classes to allow route/link manipulation
Browse files Browse the repository at this point in the history
Added `$grav['uri]->getCurrentRoute()` method to get `Grav\Framework\Route\Route` instance for the current URL
  • Loading branch information
mahagr committed Feb 20, 2018
1 parent 35f7a2a commit 871848d
Show file tree
Hide file tree
Showing 4 changed files with 440 additions and 1 deletion.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

1. [](#new)
* Added `Grav\Framework\Uri` classes extending PSR-7 `HTTP message UriInterface` implementation
* Added `$grav['uri]->getCurrentUri()` function to get `Grav\Framework\Uri` instance for the current URL.
* Added `Grav\Framework\Route` classes to allow route/link manipulation
* Added `$grav['uri]->getCurrentUri()` method to get `Grav\Framework\Uri\Uri` instance for the current URL
* Added `$grav['uri]->getCurrentRoute()` method to get `Grav\Framework\Route\Route` instance for the current URL
* Added ability to have `php` version dependencies in GPM assets
1. [](#bugfix)
* Fixed issue with remote PHP version determination for Grav updates
Expand Down
27 changes: 27 additions & 0 deletions system/src/Grav/Common/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

namespace Grav\Common;

use Grav\Common\Config\Config;
use Grav\Common\Language\Language;
use Grav\Common\Page\Page;
use Grav\Framework\Route\RouteFactory;
use Grav\Framework\Uri\UriFactory;
use Grav\Framework\Uri\UriPartsFilter;

Expand All @@ -19,6 +22,9 @@ class Uri
/** @var \Grav\Framework\Uri\Uri */
protected static $currentUri;

/** @var \Grav\Framework\Route\Route */
protected static $currentRoute;

public $url;

// Uri parts.
Expand Down Expand Up @@ -109,7 +115,10 @@ public function init()
{
$grav = Grav::instance();

/** @var Config $config */
$config = $grav['config'];

/** @var Language $language */
$language = $grav['language'];

// add the port to the base for non-standard ports
Expand Down Expand Up @@ -193,6 +202,9 @@ public function init()
$grav['base_url_absolute'] = $grav['config']->get('system.custom_base_url') ?: $this->rootUrl(true);
$grav['base_url_relative'] = $this->rootUrl(false);
$grav['base_url'] = $grav['config']->get('system.absolute_urls') ? $grav['base_url_absolute'] : $grav['base_url_relative'];

RouteFactory::setRoot($this->root_path);
RouteFactory::setLanguage($language->getLanguageURLPrefix());
}

/**
Expand Down Expand Up @@ -614,6 +626,21 @@ public static function getCurrentUri()
return static::$currentUri;
}

/**
* Returns current route.
*
* @return \Grav\Framework\Route\Route
*/
public static function getCurrentRoute()
{
if (!static::$currentRoute) {
$uri = Grav::instance()['uri'];
static::$currentRoute = RouteFactory::createFromParts($uri->toArray());
}

return static::$currentRoute;
}

/**
* Is this an external URL? if it starts with `http` then yes, else false
*
Expand Down
279 changes: 279 additions & 0 deletions system/src/Grav/Framework/Route/Route.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
<?php
/**
* @package Grav\Framework\Route
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/

namespace Grav\Framework\Route;

use Grav\Framework\Uri\UriFactory;

/**
* Implements Grav Route.
*
* @package Grav\Framework\Route
*/
class Route
{
/** @var string */
private $root = '';

/** @var string */
private $language = '';

/** @var string */
private $route = '';

/** @var array */
private $gravParams = [];

/** @var array */
private $queryParams = [];

/**
* You can use `RouteFactory` functions to create new `Route` objects.
*
* @param array $parts
* @throws \InvalidArgumentException
*/
public function __construct(array $parts = [])
{
$this->initParts($parts);
}

/**
* @return array
*/
public function getParts()
{
return [
'path' => $this->getUriPath(),
'query' => $this->getUriQuery(),
'grav' => [
'root' => $this->root,
'language' => $this->language,
'route' => $this->route,
'grav_params' => $this->gravParams,
'query_params' => $this->queryParams,
],
];
}

/**
* @return string
*/
public function getRootPrefix()
{
return $this->root;
}

/**
* @return string
*/
public function getLanguagePrefix()
{
return $this->language !== '' ? '/' . $this->language : '';
}

/**
* @return string
*/
public function getRoute()
{
return '/' . $this->route;
}

/**
* Return array of both query and Grav parameters.
*
* If a parameter exists in both, prefer Grav parameter.
*
* @return array
*/
public function getParams()
{
return $this->gravParams + $this->queryParams;
}

/**
* @return array
*/
public function getGravParams()
{
return $this->gravParams;
}

/**
* @return array
*/
public function getQueryParams()
{
return $this->queryParams;
}

/**
* Return value of the parameter, looking into both Grav parameters and query parameters.
*
* If the parameter exists in both, return Grav parameter.
*
* @param string $param
* @return string|null
*/
public function getParam($param)
{
$value = $this->getGravParam($param);
if ($value === null) {
$value = $this->getQueryParam($param);
}

return $value;
}

/**
* @param string $param
* @return string|null
*/
public function getGravParam($param)
{
return isset($this->gravParams[$param]) ? $this->gravParams[$param] : null;
}

/**
* @param string $param
* @return string|null
*/
public function getQueryParam($param)
{
return isset($this->queryParams[$param]) ? $this->queryParams[$param] : null;
}

/**
* @param string $param
* @param mixed $value
* @return Route
*/
public function withGravParam($param, $value)
{
return $this->withParam('gravParams', $param, $value);
}

/**
* @param string $param
* @param mixed $value
* @return Route
*/
public function withQueryParam($param, $value)
{
return $this->withParam('queryParams', $param, $value);
}

/**
* @return \Grav\Framework\Uri\Uri
*/
public function getUri()
{
return UriFactory::createFromParts($this->getParts());
}

/**
* @return string
*/
public function __toString()
{
$url = $this->getUriPath();

if ($this->queryParams) {
$url .= '?' . $this->getUriQuery();
}

return $url;
}

/**
* @param string $type
* @param string $param
* @param mixed $value
* @return static
*/
protected function withParam($type, $param, $value)
{
$oldValue = isset($this->{$type}[$param]) ? $this->{$type}[$param] : null;
$newValue = null !== $value ? (string)$value : null;

if ($oldValue === $newValue) {
return $this;
}

$new = clone $this;
if ($newValue === null) {
unset($new->{$type}[$param]);
} else {
$new->{$type}[$param] = $newValue;
}

return $new;
}

/**
* @return string
*/
protected function getUriPath()
{
$parts = [$this->root];

if ($this->language !== '') {
$parts[] = $this->language;
}

if ($this->route !== '') {
$parts[] = $this->route;
}

if ($this->gravParams) {
$parts[] = RouteFactory::buildParams($this->gravParams);
}

return implode('/', $parts);
}

/**
* @return string
*/
protected function getUriQuery()
{
return UriFactory::buildQuery($this->queryParams);
}

/**
* @param array $parts
*/
protected function initParts(array $parts)
{
if (isset($parts['grav'])) {
$gravParts = $parts['grav'];
$this->root = $gravParts['root'];
$this->language = $gravParts['language'];
$this->route = $gravParts['route'];
$this->gravParams = $gravParts['params'];
$this->queryParams = $parts['query_params'];

} else {
$this->root = RouteFactory::getRoot();
$this->language = RouteFactory::getLanguage();

$path = isset($parts['path']) ? $parts['path'] : '/';
if (isset($parts['params'])) {
$this->route = trim(rawurldecode($path), '/');
$this->gravParams = $parts['params'];
} else {
$this->route = trim(RouteFactory::stripParams($path, true), '/');
$this->gravParams = RouteFactory::getParams($path);
}
if (isset($parts['query'])) {
$this->queryParams = UriFactory::parseQuery($parts['query'], true);
}
}
}
}
Loading

0 comments on commit 871848d

Please sign in to comment.