NanoFramework 1.4.0
A tiny PHP Framework
Route.php
Go to the documentation of this file.
1<?php
2
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 $routesContent = file_get_contents($source);
36 $entries = explode(PHP_EOL, $routesContent);
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 if ('' === $uri) {
167 $uri = '/';
168 }
169 $method = strtolower($_SERVER['REQUEST_METHOD']);
170 foreach (self::$specificRoutes as $route => $methods) {
171 $route = preg_replace('/:segment/', '[^/]+', $route);
172 $route = preg_replace('/:any/', '.*', $route);
173 $route = '#^'.$route.'$#';
174
175 if (preg_match($route, $uri)) {
176 if (!array_key_exists($method, $methods)) {
177 return $uri;
178 }
179
180 return preg_replace($route, $methods[$method], $uri);
181 }
182 }
183
184 return $uri;
185 }
186}
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