craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.21k stars 624 forks source link

Named parameter regex Url Rule causes query string params to be ignored #2062

Closed khalwat closed 6 years ago

khalwat commented 6 years ago

Craft 3 beta 29:

If I have a named parameter regex rule like this:

Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_SITE_URL_RULES, function (RegisterUrlRulesEvent $event) {
    $event->rules = array_merge($event->rules, [
        'instantanalytics/pageViewTrack/<filename:[-\w\.*]+>?' => 'instant-analytics/track/track-page-view-url',
        'instantanalytics/eventTrack/<filename:[-\w\.*]+>?' => 'instant-analytics/track/track-event-view-url',
    ]);
});

Which will route URLs like this:

http://craft3.dev/instantanalytics/pageViewTrack/woof.jpg?url=woof.jpg&title=some+title

To my controller action:

/**
 * @param string $url
 * @param string $title
 */
public function actionTrackPageViewUrl(string $url, string $title)
{
    $analytics = InstantAnalytics::$plugin->ia->pageViewAnalytics($url, $title);
    $analytics->sendPageView();
    $response = Craft::$app->getResponse();
    $response->redirect($url, 200);
}

What seems to happen is only the filename param is sent in, and we get an error like this:

google chromescreensnapz007

Stack trace:

1. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/web/Controller.php at line 149
2. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/base/InlineAction.php at line 51 – yii\web\Controller::bindActionParams(yii\base\InlineAction, [])
3. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/base/Controller.php at line 156 – yii\base\InlineAction::runWithParams(['filename' => 'woof.jpg'])
4. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/base/Module.php at line 523 – yii\base\Controller::runAction('track-page-view-url', ['filename' => 'woof.jpg'])
5. in /home/vagrant/webdev/craft/craft/src/web/Application.php at line 242 – yii\base\Module::runAction('instant-analytics/track/track-pa...', ['filename' => 'woof.jpg'])
6. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/web/Application.php at line 102 – craft\web\Application::runAction('instant-analytics/track/track-pa...', ['filename' => 'woof.jpg'])
7. in /home/vagrant/webdev/craft/craft/src/web/Application.php at line 207 – yii\web\Application::handleRequest(craft\web\Request)
8. in /home/vagrant/sites/craft3/vendor/yiisoft/yii2/base/Application.php at line 380 – craft\web\Application::handleRequest(craft\web\Request)
9. in /home/vagrant/sites/craft3/web/index.php at line 25 – yii\base\Application::run()

^ so we can see that filename is being passed in alone to ::runAction()

The odd thing is if I remove that named parameter regex from the url rule, it all works fine.

Also if I do something like this in my controller action:

public function actionTrackPageViewUrl()
{
    $request = Craft::$app->getRequest();
    $url = $request->getParam('url');
    $title = $request->getParam('title');
    $analytics = InstantAnalytics::$plugin->ia->pageViewAnalytics($url, $title);
    $analytics->sendPageView();
    $response = Craft::$app->getResponse();
    $response->redirect($url, 200);
}

Then it works fine as well, even with the named parameter regex in the mix.

To me, it seems like what happens is if there are no named parameter regex's in my Url Rule, it turns the query string parameters into named parameters, and everything works fine.

But if there are any named parameters in my Url Rule, then it passes those into the controller, and ignores any query string parameters entirely.

khalwat commented 6 years ago

PEBCAK