# Alternative for deprecated Router::getRouteCollection()-\>parse()

**URL:** <https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816>\
**Category:** Need Help\
**Created:** [January 21, 2024, 12:53pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816 "2024-01-21T12:53:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![samclauw](https://avatars.discourse-cdn.com/v4/letter/s/a5b964/32.png) [@samclauw](https://discourse.cakephp.org/u/samclauw)\
**Post date:** [January 21, 2024, 12:53pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/1 "2024-01-21T12:53:00Z")

</div>

Hi all!

When I use this code in CakePHP 4.5.2.:

> Router::getRouteCollection()-\>parse(‘/nl/blog/categories’);

I get a deprecation error:

> **Deprecated** : 4.5.0 - Use parseRequest() instead. A:\Projects\cms\src\Controller\AppController.php, line: 291

Does anybody know the alternative for transfering a random URL (not the current url) to get this output:

> [  
> ‘pass’ =\> ,  
> ‘action’ =\> ‘overview’,  
> ‘controller’ =\> ‘Categories’,  
> ‘plugin’ =\> ‘Blog’,  
> ‘language’ =\> ‘nl’,  
> ‘\_route’ =\> object(Cake\Routing\Route\DashedRoute) id:0 { },  
> ‘\_matchedRoute’ =\> ‘/nl/blog/categorieen’,  
> ]

The most important is that I can get the action, controller, plugin, … out of the output.  
I tried a couple of things, this is one of them:

```auto
$testRequest = new ServerRequest('/nl/blog/categories');
$test2 = Router::parseRequest($testRequest);

```

Apparently, I can’t add a string to [the ServerRequest object](https://api.cakephp.org/4.0/class-Cake.Http.ServerRequest.html), while the documentation says it should: ‘You can supply the data as either an array or as a string.’

I wonder if this is a good approach. Maybe somebody can help me?  
Thanks in advance!

Cheers,  
Sam

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [January 21, 2024, 1:05pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/2 "2024-01-21T13:05:36Z")

</div>

```auto
$request = new ServerRequest(['url' => $url]);
$route = Router::parseRequest($request);

```

should be fine.

---

<div class="post-metadata">

**Author:** ![samclauw](https://avatars.discourse-cdn.com/v4/letter/s/a5b964/32.png) [@samclauw](https://discourse.cakephp.org/u/samclauw)\
**Post date:** [January 21, 2024, 1:35pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/3 "2024-01-21T13:35:04Z")

</div>

Thanks for your reply @KevinPfeifer! I tried this code before, but the problem is dat it outputs the data of the current request and not the data of the given url string. Here’s my try like you suggested:

```auto
$testRequest = new ServerRequest(['url' => '/nl/blog/categorieen']);
$testRoute = Router::parseRequest($testRequest);

debug($testRoute);

```

And this is the output when I debug the ‘$testRoute’-variable on my contact page:

> [  
> ‘pass’ =\> ,  
> ‘controller’ =\> ‘Contact’,  
> ‘action’ =\> ‘index’,  
> ‘language’ =\> ‘nl’,  
> ‘plugin’ =\> null,  
> ‘\_route’ =\> object(Cake\Routing\Route\DashedRoute) id:0 { },  
> ‘\_matchedRoute’ =\> ‘/nl/contact’,  
> ]

So it looks like the ‘url’-parameter in the new ServerRequest object is ignored 😕

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [January 21, 2024, 2:12pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/4 "2024-01-21T14:12:31Z")

</div>

I can’t confirm this

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/cakephp/original/2X/1/140fee80a0dab0c2c78750731627a24dae05672f.jpeg)

---

<div class="post-metadata">

**Author:** ![samclauw](https://avatars.discourse-cdn.com/v4/letter/s/a5b964/32.png) [@samclauw](https://discourse.cakephp.org/u/samclauw)\
**Post date:** [January 21, 2024, 6:05pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/5 "2024-01-21T18:05:38Z")

</div>

@KevinPfeifer very strange! What CakePHP 4 version do you have?  
Here’s my attempt that doesn’t work:

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/cakephp/original/2X/8/8976312ed918a4d50c5127f7b8f51d6f899d14d2.png)

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [January 21, 2024, 6:25pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/6 "2024-01-21T18:25:13Z")

</div>

I tested it with current CakePHP 5.0.4 but now I also just quickly spun up a CakePHP 4.5.3 and it works as I described.

BUT do you use fallback routes in your router? I mean [this line](https://github.com/cakephp/app/blob/5.x/config/routes.php#L78)

Or are you certain that this specific URL is mapped in your router?

---

<div class="post-metadata">

**Author:** ![samclauw](https://avatars.discourse-cdn.com/v4/letter/s/a5b964/32.png) [@samclauw](https://discourse.cakephp.org/u/samclauw)\
**Post date:** [January 23, 2024, 6:27pm UTC](https://discourse.cakephp.org/t/alternative-for-deprecated-router-getroutecollection-parse/11816/7 "2024-01-23T18:27:35Z")

</div>

Hi @KevinPfeifer,

Thanks for the additional tests! It’s good to know that there’s no bug in the CakePhp 4 core.

I’ll show you all my related code. This is my default routes.php:

````auto
<?php
/**
 * Routes configuration.
 *
 * In this file, you set up routes to your controllers and their actions.
 * Routes are very important mechanism that allows you to freely connect
 * different URLs to chosen controllers and their actions (functions).
 *
 * It's loaded within the context of `Application::routes()` method which
 * receives a `RouteBuilder` instance `$routes` as method argument.
 *
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link https://cakephp.org CakePHP(tm) Project
 * @license https://opensource.org/licenses/mit-license.php MIT License
 */

use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;

return static function (RouteBuilder $routes) {
    /*
     * The default class to use for all routes
     *
     * The following route classes are supplied with CakePHP and are appropriate
     * to set as the default:
     *
     * - Route
     * - InflectedRoute
     * - DashedRoute
     *
     * If no call is made to `Router::defaultRouteClass()`, the class used is
     * `Route` (`Cake\Routing\Route\Route`)
     *
     * Note that `Route` does not do any inflections on URLs which will result in
     * inconsistently cased URLs when used with `:plugin`, `:controller` and
     * `:action` markers.
     */
    $routes->setRouteClass(DashedRoute::class);

    $routes->scope('/', function (RouteBuilder $root) {
        $root->setExtensions(['json']);

        $root->prefix('Admin', function (RouteBuilder $admin) {
            $admin->redirect(
                '/',
                ['controller' => 'Users', 'action' => 'index'],
                ['persist' => true]
            );

            /*$admin->scope('/articles', ['plugin' => 'Blog'], function (RouteBuilder $blog) { // deze moet nog veranderen
                $blog->fallbacks(DashedRoute::class);
            });*/
            
            $admin->fallbacks(DashedRoute::class);
        });

        $root->scope('/nl', ['language' => 'nl'], function (RouteBuilder $language) {
            $language->connect(
                '/contact',
                ['controller' => 'Contact', 'action' => 'index']
            );

            $language->connect(
                '/albums/album-{id}',
                ['controller' => 'Albums', 'action' => 'index']
            )->setPatterns(['id' => '[0-9]+']
            )->setPass(['id']);

            $language->connect(
                '/{slug}',
                ['controller' => 'Pages', 'action' => 'detail']
            )->setPatterns(['slug' => '[0-9a-zA-Z-]+']
            )->setPass(['slug']);

            $language->connect(
                '/',
                ['controller' => 'Home', 'action' => 'index']
            );
        });

        /*
         * Here, we are connecting '/' (base path) to a controller called 'Pages',
         * its action called 'display', and we pass a param to select the view file
         * to use (in this case, templates/Pages/home.php)...
         */
        $root->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

        /*
         * ...and connect the rest of 'Pages' controller's URLs.
         */
        //$builder->connect('/pages/*', 'Pages::display');

        /*
         * Connect catchall routes for all controllers.
         *
         * The `fallbacks` method is a shortcut for
         *
         * ```
         * $builder->connect('/:controller', ['action' => 'index']);
         * $builder->connect('/:controller/:action/*', []);
         * ```
         *
         * You can remove these routes once you've connected the
         * routes you want in your application.
         */
        $root->fallbacks();
    });

    /*
     * If you need a different set of middleware or none at all,
     * open new scope and define routes there.
     *
     * ```
     * $routes->scope('/api', function (RouteBuilder $builder) {
     * // No $builder->applyMiddleware() here.
     *
     * // Parse specified extensions from URLs
     * // $builder->setExtensions(['json', 'xml']);
     *
     * // Connect API actions here.
     * });
     * ```
     */
};

````

I have also a routes.php in my plugin (‘/plugins\Blog’):

```auto
<?php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;

return static function (Cake\Routing\RouteBuilder $routes) {
    $routes->scope('/', function (RouteBuilder $root) {
        $root->prefix('Admin', function (RouteBuilder $admin) { // hier er nog voor zorgen dat er niet 2x 'articles' in de slug staat ('/admin/articles/articles')
            $admin->plugin('Blog', ['path' => '/articles'], function ($articles) {
                $articles->fallbacks(DashedRoute::class);
            });
            /*$admin->scope('/articles', ['plugin' => 'Blog'], function (RouteBuilder $blog) { // deze moet nog veranderen
                $blog->fallbacks(DashedRoute::class);
            });*/
            
            //$admin->fallbacks(DashedRoute::class);
        });

        $root->scope('/nl', ['language' => 'nl'], function (RouteBuilder $language) { // Met de tweede parameter zorg je dat 'language' ook in de request zit.
            $language->scope('/blog', ['plugin' => 'Blog'], function (RouteBuilder $blog) {
                $blog->connect(
                    '/',
                    ['controller' => 'Articles', 'action' => 'overview']
                );

                $blog->connect(
                    '/{slug}',
                    ['controller' => 'Articles', 'action' => 'detail']
                )->setPatterns(['slug' => '[0-9a-zA-Z-]+']
                )->setPass(['slug']);

                $blog->scope('/categorieen', ['controller' => 'Categories'], function (RouteBuilder $categories) {
                    $categories->connect(
                        '/',
                        ['action' => 'overview']
                    );

                    $categories->connect(
                        '/{slugs}',
                        ['action' => 'detail']
                    )->setPatterns(['slugs' => '[\/0-9a-zA-Z-]+']
                    )->setPass(['slugs']);
                });

                $blog->connect(
                    '/tags/{slug}',
                    ['controller' => 'Tags', 'action' => 'detail']
                )->setPatterns(['slug' => '[0-9a-zA-Z-]+']
                )->setPass(['slug']);
            });

            $language->connect(
                '/{slug}',
                ['controller' => 'Pages', 'action' => 'index']
            )->setPatterns(['slug' => '[0-9a-zA-Z-]+']
            )->setPass(['slug']);
        });
    });
};

```

As you can see, the fallbacks line is included in the default route.php:

`$root->fallbacks();`

I’m also pretty sure thet the URL is mapped on the router. I see the right page when it’s in the address bar:

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/cakephp/original/2X/8/8cb0fadfae6d1cbc22c169ff948e21d666a99e25.png)

Another fact is that this deprecated code works for me:

```auto
$test = Router::getRouteCollection()->parse('/nl/blog/categorieen');
debug($test);

```

The last code outputs the right data:

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/cakephp/original/2X/6/6042793c416093d5b1a20deb288d7656534d6c9b.png)

I’ll dive further in the route.php code. Fingers crossed I found what I’m doing wrong.  
Unless you know another possibility? 😅
