<?php/** * Lys * * GNU General Public License * * Copyright © 2007 - 2023, Yohann Schwan. All rights reserved. */namespace Lys { class Route { /** * @var array */ protected static $parameters = array(); /** * @args string $name, string $path, array $args = array(), array $keys = array() * @return void */ static function set($name, $path, $args = array(), array $keys = array(), $method = 'POST') { if(empty($path)) { unset(self::$parameters[$name]); # Ok ! return; } if(isset(self::$parameters[$name])) { throw new LogicException('(Route) Unable to redefine route'); } foreach(array_intersect($args, array_keys($keys)) as $k) { throw new LogicException('(Route) Unable to redefine key'); } self::$parameters[$name] = array( 'name' => $name, 'base' => $path, 'base_length' => $pl = strlen($path), 'args' => $args, 'args_separator' => $path[$pl - 1], 'args_size' => count($args), 'keys' => $keys, 'method' => $method ); } /** * @args string $name * @return array */ static function parameters() { return self::$parameters; } /** * @args string $name * @return array */ static function keys() { return array_keys(self::$parameters); } /** * @args string $name * @return array */ static function get($name) { if(isset(self::$parameters[$name])) { return self::$parameters[$name]; } throw new LogicException('(Route) Undefined route: ' . $name); } /** * @args string $name, array $row = array()) * @return string */ static function path($name, array $row = array()) { if(isset(self::$parameters[$name])) { $p = self::$parameters[$name]; } else { return ''; } $q = array(); foreach($p['args'] as $k) { if(isset($row[$k])) { $q[] = rawurlencode($row[$k]); } else { throw new LogicException('(Route) Missing path component: ' . $k); } } return $p['base'] . implode($a = $p['args_separator'], $q);// . (('/' == $a) && !is_empty($q) ? '/' : ''); } /** * @args string $name, array $row = array()) * @return string */ static function uri($name, array $row = array()) { if(isset(self::$parameters[$name])) { $p = self::$parameters[$name]; } else { return ''; } $q = array(); foreach($p['keys'] as $k => $n) { if(isset($row[$k]) && !empty($row[$k])) { $q[$n] = $row[$k]; } } return self::path($name, $row) . (empty($q) ? '' : '?' . http_build_query($q)); } /** * Callback * * @args array $r_1, array $r_2 * @return int */ private static function compare($r_1, $r_2) { if($s = $r_2['base_length'] - $r_1['base_length']) { return $s; } return $r_2['args_size'] - $r_1['args_size']; } /** * @args string $path * @return array */ static function analyse($path) { if(uasort(self::$parameters, array('self', 'compare'))) { foreach(self::$parameters as $n => $r) { if($r['args_size']) { if(($r['base_length'] < strlen($path)) && ($r['base'] == substr($path, 0, $r['base_length']))) { $a = explode($r['args_separator'], substr($path, $r['base_length'])); $last = array_pop($a); if(empty($last)) { # ... } else { $a[] = $last; } if(count($a) == $r['args_size']) { return $r + array( 'vars' => array_combine($r['args'], $a), ); } } } elseif($r['base'] == $path) { return $r + array( 'vars' => array( ), ); } elseif($r['base'] == ($path . '/')) { throw new HttpException('(Route) Return to directory', 301, $r['base']); } } return array(); } throw new LogicException('(Route) Unable to sort routes'); } }}