picea/src/Extension/UrlExtension.php
Dave M 2f8abebc44 - Added a new Include token (which was added as RAW content)
- Fixed UrlExtension to reflect on notes-routes changes
- Added some methods to FileFetcher
2020-10-20 19:38:37 +00:00

206 lines
6.1 KiB
PHP

<?php
namespace Picea\Extension;
use Picea\Compiler\Context;
class UrlExtension implements Extension {
protected string $urlBase;
protected string $assetToken;
protected array $routes;
protected array $routesTarget;
public array $tokens = [ "url" , "route", "asset", "url.parameters" ];
public function __construct(Context $context, string $urlBase = "", string $assetToken = "") {
$this->urlBase = trim($urlBase, "/");
$this->assetToken = $assetToken;
$this->register($context);
}
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : ?string
{
switch($token) {
case "asset":
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->buildAssetUrl($arguments) ?>";
case "route":
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->buildRouteUrl($arguments) ?>";
case "url":
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->buildUrl($arguments) ?>";
case "url.parameters":
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->setUrlParameters($arguments) ?>";
}
return null;
}
public function register(Context $context) : void
{
$context->pushFunction("url", [ $this, 'buildUrl' ]);
$context->pushFunction("asset", [ $this, 'buildAssetUrl' ]);
$context->pushFunction("route", [ $this, 'buildRouteUrl' ]);
}
public function getRouteList(bool $full = false) : array
{
return $this->routes;
}
public function setUrlParameters(string $url = "", array $parameters = []) : string
{
return $url . ( $parameters ? "?" . http_build_query($parameters) : "" );
}
public function buildUrl(string $uri = "", array $parameters = []) : string
{
return $this->setUrlParameters($this->url() . "/" . ltrim($uri, "/"), $parameters);
}
public function buildAssetUrl(string $uri, array $parameters = []) : string
{
return $this->buildUrl($uri, array_replace([ 'v' => $this->assetToken ], $parameters));
}
public function buildRouteUrl(string $name, array $parameters = []) : string
{
if ( false !== ( $route = $this->routes[$name] ?? false ) ) {
return $this->buildUrl($this->prepareRoute($route['route'], $parameters), $parameters);
}
$routeList = json_encode($this->routes, \JSON_PRETTY_PRINT);
throw new \RuntimeException("
Given route `$name` could not be found within current route list:
$routeList
");
}
public function url() : string
{
return $this->scheme() . $this->domain() . $this->base();
}
public function registerRoute(string $name, string $route, string $class, string $method, array $routeMethods) : void
{
$this->routes[$name] = [
'route' => $route,
'routeMethods' => $routeMethods,
'class' => $class,
'classMethod' => $method,
];
}
/**
* Return URI formatted
*/
protected function uri(bool $queryString = false) : string
{
$uri = ( $_SERVER['REQUEST_URI'] ?? $_SERVER['PHP_SELF'] ?? "" ) . ( $queryString ? $this->queryString() : "" );
if ( ! $queryString ) {
$uri = explode('?', $uri, 2)[0];
}
if ( ($base = $this->config['base'] ?? false) && ( stripos($uri, $base) === 0 ) ) {
$uri = substr($uri, strlen($base));
}
return '/' . ltrim($uri, '/');
}
/**
* Return query string
*/
protected function queryString() : string
{
return isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : "";
}
protected function scheme() : string
{
return ( $this->isHttps() ? "https" : "http" ) . "://";
}
protected function base() : string
{
return $this->urlBase ? "/" . $this->urlBase : "";
}
/**
* Check if Uri's segments are valid
* @param array $segments The uri's segments
*/
protected function secure($segments = []) : array
{
return array_diff($segments, [ '..', '://' ]);
}
protected function domain() : string
{
return strtolower($_SERVER['HTTP_HOST']);
}
protected function isDefaultPort() : bool
{
return in_array($_SERVER['SERVER_PORT'], [ 80, 443 ]);
}
protected function isHttps() : bool
{
$header = in_array('https', array_map("strtolower", [
$_SERVER['X-Url-Scheme'] ?? "",
$_SERVER['Front-End-Https'] ?? "",
$_SERVER['X-Forwarded-Ssl'] ?? "",
$_SERVER['X-Forwarded-Proto'] ?? "",
$_SERVER['X-Forwarded-Protocol'] ?? "",
]));
return $header
|| ( "443" === ( $_SERVER['SERVER_PORT'] ?? "" ) )
|| ( "https" === ( $_SERVER['REQUEST_SCHEME'] ?? "http") )
|| ( "off" !== ( strtolower($_SERVER['HTTPS'] ?? "off")) );
}
protected function prepareRoute(string $route, array &$arguments)
{
if ( preg_match_all('~{(.*?)}~si', $route, $matches, PREG_SET_ORDER) ) {
$search = [];
foreach($matches as $item) {
if (strpos($item[1], "=") !== false) {
list($variable, $default) = explode('=', $item[1]);
}
else {
$variable = $item[1];
}
if ( array_key_exists($variable, $arguments) ) {
$value = $arguments[ $item[1] ];
}
else if ( isset($default) ) {
$value = ""; # $default;
}
else {
$variable = $item[1];
}
$search[ $item[0] ] = $value;
unset($arguments[ $item[1] ]);
}
$route = str_replace(array_keys($search), array_values($search), $route);
}
return $route;
}
}