Drupal\Core\Datetime::dateFormat() does not properly cache results

Created on 29 October 2024, 17 days ago

Problem/Motivation

I have a page that displays a series of calendar events, where each event has a start and end date. I found that having just a dozen or so events would result in the same DB query being repeated over a thousand times:

SELECT "cid", "data", "created", "expire", "serialized", "tags", "checksum" FROM "cache_config" WHERE "cid" IN ( 'core.date_format.' ) ORDER BY "cid"

Steps to reproduce

This code results in two database queries instead of one:

\Drupal::service('date.formatter')->format(time(), 'bad type', '', NULL, 'en');
\Drupal::service('date.formatter')->format(time(), 'bad type', '', NULL, 'en');

Proposed resolution

The reason for this lies in Drupal\Core\Datetime::dateFormat():

protected function dateFormat($type, $langcode) {
    if (!isset($this->dateFormats[$type][$langcode])) {
      $original_language = $this->languageManager->getConfigOverrideLanguage();
      $this->languageManager->setConfigOverrideLanguage(new Language(['id' => $langcode]));
      $this->dateFormats[$type][$langcode] = $this->dateFormatStorage->load($type);
      $this->languageManager->setConfigOverrideLanguage($original_language);
    }
    return $this->dateFormats[$type][$langcode];
  }

The problem is that the result of isset($array['key']) is FALSE if the value stored in the array at that position is NULL. So when the result of $this->dateFormatStorage->load($type) is NULL the same (non-existant) date format is re-fetched every time this function gets called with the same values.

The solution is to use array_key_exists() instead of isset():

    if (!array_key_exists($type, $this->dateFormats) || !array_key_exists($langcode, $this->dateFormats[$type])) {
🐛 Bug report
Status

Active

Version

11.0 🔥

Component

base system

Created by

🇺🇸United States gribnif

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

Merge Requests

Comments & Activities

Production build 0.71.5 2024