Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Change matching method in ShopContextSubscriber#39837

Merged
kpodemski merged 18 commits into
PrestaShop:9.1.xfrom
djbuch:patch-69
May 26, 2026
Merged

Change matching method in ShopContextSubscriber#39837
kpodemski merged 18 commits into
PrestaShop:9.1.xfrom
djbuch:patch-69

Conversation

@djbuch
Copy link
Copy Markdown
Contributor

@djbuch djbuch commented Oct 26, 2025

Questions Answers
Branch? develop
Description? Fixed routing issue where using match() instead of matchRequest() caused the full Request object not to be passed to the router. This resulted in Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait generating a "pseudo" request without headers, breaking route conditions that rely on request properties (e.g., request.isXmlHttpRequest() on the admin_emails_send_test route).
Type? bug fix
Category? CO
BC breaks? no
Deprecations? no
How to test? 1. Navigate to the email configuration page in the Back Office in a multishop environment
2. Try to send a test email using the AJAX request
3. Verify that the request is properly handled and the isXmlHttpRequest() condition is correctly evaluated
4. Check that routes with request-based conditions (like header checks) work as expected
UI Tests 🟢 https://github.com/Codencode/ga.tests.ui.pr/actions/runs/26416354197
Fixed issue or discussion? #37572, #39991
Related PRs
Sponsor company Web Premiere

@djbuch djbuch requested a review from a team as a code owner October 26, 2025 08:55
@github-project-automation github-project-automation Bot moved this to Ready for review in PR Dashboard Oct 26, 2025
@ps-jarvis ps-jarvis added develop Branch Bug fix Type: Bug fix labels Oct 26, 2025
@Progi1984 Progi1984 linked an issue Oct 26, 2025 that may be closed by this pull request
2 tasks
@Codencode
Copy link
Copy Markdown
Contributor

Codencode commented Nov 19, 2025

Hi @djbuch,
your solution has a few issues, do you think you can fix them?
I'm asking because I wanted to test it and see if we can include it directly in the 9.0.x branch.

[Edit]
I ran a test - if you restore the $router parameter to what it was before, meaning you declare it as Symfony\Component\Routing\RouterInterface, the issue should be resolved and your solution should work.

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

Hello, I made the change you said, let's wait and see the check results.

[Edit]
But I think we will have a problem since RouterInterface doesn't define matchRequest but this is the core change needed in this bug fix

@Codencode
Copy link
Copy Markdown
Contributor

Hello, I made the change you said, let's wait and see the check results.

[Edit] But I think we will have a problem since RouterInterface doesn't define matchRequest but this is the core change needed in this bug fix

Okay, even though I tested it quickly locally and it works, let's wait for the tests to be sure/safe

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

Yes the PHPStan tests failed

Error: Call to an undefined method Symfony\Component\Routing\RouterInterface::matchRequest().


Line src/PrestaShopBundle/EventListener/Admin/Context/ShopContextSubscriber.php


365 Call to an undefined method
Symfony\Component\Routing\RouterInterface::matchRequest().

@Codencode
Copy link
Copy Markdown
Contributor

@djbuch
Okay, sorry 🙏, you're right, that's clear.

You could try it this way:
Reset the type of the $router parameter to Symfony\Component\Routing\Router
and then here

PrestaShopBundle\EventListener\Admin\Context\ShopContextSubscriber: ~

you can replace PrestaShopBundle\EventListener\Admin\Context\ShopContextSubscriber: ~ with:

  PrestaShopBundle\EventListener\Admin\Context\ShopContextSubscriber:
    autowire: true
    autoconfigure: true
    arguments:
      $router: '@router'

Let's check if it doesn't throw an error anymore, and then we'll ask the others for confirmation too.

@kpodemski
Copy link
Copy Markdown
Contributor

Hello

I checked the problem, and the code below helped:

$controller = $request->attributes->get('_controller');
if (!$controller || !str_contains($controller, '::')) {
    return null;
}

Could you guys check?

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

@kpodemski where should this code go ?

@kpodemski
Copy link
Copy Markdown
Contributor

kpodemski commented Nov 20, 2025

@djbuch
image

