Problem/Motivation
When a view uses the Smart Date date argument plugin (Drupal\smart_date\Plugin\views\argument\Date) on a field reached via a relationship, loading a page backed by that view logs a PHP 8.1+ deprecation notice
Deprecated function: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in Drupal\views\Plugin\views\argument\Formula->getFormula() (line 46 of core/modules/views/src/Plugin/views/argument/Formula.php)
with a backtrace like:
Drupal\views\Plugin\views\argument\Formula->getFormula()
Drupal\smart_date\Plugin\views\argument\Date->getFormula()
Drupal\views\Plugin\views\argument\Formula->query()
Drupal\views\ViewExecutable->_buildArguments()
Drupal\views\ViewExecutable->buildTitle()
metatag_views_get_view_tags()
metatag_views_metatags_alter()
...The Metatag module calls ViewExecutable::buildTitle() for any route backed by a view (via metatag_views_get_view_tags()) in order to resolve view-title tokens for meta tags. This walks every argument on the view, including ones that don't contribute to the title. When the argument's field is reached through a relationship, buildTitle() can run before that relationship's join has been fully resolved in the query, so ArgumentPluginBase::ensureMyTable() (called internally by Formula::query()) returns NULL for $this->tableAlias.
Date::getFormula() then calls parent::getFormula() (Formula::getFormula()), which does:
return str_replace('***table***', $this->tableAlias, $this->formula);
Passing a NULL $this->tableAlias here trips PHP 8.1+'s deprecation for passing null to a non-nullable internal function parameter.
This is non-fatal — the page itself still renders correctly, since the query object built during this title-building pass is discarded rather than executed — but it pollutes logs (and, in dev environments with verbose error display, shows up on-screen) on every page load of the affected view.
Steps to reproduce
- Enable the Metatag module.
- Create a view with a page display whose path includes an argument.
- Add a Smart Date date argument (Drupal\smart_date\Plugin\views\argument\Date) on a date field reached via a relationship (e.g. a field on a referenced entity, not the view's base table).
- Load a page rendered by that view.
- Check the logs (admin/reports/dblog, filtered to PHP) for the str_replace() deprecation above.
Proposed resolution
Guard against a NULL table alias in Date::getFormula() before delegating to the parent, e.g.:
public function getFormula() {
$this->formula = $this->getDateFormat($this->argFormat);
// The table alias can be NULL if this is invoked before the relationship
// join has been fully resolved (e.g. metatag_views_get_view_tags()
// calling ViewExecutable::buildTitle() ahead of full query execution).
// Avoid a PHP 8.1+ deprecation from passing NULL to str_replace().
$this->tableAlias = $this->tableAlias ?? '';
return parent::getFormula();
}
I have this fix applied and verified locally (confirmed via watchdog that the deprecation no longer logs after repeated page loads) and am happy to submit it as an MR.
Additional notes
This may be one instance of a broader pattern affecting Drupal\views\Plugin\views\argument\Formula::getFormula() itself in core (see #3294680: PHP8.1 deprecation: str_replace(): Passing null to parameter #3) and a similar report against Metatag (#3401733: Deprecated function: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated), but this fix addresses it at the Smart Date layer without depending on either of those being resolved.
Issue fork smart_date-3608189
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
Comment #2
mandclu commentedComment #5
mandclu commented