/** * {@inheritdoc} */ public function resolvePlaceholders($text, array $data = [], BubbleableMetadata $bubbleable_metadata = NULL, array $options = []) { $options += ['langcode' => NULL, 'clear' => FALSE]; $placeholder_by_data = $this->scan($text); if (empty($placeholder_by_data)) { return []; } $replacements = []; foreach ($placeholder_by_data as $data_name => $placeholders) { foreach ($placeholders as $placeholder_main_part => $placeholder) { try { if (!isset($data[$data_name])) { throw new MissingDataException("There is no data with the name '{$data_name}' available."); } list($property_sub_paths, $filters) = $this->parseMainPlaceholderPart($placeholder_main_part, $placeholder); $fetched_data = $this->dataFetcher->fetchDataBySubPaths($data[$data_name], $property_sub_paths, $bubbleable_metadata, $options['langcode']); // Apply filters. if ($filters) { $value = $fetched_data->getValue(); $definition = $fetched_data->getDataDefinition(); foreach ($filters as $data) { list($filter_id, $arguments) = $data; $filter = $this->dataFilterManager->createInstance($filter_id); if (!$filter->allowsNullValues() && !isset($value)) { throw new MissingDataException("There is no data value for filter '{$filter_id}' to work on."); } $value = $filter->filter($definition, $value, $arguments, $bubbleable_metadata); $definition = $filter->filtersTo($definition, $arguments); } } else { $value = $fetched_data->getString(); } // Escape the tokens, unless they are explicitly markup. $replacements[$placeholder] = $value instanceof MarkupInterface ? $value : new HtmlEscapedText($value); } catch (\InvalidArgumentException $e) { // Should we log warnings if there are problems other than missing // data, like syntactically invalid placeholders? if (!empty($options['clear'])) { $replacements[$placeholder] = ''; } } catch (MissingDataException $e) { if (!empty($options['clear'])) { $replacements[$placeholder] = ''; } } } } return $replacements; }
/** * @cover \Drupal\rules\Plugin\TypedDataFilter\FormatDateFilter */ public function testFormatDateFilter() { $filter = $this->dataFilterManager->createInstance('format_date'); $data = $this->typedDataManager->create(DataDefinition::create('timestamp'), 3700); $this->assertTrue($filter->canFilter($data->getDataDefinition())); $this->assertFalse($filter->canFilter(DataDefinition::create('any'))); $this->assertEquals('string', $filter->filtersTo($data->getDataDefinition(), [])->getDataType()); $fails = $filter->validateArguments($data->getDataDefinition(), []); $this->assertEquals(0, count($fails)); $fails = $filter->validateArguments($data->getDataDefinition(), ['medium']); $this->assertEquals(0, count($fails)); $fails = $filter->validateArguments($data->getDataDefinition(), ['invalid-format']); $this->assertEquals(1, count($fails)); $fails = $filter->validateArguments($data->getDataDefinition(), ['custom']); $this->assertEquals(1, count($fails)); $fails = $filter->validateArguments($data->getDataDefinition(), ['custom', 'Y']); $this->assertEquals(0, count($fails)); /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */ $date_formatter = $this->container->get('date.formatter'); $this->assertEquals($date_formatter->format(3700), $filter->filter($data->getDataDefinition(), $data->getValue(), [])); $this->assertEquals($date_formatter->format(3700, 'short'), $filter->filter($data->getDataDefinition(), $data->getValue(), ['short'])); $this->assertEquals('1970', $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y'])); // Verify the filter works with non-timestamp data as well. $data = $this->typedDataManager->create(DataDefinition::create('datetime_iso8601'), "1970-01-01T10:10:10+00:00"); $this->assertTrue($filter->canFilter($data->getDataDefinition())); $this->assertEquals('string', $filter->filtersTo($data->getDataDefinition(), [])->getDataType()); $this->assertEquals('1970', $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y'])); // Test cache dependencies of date format config entities are added in. $metadata = new BubbleableMetadata(); $filter->filter($data->getDataDefinition(), $data->getValue(), ['short'], $metadata); $this->assertEquals(DateFormat::load('short')->getCacheTags(), $metadata->getCacheTags()); $metadata = new BubbleableMetadata(); $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y'], $metadata); $this->assertEquals([], $metadata->getCacheTags()); }