[regression] route defaults are now automatically route parameters

Created on 5 May 2023, over 1 year ago
Updated 12 June 2023, over 1 year ago

Follow-up to #3277784 πŸ› copyRawVariables should support default route parameters Fixed , related to #3352384 ✨ Add Exception for TypeError Argument must be String in \Drupal\Component\Utility\Html escape{} Needs work

Problem/Motivation

#3277784 πŸ› copyRawVariables should support default route parameters Fixed introduced this with commit a894a04b:

    // Route defaults that do not start with a leading "_" are also
    // parameters, even if they are not included in path or host patterns.
    foreach ($route->getDefaults() as $name => $value) {
      if (!isset($raw_variables[$name]) && substr($name, 0, 1) !== '_') {
        $raw_variables[$name] = $value;
      }
    }

Route parameters, however, might end up in TitleResolver, which is pulling all route parameters considering them safe as translation arguments:

if (($raw_parameters = $request->attributes->get('_raw_variables'))) {
  foreach ($raw_parameters->all() as $key => $value) {
    $args['@' . $key] = $value ?? '';
    $args['%' . $key] = $value ?? '';
  }
}

and

$route_title = $this->t($title, $args, $options);

So route defaults are now required to be scalars, as otherwise t() fails with a TypeError.
However (@larowlan):

I think default arguments can totally be arrays and as such that automagic '@arg' '%arg' should be checking if $value is a scalar - i.e. that sounds like a bug in TitleResolver in my book

This hit e.g. the CiviCRM module which defined a route default args being an array.

Steps to reproduce

You can reproduce the issue with Drupal 9.5.9 by declaring a new Route object with an array in its default argument, e.g.

in a module's modulename.routing.yml:

route_callbacks:
  - '\Drupal\modulename\Routing\Routes::getRoutes'

in the module's src/Routing/Routes.php:

class Routes {
  public function getRoutes() {
    $route_collection = new \Symfony\Component\Routing\RouteCollection();
    return $route_collection->add('/my-path', [
      '_title' => 'Page Title',
      '_controller' => 'Drupal\modulename\Controller\ModuleController:run',
      'my_default_arg' => ['some' => 'array'],
    ]);
    return $route_collection;
  }
}

Proposed resolution

TitleResolver should check for route parameters being a scalar before copying them as translation arguments:

if (($raw_parameters = $request->attributes->get('_raw_variables'))) {
  foreach ($raw_parameters->all() as $key => $value) {
    if (is_scalar($value) {
      $args['@' . $key] = $value ?? '';
      $args['%' . $key] = $value ?? '';
    }
  }
}

or variables cast-able to string (while that might not make sense for all types).

πŸ› Bug report
Status

Fixed

Version

9.5

Component
BaseΒ  β†’

Last updated about 3 hours ago

Created by

πŸ‡©πŸ‡ͺGermany jensschuppe

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024