Skip to content

Remove unnecessary controller $lang arguments caused by positional route parameter binding while preserving configurable lang.url_segment #543

Description

@armanist

Summary

Refactor route parameter dispatch so controller actions no longer need explicit unused $lang arguments just to preserve parameter ordering when multilingual URL segments are enabled.

The framework should continue to support configurable language detection through lang.url_segment, and $lang should remain available when an action explicitly requests it, but controller and generated template action signatures should no longer be forced to include it as positional boilerplate.

Why

The project already supports configurable language detection from the URL through lang.url_segment, for example:

return [
    'enabled' => true,
    'supported' => ['en', 'es'],
    'default' => 'en',
    'url_segment' => 1,
];

Current language detection is already handled at the framework level through the request/route flow and LangFactory.

However, many DemoWeb and DemoApi controller actions still need to declare unused parameters such as:

public function post(Request $request, ?string $lang, string $postUuid): Response

or:

public function delete(?string $lang, string $uuid): Response

This is not because the action needs direct access to the current language. It happens because:

  • multilingual routes prepend an optional URL segment such as [:alpha:2]?
  • unnamed route segments are compiled into positional route params such as _segment0
  • scalar action arguments are currently resolved positionally during dispatch
  • later real route parameters such as uuid are therefore shifted unless the action reserves a placeholder argument for the language segment

As a result, the current multilingual route setup leaks framework routing mechanics into controller method signatures.

Goal

Preserve configurable multilingual URL segment handling while removing the need for fake/unused $lang parameters in controller actions and generated templates.

At the same time, if an action explicitly requests $lang, it should still be available intentionally rather than disappearing completely from action injection.

Proposed Direction

Refactor routing/dispatch behavior so the configured language URL segment is treated as framework-owned route context rather than a normal positional controller argument.

The implementation should preserve:

  • lang.url_segment
  • current language detection behavior
  • current_lang() usage
  • existing multilingual URL behavior

But it should stop forcing controller actions to declare unused $lang parameters solely to keep later route parameters aligned.

If an action explicitly declares string $lang or ?string $lang, the current language should still be available through intentional injection rather than positional leakage.

Examples

Current undesired pattern:

public function post(Request $request, ?string $lang, string $postUuid): Response
{
    // $lang is unused
}

Desired common behavior:

public function post(Request $request, string $postUuid): Response
{
}

Desired explicit access when needed:

public function post(Request $request, ?string $lang, string $postUuid): Response
{
    // $lang is intentionally requested here
}

Current language access should also continue to work through framework state such as:

current_lang()

Acceptance Criteria

  • configurable lang.url_segment behavior remains supported
  • current language detection from URL segments continues to work
  • controller actions no longer need unused $lang arguments solely because of multilingual route parameter ordering
  • if an action explicitly requests $lang, it remains available intentionally
  • generated DemoWeb and DemoApi controller signatures can be simplified accordingly
  • the routing/dispatch change does not break ordinary non-language route parameters such as uuid, token, or code
  • tests cover multilingual route matching and controller argument resolution with configured language URL segments

Notes

Relevant code:

  • src/Router/PatternCompiler.php
  • src/Router/RouteDispatcher.php
  • src/Di/DiContainer.php
  • src/Lang/Factories/LangFactory.php
  • src/Module/Templates/DemoWeb/src/routes/routes.php.tpl
  • src/Module/Templates/DemoApi/src/routes/routes.php.tpl
  • DemoWeb and DemoApi controller templates containing unused $lang arguments

Metadata

Metadata

Assignees

No one assigned

    Labels

    langLanguage and translation packageroutingRouting and route resolution

    Type

    No fields configured for Bug.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions