Problem/Motivation

Following #2807743: Switch from deprecation notice to warning for non-standard placeholders in FormattableMarkup::placeholderFormat() we now get deprecation messages at 9.1 when placeholders do not have a required prefix character. However, it seems that there are valid situations where placeholder prefixes are not required, and cases where the placeholder name has to be a specific string without any prefix, such as in the $context array.

See Rules issue #3172046: [10] Fix automated test results - Support for keys without a placeholder prefix is deprecated (Rules) comments #3 and #4 for more details.

Proposed resolution

Investigate whether the current criteria for determining the placeholders is too strict and produces deprecation warnings that cannot be resolved or corrected.

Remaining tasks

Issue fork drupal-3173103

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jonathan1055 created an issue. See original summary.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

larowlan’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: +Bug Smash Initiative

Is this still relevant?

aludescher’s picture

Yes, still relevant.
LoggerChannel adds some placeholders without prefix in the keys which are than reported as deprecated by Formattablemarkup.

This causes error: "Support for keys without a placeholder prefix is deprecated in Drupal 9.1.0 ...".
But if '@uid' parameter is also set the error will be "Invalid placeholder (%s) with string: ...".

aludescher’s picture

This patch is just a basic workaround!

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

tr’s picture

Priority: Normal » Major
Status: Postponed (maintainer needs more info) » Active

This has become a much bigger problem, because this now generates a warning when running D10 (see #3295625: Remove deprecated code from FormattableMarkup), causing test failures.

I discuss in #3172046: [10] Fix automated test results - Support for keys without a placeholder prefix is deprecated (Rules) why this core behavior is wrong:

I looked at this a bit and my impression is that this is a false positive caused by the difference between PSR-3 logging used by Symfony and Drupal logging. The former uses different placeholders and has different parameters, and Drupal core performs some gymnastics to bend its logging into the shape required for Symfony.

For example, the Symfony log($level, $message, array $context = []) requires that $message is a string with PSR-3 placeholders, and $context is an array of placeholder replacements and other things. While Drupal logging (e.g. the messenger service) requires a message string to be either a plain string or a FormattableMarkup object created by t($message, array $placehoders), but specifically there is no separate argument for placeholders.

It's those "other things" in $context that are causing a problem - they are not being passed as placeholders, but as additional data needed by the logger at a different point in the code. Thus they don't have prefixes like placeholders do, and they shouldn't need prefixes. It seems to me that the deprecation notice is being a little too aggressive when checking prefixes, because it's assuming everything in $context is a placeholder when that's not true.

Drupal does have a compatibility layer, which we use already. See for example this code in RulesLog:

     // Convert PSR3-style messages to \Drupal\Component\Render\FormattableMarkup
    // style, so they can be translated at runtime.
    $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context);

There may be a workaround to avoid this deprecation notice by artificially renaming some of the keys in the $context array so that they look like placeholder keys, but that's not something I'm interested in investigating right now.

additionally mentioned in that issue:

From https://api.drupal.org/api/drupal/vendor%21psr%21log%21Psr%21Log%21Logge...

The context array can contain arbitrary data. The only assumption that can be made by implementors is that if an Exception instance is given to produce a stack trace, it MUST be in a key named "exception".

So in this case, the Symfony specification clearly states that $context is not used just for Drupal placeholders, meaning the keys do not have to conform to Drupal placeholder key names with prefix.

And specifically in some cases you MUST use a key named "exception", which would also trigger the above deprecation notice.

This strengthens my initial impression that this deprecation is a false positive in our case, caused by Drupal core being too aggressive at identifying what is a placeholder. So if I were going to work on this (which I'm not, at the moment), the way I would approach it is to investigate that core Drupal deprecation notice with the intention of rolling a patch for core to remove the assumption about the contents of the $context array.

Note since the time I originally posted this api.drupal.org has stopped hosting the API doc page for the Symfony LoggerInterface, so you'll have to find that on your own ...

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

tolstoydotcom’s picture

I tried to duplicate this on D11 and it worked as expected, without warnings. What's a snippet that shows the problem?

\Drupal::logger('test')->info('test is @test', ['@test' => 'test', 'test' => 'test']);
\Drupal::logger('test')->log(1, 'test2 is @test', ['@test' => 'test', 'test' => 'test']);
prabuela’s picture

Assigned: Unassigned » prabuela
prabuela’s picture

Assigned: prabuela » Unassigned
tolstoydotcom’s picture

I was able to see warnings by following the instructions at #3347741: D10 "Invalid placeholder (context) with string" error

The merge request I added to this issue only calls trigger_error if a key starts with a non-alphanumeric character. A key of context wouldn't cause a warning, but *context would.

j.’s picture

Am i missing something? i see the issue fork, but no merge request/patch to test.

tolstoydotcom’s picture

I might have done the merge request wrong, but the only file I changed is this:

https://git.drupalcode.org/issue/drupal-3173103/-/blob/3173103-false-pos...

I don't think that has changed much between versions so you can probably just post it into a D10/D11 installation.

Or, click 'Show commands' above and follow those instructions.

j.’s picture

Thanks TolstoyDotCom. I'm using views_conditional and have been having issues with this (https://www.drupal.org/project/views_conditional/issues/3347741#comment-...), but can confirm that the changes in #15 stop the error messages that were flooding the logs. For the record, the site is using 10.0.10 and views_conditional 1.5.

tobas1996’s picture

#17 I created the MR, now you can put just the .diff :

https://git.drupalcode.org/project/drupal/-/merge_requests/4528.diff

Thanks!

j.’s picture

Thanks. patch applied cleanly to 10.1.2

boby_ui’s picture

+1 patch works well for 10.1.2

tolstoydotcom’s picture

Please note that the patch from #8 and my changes in #15 are different, mine is a more generalized solution.

I've since changed core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php to deal with the changes to core/lib/Drupal/Component/Render/FormattableMarkup.php. Hopefully that will cause the test to succeed. If anyone has any ideas for other tests please let me know.

tolstoydotcom’s picture

Status: Active » Needs review

Is #15 a reasonable solution or does anyone have a better way to do this?

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new108.73 KB

Nice addition of ctype_alnum.

Lets see what committers say!

Verified the tests fail without the fix too.

failure

longwave’s picture

Status: Reviewed & tested by the community » Fixed

I think we could almost consider dropping the warning entirely, but there is some benefit in keeping it for users that previously were used to the ! syntax that is no longer allowed. As we ignore valid placeholders that aren't present in the string, ignoring entirely-invalid placeholders that don't begin with a special character also seems fine.

Backported to 10.1.x as a low risk bug fix.

Committed and pushed e1a599bedd to 11.x and 08fa3c2ea2 to 10.1.x. Thanks!

  • longwave committed 08fa3c2e on 10.1.x
    Issue #3173103 by TolstoyDotCom, aludescher, smustgrave, J.,...

  • longwave committed e1a599be on 11.x
    Issue #3173103 by TolstoyDotCom, aludescher, smustgrave, J.,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

donquixote’s picture

Related: #3352384: Add Exception for TypeError Argument must be String in Drupal Component Utility Html escape{}

A question is whether we should already validate and filter placeholder arguments in FormattableMarkup::__construct(), or wait for __toString() to be called as it is now.

Doing it in __construct() will provide a more useful backtrace.
However, if there is any code that relies on non-Drupal placeholders returned from FormattableMarkup->getArguments(), even if they won't be inserted in the string, that code would no longer work as designed.

So maybe we can validate in __construct() to call trigger_error(), but filter in ::placeholderFormat() which is called in __toString(), where we then don't call trigger_error() again.