I haven't tested other bugs that were reported by @Codencode, I've only tested sending emails :)

If that works, then it also requires removing RouterInterface and adapting tests if needed

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

But the problem here is in the matching of the route. Because of "request.isXmlHttpRequest()" in the route definition.

@kpodemski
Copy link
Copy Markdown
Contributor

@djbuch I'm not sure about that, to me the problem was a mismatch in the route. After applying the changes I don't have any errors mentioned by @Codencode

@Codencode
Copy link
Copy Markdown
Contributor

@djbuch image

I haven't tested other bugs that were reported by @Codencode, I've only tested sending emails :)

If that works, then it also requires removing RouterInterface and adapting tests if needed

@kpodemski this solution works, I tested it for the cases that were causing issues and it's ok.
@djbuch it's also less impactful, I would take it into consideration!

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

@kpodemski yes but the missmatch is because of request.isXmlHttpRequest(), with your code we just don't get the ShopContext from the route.

But the route exists, it is defined so it should be found. You can see that if you remove the condition request.isXmlHttpRequest() on the route definition the original code works, but this is the problem if we want the condition ton work we need to pass all the request to the match, not only a mocked request as it is done with ->match($request->getPathInfo())

[EDIT] : Did you try it in multishop context ?

@kpodemski
Copy link
Copy Markdown
Contributor

@djbuch

[EDIT] : Did you try it in multishop context ?

Of course, it worked for me w/o multistore enabled. It didn't after enabling multi-store, it showed me that the URL doesn't exist.

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

OK and are you shure that with your code the good shop context is loaded ?

@kpodemski
Copy link
Copy Markdown
Contributor

@djbuch checking

@kpodemski
Copy link
Copy Markdown
Contributor

@djbuch I'm testing sending emails, I've set a different data in the single and all stores context, I managed to correctly receive the email for the corresponding inboxes

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

And what if you don't send this through XmlHttpRequest ? Because the whole this is about this condition in route definition.

If it is not needed for security reasons, then we could remove it from the conditions.

@Codencode
Copy link
Copy Markdown
Contributor

And what if you don't send this through XmlHttpRequest ? Because the whole this is about this condition in route definition.

If it is not needed for security reasons, then we could remove it from the conditions.

If we remove it from the route definition, we then have to add the check in the controller method. This was the solution I thought of, which you can find here: #39991

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

Yes but with my solution the condition works

@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented Nov 20, 2025

@Codencode it is always false because ->match($request->getPathInfo()) will recreate a mocked request with the info about XmlHttpRequest missing, but with ->matchRequest($request) it works

@Codencode
Copy link
Copy Markdown
Contributor

Yes but with my solution the condition works

Ah ok, I didn't realize it was in addition to your solution.

@kpodemski
Copy link
Copy Markdown
Contributor

kpodemski commented Nov 20, 2025

@djbuch @Codencode

ok, thanks for the info

let's ping @jolelievre to see his opinion as well, not relying on the interface is not a clean way, but on the other hand, creating an adapter like some RouterMatcher is probably too much

@kpodemski
Copy link
Copy Markdown
Contributor

kpodemski commented Nov 20, 2025

@djbuch

Well, I've checked, and route conditions in rhe route listener are checked before our subscriber, so when I do the POST directly, it shows me:

No route found for "POST http://prestashop9.test/admin-dev/index.php/configure/advanced/emails/send-testing-email" (from "http://prestashop9.test/admin-dev/index.php/configure/advanced/emails/

When I remove the condition:
{"errors":[]}

It returns me JSON response :)

private readonly ShopConfigurationInterface $configuration,
private readonly MultistoreFeature $multistoreFeature,
private readonly RouterInterface $router,
private readonly Router $router,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be able to replace this with RequestMatcherInterface the interface that implements the method you need. And the @router service correctly implements it

As much as possible we should favor using interfaces instead of explicit classes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello I already tried that : 4228f42 but the check failed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok tried again and with forcing the argument this time, let's see

Comment on lines +62 to +66
PrestaShopBundle\EventListener\Admin\Context\ShopContextSubscriber:
autowire: true
autoconfigure: true
arguments:
$router: '@router'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autowire and autoconfigure are already set as default values on this file (at the top of the file), so in theory you don't need to change this service definition

The autowiring should also be able to automatically inject the @router service (also check my other comment about using the appropriate interface) If by lack of chance the DI doesn't inject the service you expect to you can at most limit this modifications to only the arguments part

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jolelievre
Hi Jonathan,
If we don't pass the $router: '@router' parameter to the service, we get this error:

Cannot autowire service "PrestaShopBundle\EventListener\Admin\Context\ShopContextSubscriber": argument 
"$router" of method "__construct()" references class "Symfony\Component\Routing\Router" but no such service exists. 
Try changing the type-hint to one of its parents: interface "Symfony\Component\Routing\RouterInterface", interface 
"Symfony\Component\Routing\RequestContextAwareInterface", interface "Symfony\Component\Routing\Generator\UrlGeneratorInterface", 
or interface "Symfony\Component\Routing\Matcher\UrlMatcherInterface".

So apparently, the system can't inject Symfony\Component\Routing\Router, which is why I suggested modifying the service definition.

You're absolutely right that we can avoid re-adding autowire and autoconfigure - I was the one who led @djbuch to make that mistake.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, tried without, and I need the arguments part. But as it is written for some other Services forcing arguments in the file I think I should keep

autowire: true
autoconfigure: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok my bad, let's go with then

@Codencode Codencode requested a review from a team as a code owner May 25, 2026 19:17
@Codencode Codencode changed the base branch from develop to 9.1.x May 25, 2026 19:18
@github-actions github-actions Bot modified the milestones: 9.2.0, 9.1.4 May 25, 2026
@ps-jarvis ps-jarvis moved this from Waiting for author to Need 2nd approval in PR Dashboard May 25, 2026
@Codencode Codencode requested review from jolelievre and kpodemski May 25, 2026 19:29
@Codencode
Copy link
Copy Markdown
Contributor

@kpodemski @djbuch

since the PR was stuck on rebase for a while, I went ahead and did it myself.

@Codencode
Copy link
Copy Markdown
Contributor

Codencode commented May 25, 2026

@kpodemski @jolelievre I ran the test and the PR works correctly.

We're now waiting for the UI tests that were created from scratch because I performed the rebase, and obviously the second approval is still missing.

c/c @SiraDIOP

screen-capture.webm

@Codencode Codencode closed this May 26, 2026
@github-project-automation github-project-automation Bot moved this from Need 2nd approval to Closed in PR Dashboard May 26, 2026
@Codencode Codencode reopened this May 26, 2026
@github-project-automation github-project-automation Bot moved this from Closed to Reopened in PR Dashboard May 26, 2026
@Codencode
Copy link
Copy Markdown
Contributor

Codencode commented May 26, 2026

@kpodemski kpodemski added QA ✔️ Status: check done, code approved QA ✔️ by Community Check done, code approved by community member and removed Waiting for author Status: action required, waiting for author feedback labels May 26, 2026
@ps-jarvis ps-jarvis added the Waiting for QA Status: action required, waiting for test feedback label May 26, 2026
@kpodemski kpodemski merged commit 7693541 into PrestaShop:9.1.x May 26, 2026
48 checks passed
@github-project-automation github-project-automation Bot moved this from Reopened to Merged in PR Dashboard May 26, 2026
@ps-jarvis ps-jarvis moved this from Merged to To be tested in PR Dashboard May 26, 2026
@ps-jarvis ps-jarvis moved this from To be tested to Merged in PR Dashboard May 26, 2026
@kpodemski
Copy link
Copy Markdown
Contributor

thank you @djbuch @Codencode

@kpodemski kpodemski removed the Waiting for QA Status: action required, waiting for test feedback label May 26, 2026
@djbuch
Copy link
Copy Markdown
Contributor Author

djbuch commented May 26, 2026 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug fix Type: Bug fix develop Branch QA ✔️ by Community Check done, code approved by community member QA ✔️ Status: check done, code approved Topwatchers Backlog prioritization: issue reported & followed by +6 people

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

Multistore - Send test email doesn't work

7 participants