Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can not create links from routes with optional parameters #46

Closed
mimmi20 opened this issue Aug 4, 2020 · 5 comments
Closed

Can not create links from routes with optional parameters #46

mimmi20 opened this issue Aug 4, 2020 · 5 comments

Comments

@mimmi20
Copy link

mimmi20 commented Aug 4, 2020

Bug Report

Q A
Version mezzio/mezzio 3.2.2
Version laminas/laminas-router 3.3.2
PHP 7.2.31

Summary

Current behavior

Actually I have an Zend MVC Application with the following routing:

return [
    'routes' => [
        'wizard' => [
            'type' => Segment::class,
            'options' => [
                'route'    => '/wizard/[:embed/]:id/:sessionId',
                'constraints' => [
                    'id'    => '[1-9][0-9]*',
                    'embed' => 'embed',
                ],
                'defaults' => [
                    'controller' => Controller\IndexController::class,
                    'id'         => 1,
                ],
            ],
        ]

I'm using this call to generate an Uri in a view script:

$this->url('wizard', ['id' => 1, 'embed' => null, 'sessionId' => 'os09t2ujphehcbvp7nr7fgs5ei'])

The generated Uri is "/wizard/1/os09t2ujphehcbvp7nr7fgs5ei".

I'm trying to rewrite that Application to an Mezzio Application.

The new Route configuration is:

$wizardRoute = $app->post(
        '/wizard/[:embed/]:id/:sessionId',
        [
            MandantHandler::class,
            SessionMiddleware::class,
            StartFormHandler::class,
        ],
        'wizard'
    );

    $wizardRoute->setOptions(
        [
            'constraints' => [
                'id'    => '[1-9][0-9]*',
                'embed' => 'embed',
            ],
            'defaults' => [
                'id' => 1,
                'embed' => '', // <-- this is nessesary to get this working
            ],
        ]
    );

The new Call in a view script has to be:

$this->url('wizard', ['id' => 2, 'embed' => '', 'sessionId' => '2d5d501b4a0f1d8caa171258e8821a54'])

The generated Uri is now "/wizard//2/2d5d501b4a0f1d8caa171258e8821a54". (With double Slash)

If I set the "embed" parameter to null or don't set default, I get this Exception:

Laminas\Router\Exception\InvalidArgumentException thrown with message "Missing parameter "embed""

Stacktrace:
#63 Laminas\Router\Exception\InvalidArgumentException in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:310
#62 Laminas\Router\Http\Segment:buildPath in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:329
#61 Laminas\Router\Http\Segment:buildPath in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Segment.php:424
#60 Laminas\Router\Http\Segment:assemble in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/Part.php:208
#59 Laminas\Router\Http\Part:assemble in /home/developer/projects/mezzio/vendor/laminas/laminas-router/src/Http/TreeRouteStack.php:371
#58 Laminas\Router\Http\TreeRouteStack:assemble in /home/developer/projects/mezzio/vendor/mezzio/mezzio-laminasrouter/src/LaminasRouter.php:128
#57 Mezzio\Router\LaminasRouter:generateUri in /home/developer/projects/mezzio/vendor/mezzio/mezzio-helpers/src/UrlHelper.php:106
#56 Mezzio\Helper\UrlHelper:__invoke in /home/developer/projects/mezzio/vendor/mezzio/mezzio-helpers/src/UrlHelper.php:129
#55 Mezzio\Helper\UrlHelper:generate in /home/developer/projects/mezzio/vendor/mezzio/mezzio-laminasviewrenderer/src/UrlHelper.php:47
...
#2 Laminas\HttpHandlerRunner\RequestHandlerRunner:run in /home/developer/projects/mezzio/vendor/mezzio/mezzio/src/Application.php:82
#1 Mezzio\Application:run in /home/developer/projects/mezzio/public/index.php:29
#0 {closure} in /home/developer/projects/mezzio/public/index.php:30

How to reproduce

Expected behavior

It is possible to set an optional Parameter to null and the Parameter is not in the generated Uri.

@weierophinney
Copy link
Contributor

The problem is that you have an optional segment followed by required segments. This has always had problematic behavior, and we do not recommend it.

Instead, create two separate routes, one that does not have the :embed segment, and one that has it as a required segment.

@mimmi20
Copy link
Author

mimmi20 commented Aug 5, 2020

Instead, create two separate routes

In our project we have in summary 9 routes with this optional Parameter. We had duplicated routes before for some of them, until we found out in Zend MVC does this kind of routing work. Our problem with duplicated routes was, that we forget often to change the second one.

@mimmi20 mimmi20 closed this as completed Oct 18, 2021
@jscssphtml
Copy link

Please leave this open. This happens also for routing without any non-optional postfixes....

We have a very simple route defined: (this is just a extension of the skeleton app)

$app->get('/[:projectId]', App\Handler\HomePageHandler::class, 'home');

With the same result during building the url:

Laminas\Router\Exception\InvalidArgumentException thrown with message "Missing parameter "projectId""

We have researched a little bit on this and found out, that the "name" parameter is added to the options here:
https://github.com/mezzio/mezzio-laminasrouter/blob/3.8.x/src/LaminasRouter.php#L118

Which results in the options parameter "has_child" parameter here:
https://github.com/laminas/laminas-router/blob/3.10.x/src/Http/Part.php#L202

Which than results in this invalid argument exception:
https://github.com/laminas/laminas-router/blob/3.10.x/src/Http/Segment.php#L329

@Ocramius
Copy link
Member

@jscssphtml new issue, perhaps with test case, would be nice

@boesing
Copy link
Member

boesing commented Nov 28, 2022

I guess that this issue is better placed in https://github.com/mezzio/mezzio-laminasrouter as that seems to be a specific laminas-router issue rather than a mezzio issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants