├── .gitignore
├── phpunit.xml
├── composer.json
├── LICENSE.md
├── README.md
└── src
└── RoutesPublisherCommand.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | composer.lock
4 | .DS_Store
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | ./tests/
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "themsaid/laravel-routes-publisher",
3 | "description": "A command to replace deprecated Route::controller with explicit routes.",
4 | "keywords": ["laravel", "routes"],
5 | "homepage": "https://github.com/themsaid/laravel-routes-publisher",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Mohamed Said",
10 | "email": "theMohamedSaid@gmail.com"
11 | }
12 | ],
13 | "require": {
14 | "php": ">=5.5.9",
15 | "illuminate/support": "^5.2"
16 | },
17 | "autoload": {
18 | "psr-4": {
19 | "Themsaid\\RoutesPublisher\\": "src"
20 | }
21 | },
22 | "extra": {
23 | "laravel": {
24 | "providers": [
25 | "Themsaid\\RoutesPublisher\\RoutesPublisherCommand"
26 | ]
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Mohamed Said
4 |
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Routes Publisher
2 |
3 | A command to replace deprecated `Route::controller()` and `Route::controllers()` with explicit routes.
4 |
5 | 
6 |
7 | In laravel 5.3 implicit controller routes will be removed from the framework, the functionality will likely be extracted into a separate
8 | package, however if you'd like to make the move and start using explicit routes this package will help you.
9 |
10 | # Installation
11 |
12 | #### Step 1:
13 |
14 | ```
15 | composer require themsaid/laravel-routes-publisher
16 | ```
17 |
18 | #### Step 2:
19 |
20 | Include the following command in your `$commands` attribute of `app/Console/Kernel.php`:
21 |
22 | ```
23 | \Themsaid\RoutesPublisher\RoutesPublisherCommand::class
24 | ```
25 |
26 | # Usage
27 |
28 | Run the following command:
29 |
30 | ```
31 | php artisan themsaid:publishRoutes
32 | ```
33 |
34 | After the command is done, two new files will be generated in your `app/Http` directory:
35 |
36 | ```
37 | routes.php.generated
38 | routes.php.backup
39 | ```
40 |
41 | Replace the content of your `routes.php` file with that of `routes.php.generated`, knowing that if anything went wrong a backup
42 | of your original `routes.php`'s content will be available in `routes.php.backup`.
43 |
44 | #### This package assumes the following:
45 |
46 | - Your `routes.php` doesn't contain any PHP syntax errors.
47 | - Your `routes.php` file is located in `app\Http\routes.php` with the exact name.
48 | - Your `routes.php` files doesn't include any other file using `include` or `require`.
49 | - Your Application namespace is correctly registered in the psr-4 section of `composer.json`.
50 |
51 | # Problems?
52 | I tried hard to cover different syntax and file formatting in this package, however if you found any problems while using the
53 | package please [open a new issue](https://github.com/themsaid/laravel-routes-publisher/issues/new).
--------------------------------------------------------------------------------
/src/RoutesPublisherCommand.php:
--------------------------------------------------------------------------------
1 | controllersNamespace = $application->getNamespace().$this->controllersNamespace;
52 | }
53 |
54 | /**
55 | * Execute the console command.
56 | *
57 | * @return mixed
58 | */
59 | public function handle()
60 | {
61 | $exactFileContent = file_get_contents(base_path($this->routesFilePath));
62 |
63 | $preparedFileContent = $this->prepareFileContent($exactFileContent);
64 |
65 | $output = '';
66 |
67 | foreach (explode("\n", $preparedFileContent) as $line) {
68 | $preparedLine = $this->prepareLine($line);
69 |
70 | if (preg_match('/controller(?:[^s\(]*)\(([^,]*),([^,)]*)/', $preparedLine, $matches)) {
71 | if (count($matches) != 3) {
72 | $this->error($preparedLine.' Looks weird, unable to parse it.');
73 | }
74 |
75 | preg_match('/^( *)/', $line, $spaces);
76 |
77 | $output .= $this->extractController(trim($matches[1], '\''), trim($matches[2], '\''), $spaces[1]);
78 | } elseif (preg_match('/controllers(?:[^\(]*)\((.*)\)/', $preparedLine, $matches)) {
79 | preg_match('/^( *)/', $line, $spaces);
80 |
81 | $output .= $this->extractControllers($matches[1], $spaces[1]);
82 | } else {
83 | $output .= $line."\n";
84 | }
85 | }
86 |
87 | file_put_contents(base_path($this->routesFilePath . '.generated'), $output);
88 |
89 | file_put_contents(base_path($this->routesFilePath . '.backup'), $preparedFileContent);
90 |
91 | $this->info('Done! Generated file was published in "'.base_path($this->routesFilePath . '.generated').'"');
92 |
93 | $this->info('Also a backup of '. basename('$this->routesFilePath') .' was published in "'.base_path($this->routesFilePath . '.backup').'"');
94 | }
95 |
96 | /**
97 | * Prepare file content for parsing.
98 | *
99 | * @param string $fileContent
100 | *
101 | * @return string
102 | */
103 | private function prepareFileContent($fileContent)
104 | {
105 | // Remove 1 line comments
106 | $fileContent = preg_replace("#(.*)//(.*)#", " ", $fileContent);
107 |
108 | // Remove multi-line comments
109 | $fileContent = preg_replace("#/\*(.*)\*?/#", "", $fileContent);
110 |
111 | // Remove all new line characters
112 | $fileContent = preg_replace("/\n*/", "", $fileContent);
113 |
114 | // Add 2 new line characters after [\'"]([^\'"]*)[\'"]/', $arrayString, $matches);
150 |
151 | $routes = '';
152 |
153 | foreach (array_combine($matches[1], $matches[2]) as $path => $controller) {
154 | $routes .= $this->extractController($path, $controller, $initialSpace);
155 | }
156 |
157 | return $routes;
158 | }
159 |
160 | /**
161 | * Extract routes from a given controller
162 | *
163 | * @param string $path
164 | * @param string $controller
165 | *
166 | * @param string $initialSpace
167 | *
168 | * @return string
169 | */
170 | private function extractController($path, $controller, $initialSpace = '')
171 | {
172 | $class = new ReflectionClass($this->controllersNamespace.'\\'.$controller);
173 |
174 | $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
175 |
176 | $routables = array_filter($methods, function ($method) {
177 | return
178 | $method->class != 'Illuminate\Routing\Controller' &&
179 | Str::startsWith($method->name, ['any', 'get', 'post', 'put', 'delete', 'patch']);
180 | });
181 |
182 | $routes = "\n$initialSpace// $controller\n";
183 |
184 | foreach ($routables as $routable) {
185 | $routes .= $initialSpace.$this->createRoute($routable, $path, $controller);
186 | }
187 |
188 | return $routes;
189 | }
190 |
191 | /**
192 | * @param ReflectionMethod $routable
193 | * @param string $path
194 | * @param string $controller
195 | *
196 | * @return string
197 | */
198 | private function createRoute(ReflectionMethod $routable, $path, $controller)
199 | {
200 | $verb = $this->getVerb($routable->name);
201 |
202 | $uri = $this->getUri($routable, $path);
203 |
204 | return 'Route::'."$verb('$uri', '$controller@{$routable->name}');\n";
205 | }
206 |
207 | /**
208 | * Get the verb of the route from name.
209 | *
210 | * @param string $name
211 | *
212 | * @return string
213 | */
214 | public function getVerb($name)
215 | {
216 | return head(explode('_', Str::snake($name)));
217 | }
218 |
219 | /**
220 | * Determine the URI from the given method name.
221 | *
222 | * @param ReflectionMethod $routable
223 | * @param string $path
224 | *
225 | * @return string
226 | */
227 | public function getUri(ReflectionMethod $routable, $path)
228 | {
229 | $uri =
230 | $path
231 | .'/'
232 | .implode('-', array_slice(explode('_', Str::snake($routable->name)), 1))
233 | .'/'
234 | .$this->getWildcards($routable);
235 |
236 | $uri = str_replace('//', '/', $uri);
237 |
238 | $uri = rtrim($uri, '/');
239 |
240 | if (Str::endsWith($uri, 'index')) {
241 | $uri = Str::replaceLast('index', '', $uri);
242 | }
243 |
244 | return $uri;
245 | }
246 |
247 | /**
248 | * Get the wildcards string for the route URI.
249 | *
250 | * @param ReflectionMethod $routable
251 | *
252 | * @return string
253 | */
254 | private function getWildcards(ReflectionMethod $routable)
255 | {
256 | $output = '';
257 |
258 | foreach ($routable->getParameters() as $parameter) {
259 | if ($parameter->hasType()) {
260 | continue;
261 | }
262 |
263 | $wildCard = Str::snake($parameter->getName()).($parameter->isDefaultValueAvailable() ? '?' : '');
264 |
265 | $output .= '{'.$wildCard.'}/';
266 | }
267 |
268 | return $output;
269 | }
270 | }
271 |
--------------------------------------------------------------------------------