1
0
www.mikescher.com/www/internals/ruleengine.php

114 lines
2.8 KiB
PHP
Raw Permalink Normal View History

2020-01-14 22:25:43 +01:00
<?php
2020-01-13 14:39:35 +01:00
require_once "website.php";
class RuleEngine
{
/**
2020-01-15 01:46:31 +01:00
* @param Website $site
2020-01-13 14:39:35 +01:00
* @param array $urlConfig
* @return URLRoute
*/
2020-01-15 01:46:31 +01:00
public static function findRoute(Website $site, array $urlConfig): URLRoute
2020-01-13 14:39:35 +01:00
{
2020-01-15 01:46:31 +01:00
if ($site->isProd())
2020-01-13 14:39:35 +01:00
$requri = $_SERVER['REQUEST_URI'];
else
$requri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'localhost:80/';
$parse = parse_url($requri);
$path = isset($parse['path']) ? $parse['path'] : '';
2022-10-15 16:56:50 +02:00
$pathparts = preg_split('@/@', $path, -1, PREG_SPLIT_NO_EMPTY);
2020-01-13 14:39:35 +01:00
$partcount = count($pathparts);
foreach ($urlConfig as $rule)
{
2020-01-15 01:46:31 +01:00
$route = self::testRule($site, $rule, $requri, $pathparts, $partcount);
2020-01-13 14:39:35 +01:00
if ($route === null) continue;
2020-01-15 01:46:31 +01:00
if ($route->needsAdminLogin && !$site->isLoggedInByCookie()) return URLRoute::getLoginRoute($route, $requri);
return $route;
2020-01-13 14:39:35 +01:00
}
return URLRoute::getNotFoundRoute($requri);
}
2020-01-15 01:46:31 +01:00
private static function testRule(Website $site, array $rule, string $requri, array $pathparts, int $partcount)
2020-01-13 14:39:35 +01:00
{
if ($partcount !== count($rule['url'])) return null;
$urlparams = [];
$match = true;
for($i = 0; $i < $partcount; $i++)
{
$comp = $rule['url'][$i];
if (startsWith($comp, '?{') && endsWith($comp, '}'))
{
$ident = substr($comp, 2, strlen($comp)-3);
$urlparams[$ident] = $pathparts[$i];
}
else if ($comp === '*')
{
if (!isset($urlparams['*'])) $urlparams['*'] = [];
$urlparams['*'] []= $pathparts[$i];
}
else
{
if (strtolower($comp) !== strtolower($pathparts[$i])) { $match = false; break; }
}
}
if (!$match) return null;
$route = new URLRoute($rule['target'], $requri);
foreach($rule['parameter'] as $optname => $optvalue)
{
$value = $optvalue;
if ($value === '%GET%')
{
if (!isset($_GET[$optname])) { $match = false; break; }
$value = $_GET[$optname];
}
else if ($value === '%POST%')
{
if (!isset($_POST[$optname])) { $match = false; break; }
$value = $_POST[$optname];
}
else if ($value === '%URL%')
{
if (!isset($urlparams[$optname])) { $match = false; break; }
$value = urldecode($urlparams[$optname]);
}
$route->parameter[strtolower($optname)] = $value;
}
if (!$match) return null;
2020-01-16 13:21:14 +01:00
$route->urlParameter = $urlparams;
2020-01-13 14:39:35 +01:00
$ctrlOpt = $rule['options'];
if (in_array('disabled', $ctrlOpt)) return null;
if (in_array('api', $ctrlOpt)) $route->isAPI = true;
if (isset($ctrlOpt['method']) && $_SERVER["REQUEST_METHOD"] !== $ctrlOpt['method']) return null;
$route->needsAdminLogin = in_array('password', $ctrlOpt);
2020-01-13 14:39:35 +01:00
2020-01-15 01:46:31 +01:00
if ($site->isProd() && isHTTPRequest() && !in_array('http', $ctrlOpt))
2020-01-13 14:39:35 +01:00
{
// enforce https
$redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
return $route;
}
}