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])) {