hnrazevedo /
Router
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types = 1); |
||
| 4 | |||
| 5 | namespace HnrAzevedo\Router; |
||
| 6 | |||
| 7 | use HnrAzevedo\Http\Uri; |
||
| 8 | |||
| 9 | final class Router implements RouterInterface |
||
| 10 | { |
||
| 11 | use DefinitionsTrait, |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 12 | RunInTrait, |
||
| 13 | CheckTrait, |
||
| 14 | OwnerTrait, |
||
| 15 | MiddlewareTrait, |
||
| 16 | WhereTrait, |
||
| 17 | PrioritizeTrait, |
||
| 18 | CurrentTrait, |
||
| 19 | AttributeTrait; |
||
| 20 | |||
| 21 | private array $groupsName = []; |
||
| 22 | private ?\Exception $error = null; |
||
| 23 | |||
| 24 | public static function name(string $name): Router |
||
| 25 | { |
||
| 26 | self::getInstance()->existRouteName($name); |
||
| 27 | $route = self::getInstance()->inSave(); |
||
| 28 | $route['name'] = $name; |
||
| 29 | self::getInstance()->routesName[$name] = $name; |
||
| 30 | self::getInstance()->unsetRoute(array_key_last(self::getInstance()->getRoutes()))->updateRoute($route, $name); |
||
| 31 | return self::getInstance(); |
||
| 32 | } |
||
| 33 | |||
| 34 | public static function attribute(string $name, $value = null) |
||
| 35 | { |
||
| 36 | $route = self::getInstance()->inSave(); |
||
| 37 | |||
| 38 | if(null === $value) { |
||
| 39 | return (isset($route['attributes'][$name])) ? $route['attributes'][$name] : null; |
||
| 40 | } |
||
| 41 | |||
| 42 | self::getInstance()->throwCallable($value); |
||
| 43 | $route['attributes'][$name] = $value; |
||
| 44 | self::getInstance()->updateRoute($route, array_key_last(self::getInstance()->getRoutes())); |
||
| 45 | return self::getInstance(); |
||
| 46 | } |
||
| 47 | |||
| 48 | public static function groupAttribute(string $name, $value = null, ?array $excepts = []): Router |
||
| 49 | { |
||
| 50 | $group = self::getInstance()->inSave()['group']; |
||
| 51 | foreach(self::getInstance()->getRoutes() as $r => $route){ |
||
| 52 | if($route['group'] !== $group || in_array($route['name'], $excepts)) { |
||
| 53 | continue; |
||
| 54 | } |
||
| 55 | |||
| 56 | $route['attributes'] = array_merge([$name => $value], $route['attributes']); |
||
| 57 | self::getInstance()->updateRoute($route, $r); |
||
| 58 | } |
||
| 59 | return self::getInstance(); |
||
| 60 | } |
||
| 61 | |||
| 62 | public static function group(string $prefix, \Closure $closure): Router |
||
| 63 | { |
||
| 64 | $id = sha1(date('d/m/Y h:m:i')); |
||
| 65 | while(array_key_exists($id, self::getInstance()->groupsName)){ |
||
| 66 | $id = sha1(date('d/m/Y h:m:i').$id); |
||
| 67 | } |
||
| 68 | |||
| 69 | self::getInstance()->groupsName[$id] = $id; |
||
| 70 | |||
| 71 | self::getInstance()->setPrefix($prefix); |
||
| 72 | |||
| 73 | self::getInstance()->setGroup($id); |
||
| 74 | |||
| 75 | $closure(); |
||
| 76 | |||
| 77 | self::getInstance()->setGroup(null); |
||
| 78 | self::getInstance()->setPrefix(''); |
||
| 79 | return self::getInstance(); |
||
| 80 | } |
||
| 81 | |||
| 82 | public static function load(?string $name = null): RouterInterface |
||
| 83 | { |
||
| 84 | self::getInstance()->loaded = true; |
||
| 85 | |||
| 86 | if(null !== $name) { |
||
| 87 | return self::getInstance()->loadByName($name); |
||
| 88 | } |
||
| 89 | |||
| 90 | self::loadPipeline(); |
||
| 91 | |||
| 92 | self::getInstance()->sortRoutes(); |
||
| 93 | |||
| 94 | $requestMethod = (isset($_REQUEST['REQUEST_METHOD'])) ? $_REQUEST['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']; |
||
| 95 | |||
| 96 | foreach(self::getInstance()->getRoutes() as $r => $route){ |
||
| 97 | self::getInstance()->currentRoute = $route; |
||
| 98 | self::getInstance()->currentRoute['name'] = $r; |
||
| 99 | |||
| 100 | try{ |
||
| 101 | self::getInstance()->checkMethod($route, $requestMethod); |
||
| 102 | self::getInstance()->checkData($route, (new Uri($_SERVER['REQUEST_URI']))->getPath()); |
||
| 103 | return self::getInstance(); |
||
| 104 | }catch(\Exception $er){ |
||
| 105 | continue; |
||
| 106 | } |
||
| 107 | } |
||
| 108 | |||
| 109 | self::getInstance()->currentRoute = []; |
||
| 110 | |||
| 111 | self::getInstance()->error = new \Exception('Not found', 404); |
||
| 112 | |||
| 113 | return self::getInstance(); |
||
| 114 | } |
||
| 115 | |||
| 116 | public static function run(?string $name = null): RouterInterface |
||
| 117 | { |
||
| 118 | if(!self::getInstance()->loaded) { |
||
| 119 | self::getInstance()->load($name); |
||
| 120 | } |
||
| 121 | |||
| 122 | self::getInstance()->checkError(); |
||
| 123 | |||
| 124 | self::getInstance()->handleMiddlewares(); |
||
| 125 | |||
| 126 | self::getInstance()->executeBefore(); |
||
| 127 | |||
| 128 | try{ |
||
| 129 | $action = unserialize(self::getInstance()->current()['action']); |
||
| 130 | self::getInstance()->executeRouteAction((is_string($action)) ? $action : $action->getClosure()); |
||
| 131 | }catch(\Exception $er){ |
||
| 132 | self::getInstance()->error = $er; |
||
| 133 | } |
||
| 134 | |||
| 135 | self::getInstance()->executeAfter(); |
||
| 136 | |||
| 137 | self::getInstance()->checkError(); |
||
| 138 | |||
| 139 | return self::getInstance(); |
||
| 140 | } |
||
| 141 | |||
| 142 | private function checkError(): void |
||
| 143 | { |
||
| 144 | if(isset($this->error)) { |
||
| 145 | throw $this->error; |
||
| 146 | } |
||
| 147 | } |
||
| 148 | |||
| 149 | private function loadByName(string $name): RouterInterface |
||
| 150 | { |
||
| 151 | $this->hasRouteName($name); |
||
| 152 | $this->currentRoute = $this->getRoutes()[$name]; |
||
| 153 | return $this; |
||
| 154 | } |
||
| 155 | |||
| 156 | public static function routes(?array $routes = null): array |
||
| 157 | { |
||
| 158 | if(null !== $routes) { |
||
| 159 | self::getInstance()->setRoutes($routes); |
||
| 160 | self::getInstance()->sortRoutes(); |
||
| 161 | } |
||
| 162 | return self::getInstance()->routes; |
||
| 163 | } |
||
| 164 | |||
| 165 | public static function getAttribute(string $name): Mixed |
||
| 166 | { |
||
| 167 | return (array_key_exists($name, Router::current()['attributes'])) ? Router::current()['attributes'][$name] : null; |
||
| 168 | } |
||
| 169 | |||
| 170 | public static function getAttributes(): array |
||
| 171 | { |
||
| 172 | return Router::current()['attributes']; |
||
| 173 | } |
||
| 174 | |||
| 175 | } |
||
| 176 |