diff --git a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php index 888a36bd49..41e641a7ec 100644 --- a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php +++ b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php @@ -5,6 +5,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Datetime\DateFormatInterface; +use Drupal\Core\Entity\EntityStorageInterface; /** * Defines the Date Format configuration entity class. @@ -100,4 +101,22 @@ public function getCacheTagsToInvalidate() { return ['rendered']; } + /** + * {@inheritdoc} + */ + public static function postDelete(EntityStorageInterface $storage, array $entities) { + parent::postDelete($storage, $entities); + \Drupal::token()->resetInfo(); + } + + /** + * {@inheritdoc} + */ + public function postSave(EntityStorageInterface $storage, $update = TRUE) { + parent::postSave($storage, $update); + if (!$update) { + \Drupal::token()->resetInfo(); + } + } + } diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc index c55e106b76..1b4777d51e 100644 --- a/core/modules/system/system.tokens.inc +++ b/core/modules/system/system.tokens.inc @@ -8,7 +8,6 @@ */ use Drupal\Core\Url; -use Drupal\Core\Datetime\Entity\DateFormat; use Drupal\Core\Render\BubbleableMetadata; /** @@ -54,18 +53,18 @@ function system_token_info() { $date_formatter = \Drupal::service('date.formatter'); // Date related tokens. - $date['short'] = [ - 'name' => t("Short format"), - 'description' => t("A date in 'short' format. (%date)", ['%date' => $date_formatter->format(REQUEST_TIME, 'short')]), - ]; - $date['medium'] = [ - 'name' => t("Medium format"), - 'description' => t("A date in 'medium' format. (%date)", ['%date' => $date_formatter->format(REQUEST_TIME, 'medium')]), - ]; - $date['long'] = [ - 'name' => t("Long format"), - 'description' => t("A date in 'long' format. (%date)", ['%date' => $date_formatter->format(REQUEST_TIME, 'long')]), - ]; + /** @var \Drupal\Core\Datetime\DateFormatInterface[] $date_formats */ + $date_formats = \Drupal::entityTypeManager()->getStorage('date_format')->loadMultiple(); + foreach ($date_formats as $date_format) { + $date[$date_format->id()] = [ + 'name' => $date_format->label(), + 'description' => t('A date in the %name format. (%date)', [ + '%name' => $date_format->label(), + '%date' => $date_formatter->format(\Drupal::time()->getRequestTime(), $date_format->id()), + ]), + ]; + } + $date['custom'] = [ 'name' => t("Custom format"), 'description' => t('A date in a custom format. See the PHP documentation for details.'), @@ -166,16 +165,17 @@ function system_tokens($type, $tokens, array $data, array $options, BubbleableMe $date = $data['date']; } + /** @var \Drupal\Core\Entity\EntityStorageInterface $date_format_storage */ + $date_format_storage = \Drupal::entityTypeManager()->getStorage('date_format'); foreach ($tokens as $name => $original) { + // Date type token replacement. + $date_format = $date_format_storage->load($name); + if ($date_format) { + $bubbleable_metadata->addCacheableDependency($date_format); + $replacements[$original] = \Drupal::service('date.formatter')->format($date, $name, '', NULL, $langcode); + continue; + } switch ($name) { - case 'short': - case 'medium': - case 'long': - $date_format = DateFormat::load($name); - $bubbleable_metadata->addCacheableDependency($date_format); - $replacements[$original] = \Drupal::service('date.formatter')->format($date, $name, '', NULL, $langcode); - break; - case 'since': $replacements[$original] = \Drupal::service('date.formatter')->formatTimeDiffSince($date, ['langcode' => $langcode]); $bubbleable_metadata->setCacheMaxAge(0); diff --git a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php index 1f86dd386a..ffefda4af1 100644 --- a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php +++ b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php @@ -6,6 +6,7 @@ use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Xss; +use Drupal\Core\Datetime\Entity\DateFormat; use Drupal\Core\Render\BubbleableMetadata; /** @@ -137,10 +138,20 @@ public function testSystemDateTokenReplacement() { // Generate and test tokens. $tests = []; + /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */ $date_formatter = \Drupal::service('date.formatter'); - $tests['[date:short]'] = $date_formatter->format($date, 'short', '', NULL, $this->interfaceLanguage->getId()); - $tests['[date:medium]'] = $date_formatter->format($date, 'medium', '', NULL, $this->interfaceLanguage->getId()); - $tests['[date:long]'] = $date_formatter->format($date, 'long', '', NULL, $this->interfaceLanguage->getId()); + + // Test standard date format tokens. + $date_formats = array_keys(\Drupal::entityTypeManager()->getStorage('date_format')->loadMultiple()); + $this->assertCount(11, $date_formats); + $this->assertTrue(in_array('short', $date_formats)); + $this->assertTrue(in_array('medium', $date_formats)); + $this->assertTrue(in_array('long', $date_formats)); + $this->assertTrue(in_array('html_date', $date_formats)); + foreach ($date_formats as $date_format) { + $tests['[date:' . $date_format . ']'] = $date_formatter->format($date, $date_format, '', NULL, $this->interfaceLanguage->getId()); + } + $tests['[date:custom:m/j/Y]'] = $date_formatter->format($date, 'custom', 'm/j/Y', NULL, $this->interfaceLanguage->getId()); $tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, ['langcode' => $this->interfaceLanguage->getId()]); $tests['[date:raw]'] = Xss::filter($date); @@ -154,4 +165,30 @@ public function testSystemDateTokenReplacement() { } } + /** + * Tests the generation of all system date format tokens when formats change. + */ + public function testSystemDateTokenGetInfo() { + $tokens = \Drupal::token()->getInfo(); + $this->assertArrayNotHasKey('y2k', $tokens['tokens']['date']); + + // Add new formats. + $date_format = DateFormat::create([ + 'id' => 'y2k', + 'label' => 'Y2K', + 'pattern' => 'y', + ]); + $date_format->save(); + + $tokens = \Drupal::token()->getInfo(); + $this->assertArrayHasKey('y2k', $tokens['tokens']['date']); + + // Delete the new format. + DateFormat::load('y2k')->delete(); + + // Verify the token was removed. + $tokens = \Drupal::token()->getInfo(); + $this->assertArrayNotHasKey('y2k', $tokens['tokens']['date']); + } + }