NanoFramework 1.5.2
A tiny PHP Framework
Loading...
Searching...
No Matches
Route.php
Go to the documentation of this file.
1<?php
2
3namespace SteeveDroz\NanoFramework;
4
10abstract class Route
11{
15 protected static $namespace = 'App';
16
20 protected static $specificRoutes = [];
21
29 public static function load(string $source): void
30 {
31 if (!file_exists($source)) {
32 return;
33 }
34
35 $entries = file($source, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
36
37 foreach ($entries as $line) {
38 $line = preg_replace('/#.*$/', '', $line);
39 $elements = [];
40 preg_match('/^\s*([a-z][a-z,]+[a-z]):\s*([^\s]+)\s*->\s*([^\s]+)\s*$/', $line, $elements);
41 if (count($elements) > 3) {
42 $methods = explode(',', $elements[1]);
43 $route = [];
44 foreach ($methods as $method) {
45 $method = strtolower($method);
46 if ('get' == $method || 'all' == $method) {
47 $route['get'] = $elements[3];
48 }
49 if ('post' == $method || 'all' == $method) {
50 $route['post'] = $elements[3];
51 }
52 if ('put' == $method || 'all' == $method) {
53 $route['put'] = $elements[3];
54 }
55 if ('delete' == $method || 'all' == $method) {
56 $route['delete'] = $elements[3];
57 }
58 }
59 if (!array_key_exists($elements[2], self::$specificRoutes)) {
60 self::$specificRoutes[$elements[2]] = [];
61 }
62 self::$specificRoutes[$elements[2]] = array_merge(self::$specificRoutes[$elements[2]], $route);
63 }
64 }
65 }
66
72 public static function setNamespace(string $namespace)
73 {
74 self::$namespace = $namespace;
75 }
76
82 public static function getNamespace(): string
83 {
84 return self::$namespace;
85 }
86
92 public static function getSpecificRoutes(): array
93 {
94 return unserialize(serialize(self::$specificRoutes));
95 }
96
104 public static function display(): void
105 {
106 session_start();
107 $protocol = array_key_exists('HTTPS', $_SERVER) && 'on' === $_SERVER['HTTPS'] ? 'https://' : 'http://';
108 $fullUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
109 $siteUrl = DotEnv::getEnv('SITE_URL');
110 if (null !== $siteUrl && 0 === strpos($fullUrl, $siteUrl)) {
111 $uri = substr($fullUrl, strlen($siteUrl));
112 } else {
113 $uri = $_SERVER['REQUEST_URI'];
114 }
115 $uri = self::getUri($uri);
116 $parts = array_filter(explode('/', $uri), 'strlen');
117
118 try {
119 $className = '\\' . self::$namespace . '\\Controllers\\' . ucfirst(array_shift($parts));
120 $class = new $className();
121 $method = array_shift($parts) ?? 'index';
122
123 call_user_func_array([$class, $method], $parts);
124 } catch (\SteeveDroz\NanoFramework\Exceptions\RedirectException $e) {
125 if (preg_match('#^https?://#', $e->getMessage())) {
126 header('Location: ' . $e->getMessage());
127 } else {
128 header('Location: ' . $siteUrl . $e->getMessage());
129 }
130 } catch (\SteeveDroz\NanoFramework\Exceptions\Error404Exception $e) {
131 }
132 }
133
137 public static function analyzeError(\Error $e)
138 {
139 $recognizedMessages = [
140 'Class \'\\App\\Controllers\Home\' not found',
141 'Class "\\App\\Controllers\Home" not found',
142 ];
143 if (in_array($e->getMessage(), $recognizedMessages)) {
144 echo '<h1>NanoFramework recognizes that error and knows how to fix it.</h1>' . PHP_EOL;
145 echo '<ol>' . PHP_EOL;
146 echo '<li>' . PHP_EOL;
147 echo '<ul>' . PHP_EOL;
148 echo '<li>If you did not edit your <code>composer.json</code> file, simply run <code>vendor/bin/nano-generate composer</code> from the command line and confirm with <code>y</code>.</li>' . PHP_EOL;
149 echo '<li>If you did edit <code>composer.json</code>, add this code in the file instead:<code><pre>"autoload": {' . PHP_EOL . ' "psr-4": {' . PHP_EOL . ' "App\\\\": "app"' . PHP_EOL . ' }' . PHP_EOL . '}</pre></code></li>' . PHP_EOL;
150 echo '</ul>' . PHP_EOL;
151 echo '</li>' . PHP_EOL;
152 echo '<li>After that, run <code>composer dumpautoload</code>.</li>' . PHP_EOL;
153 echo '</ol>' . PHP_EOL;
154 }
155 }
156
164 protected static function getUri(string $uri): string
165 {
166 $uri = explode('?', $uri)[0];
167
168 if ('' === $uri) {
169 $uri = '/';
170 }
171 $method = strtolower($_SERVER['REQUEST_METHOD']);
172 foreach (self::$specificRoutes as $route => $methods) {
173 $route = preg_replace('/:segment/', '[^/]+', $route);
174 $route = preg_replace('/:any/', '.*', $route);
175 $route = '#^' . $route . '$#';
176
177 if (preg_match($route, $uri)) {
178 if (!array_key_exists($method, $methods)) {
179 return $uri;
180 }
181
182 return preg_replace($route, $methods[$method], $uri);
183 }
184 }
185
186 return $uri;
187 }
188}
static getEnv(string $key)
Definition DotEnv.php:74
Maps the URIs to the Controllers.
Definition Route.php:11
static analyzeError(\Error $e)
Definition Route.php:137
static getUri(string $uri)
Definition Route.php:164
static load(string $source)
Definition Route.php:29
static setNamespace(string $namespace)
Definition Route.php:72