/**
  * {@inheritdoc}
  */
 public function getDerivativeDefinitions($base_plugin_definition)
 {
     foreach ($this->typedDataManager->getDefinitions() as $data_type_id => $data_type_definition) {
         if (is_subclass_of($data_type_definition['class'], ComplexDataInterface::class, TRUE)) {
             /** @var \Drupal\Core\TypedData\ComplexDataDefinitionInterface $base_definition */
             $base_definition = $this->typedDataManager->createDataDefinition($data_type_id);
             foreach ($base_definition->getPropertyDefinitions() as $property_name => $property_definition) {
                 if ($property_definition instanceof BaseFieldDefinition || $property_definition instanceof FieldConfig) {
                     $this->generateDerivativeDefinition($base_plugin_definition, $data_type_id, $data_type_definition, $base_definition, $property_name, $property_definition);
                 }
             }
         }
     }
     return $this->derivatives;
 }
Example #2
0
 /**
  * @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());
 }
 /**
  * Tests the getAllBundleInfo() method.
  *
  * @covers ::getAllBundleInfo
  */
 public function testGetAllBundleInfo()
 {
     $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]);
     $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
     $apple = $this->prophesize(EntityTypeInterface::class);
     $apple->getLabel()->willReturn('Apple');
     $apple->getBundleOf()->willReturn(NULL);
     $banana = $this->prophesize(EntityTypeInterface::class);
     $banana->getLabel()->willReturn('Banana');
     $banana->getBundleOf()->willReturn(NULL);
     $this->setUpEntityTypeDefinitions(['apple' => $apple, 'banana' => $banana]);
     $this->cacheBackend->get('entity_bundle_info:en')->willReturn(FALSE);
     $this->cacheBackend->set('entity_bundle_info:en', Argument::any(), Cache::PERMANENT, ['entity_types', 'entity_bundles'])->will(function () {
         $this->get('entity_bundle_info:en')->willReturn((object) ['data' => 'cached data'])->shouldBeCalled();
     })->shouldBeCalled();
     $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled();
     $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
     $expected = ['apple' => ['apple' => ['label' => 'Apple']], 'banana' => ['banana' => ['label' => 'Banana']]];
     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
     $this->assertSame($expected, $bundle_info);
     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
     $this->assertSame($expected, $bundle_info);
     $this->entityTypeBundleInfo->clearCachedBundles();
     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
     $this->assertSame('cached data', $bundle_info);
 }
Example #4
0
 /**
  * {@inheritdoc}
  */
 public function clearCachedBundles()
 {
     $this->bundleInfo = [];
     Cache::invalidateTags(['entity_bundles']);
     // Entity bundles are exposed as data types, clear that cache too.
     $this->typedDataManager->clearCachedDefinitions();
 }
 /**
  * Returns a typed data object.
  *
  * This helper for quick creation of typed data objects.
  *
  * @param string $data_type
  *   The data type to create an object for.
  * @param mixed[] $value
  *   The value to set.
  *
  * @return \Drupal\Core\TypedData\TypedDataInterface
  *   The created object.
  */
 protected function getTypedData($data_type, $value)
 {
     $definition = $this->typedDataManager->createDataDefinition($data_type);
     $data = $this->typedDataManager->create($definition);
     $data->setValue($value);
     return $data;
 }
 /**
  * Tests the clearCachedFieldDefinitions() method.
  *
  * @covers ::clearCachedFieldDefinitions
  */
 public function testClearCachedFieldDefinitions()
 {
     $this->setUpEntityTypeDefinitions();
     $this->cacheTagsInvalidator->invalidateTags(['entity_field_info'])->shouldBeCalled();
     $this->container->get('cache_tags.invalidator')->willReturn($this->cacheTagsInvalidator->reveal())->shouldBeCalled();
     $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
     $this->entityFieldManager->clearCachedFieldDefinitions();
 }
Example #7
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     $cached_values = $form_state->getTemporaryValue('wizard');
     $this->machine_name = $cached_values['id'];
     $form['items'] = array('#type' => 'markup', '#prefix' => '<div id="configured-contexts">', '#suffix' => '</div>', '#theme' => 'table', '#header' => array($this->t('Context ID'), $this->t('Label'), $this->t('Data Type'), $this->t('Options')), '#rows' => $this->renderRows($cached_values), '#empty' => t('No contexts or relationships have been added.'));
     foreach ($this->typedDataManager->getDefinitions() as $type => $definition) {
         $types[$type] = $definition['label'];
     }
     if (isset($types['entity'])) {
         unset($types['entity']);
     }
     asort($types);
     $form['context'] = ['#type' => 'select', '#options' => $types];
     $form['add'] = ['#type' => 'submit', '#name' => 'add', '#value' => $this->t('Add new context'), '#ajax' => ['callback' => [$this, 'addContext'], 'event' => 'click'], '#submit' => ['callback' => [$this, 'submitForm']]];
     $form['relationships'] = ['#type' => 'select', '#title' => $this->t('Add a relationship'), '#options' => $this->getAvailableRelationships($cached_values), '#access' => $this->relationships];
     $form['add_relationship'] = ['#type' => 'submit', '#name' => 'add_relationship', '#value' => t('Add Relationship'), '#ajax' => ['callback' => [$this, 'addRelationship'], 'event' => 'click'], '#submit' => ['callback' => [$this, 'submitForm']], '#access' => $this->relationships];
     return $form;
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 public function clearCachedFieldDefinitions()
 {
     $this->baseFieldDefinitions = [];
     $this->fieldDefinitions = [];
     $this->fieldStorageDefinitions = [];
     $this->fieldMap = [];
     $this->fieldMapByFieldType = [];
     $this->entityDisplayRepository->clearDisplayModeInfo();
     $this->extraFields = [];
     Cache::invalidateTags(['entity_field_info']);
     // The typed data manager statically caches prototype objects with injected
     // definitions, clear those as well.
     $this->typedDataManager->clearCachedDefinitions();
 }
 /**
  * Builds an array of options for the parameter type.
  *
  * @return array[]
  *   A multidimensional array. The top level is keyed by group ('Content',
  *   'Configuration', 'Typed Data'). Those values are an array of type labels,
  *   keyed by the machine name.
  */
 protected function buildParameterTypeOptions()
 {
     $options = [static::NO_CONTEXT_KEY => $this->t('No context selected')];
     // Make a grouped, sorted list of entity type options. Key the inner array
     // to use the typed data format of 'entity:$entity_type_id'.
     foreach ($this->entityTypeRepository->getEntityTypeLabels(TRUE) as $group_label => $grouped_options) {
         foreach ($grouped_options as $key => $label) {
             $options[$group_label]['entity:' . $key] = $label;
         }
     }
     $primitives_label = (string) $this->t('Primitives');
     foreach ($this->typedDataManager->getDefinitions() as $key => $definition) {
         if (is_subclass_of($definition['class'], PrimitiveInterface::class)) {
             $options[$primitives_label][$key] = $definition['label'];
         }
     }
     asort($options[$primitives_label], SORT_NATURAL);
     return $options;
 }
 /**
  * @cover replacePlaceHolders
  */
 public function testApplyingFilters()
 {
     $this->node->field_integer = [1, 2, NULL];
     $this->node->title->value = NULL;
     $result = $this->placeholderResolver->replacePlaceHolders("test {{node.field_integer.2.value|default('0')}}", ['node' => $this->node->getTypedData()]);
     $this->assertEquals('test 0', $result);
     $result = $this->placeholderResolver->replacePlaceHolders("test {{node.title.value|default('tEsT')|lower}}", ['node' => $this->node->getTypedData()]);
     $this->assertEquals('test test', $result);
     // Test filter expressions with whitespaces.
     $result = $this->placeholderResolver->replacePlaceHolders("test {{ node.title.value | default('tEsT') | lower }}", ['node' => $this->node->getTypedData()]);
     $this->assertEquals('test test', $result);
     // Test a filter expression on data without accessing a property.
     $text = 'test {{string | lower}}';
     $result = $this->placeholderResolver->replacePlaceHolders($text, ['string' => $this->typedDataManager->create(DataDefinition::create('string'), 'Replacement')]);
     $this->assertEquals('test replacement', $result);
     $text = "The year is {{ date | format_date('custom', 'Y') }}.";
     $result = $this->placeholderResolver->replacePlaceHolders($text, ['date' => $this->typedDataManager->create(DataDefinition::create('timestamp'), '3600')]);
     $this->assertEquals('The year is 1970.', $result);
 }
 /**
  * Extracts an array of tokens and labels of the required data type.
  *
  * This method can specify a data type to extract from contexts. A classic
  * example of this would be wanting to find all the 'entity_reference'
  * properties on an entity. This method will iterate over all supplied
  * contexts returning an array of tokens of type 'entity_reference' with a
  * corresponding label that denotes their relationship to the provided
  * array of contexts.
  *
  * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
  *   The array of contexts with which we are currently dealing.
  * @param mixed string|array $data_types
  *   Data types to extract from the array of contexts.
  *
  * @return array
  *   An array of token keys and corresponding labels.
  */
 public function getTokensOfDataType($contexts, $data_types)
 {
     if (!is_array($data_types)) {
         $data_types = [$data_types];
     }
     $tokens = [];
     foreach ($contexts as $context_id => $context) {
         $data_definition = $this->manager->createDataDefinition($context->getContextDefinition()->getDataType());
         /**
          * @var \Drupal\Core\Field\BaseFieldDefinition $property
          */
         if ($data_definition instanceof ComplexDataDefinitionInterface) {
             foreach ($data_definition->getPropertyDefinitions() as $property_name => $property) {
                 if (in_array($property->getType(), $data_types)) {
                     $tokens["{$context_id}:{$property_name}"] = $this->getRelatedPropertyLabel($property, $context, $context_id);
                 }
             }
         }
     }
     return $tokens;
 }
Example #12
0
 /**
  * {@inheritdoc}
  */
 public function createFieldItem(FieldItemListInterface $items, $index, $values = NULL)
 {
     // Leverage prototyping of the Typed Data API for fast instantiation.
     return $this->typedDataManager->getPropertyInstance($items, $index, $values);
 }
 /**
  * @covers ::fetchDefinitionByPropertyPath
  * @expectedException \InvalidArgumentException
  * @expectedExceptionMessage The data selector 'unknown_property' cannot be applied because the definition of type 'integer' is not a list or a complex structure
  */
 public function testFetchingAtInvalidPosition()
 {
     $list_definition = $this->typedDataManager->createListDataDefinition('integer');
     // This should trigger an exception.
     $this->dataFetcher->fetchDefinitionByPropertyPath($list_definition, 'unknown_property');
 }
Example #14
0
 /**
  * @cover fetchDataByPropertyPath
  * @expectedException \Drupal\Core\TypedData\Exception\MissingDataException
  * @expectedExceptionMessageRegExp #Unable to apply data selector 'field_integer.0.value' at 'field_integer':.*#
  */
 public function testFetchingFromEmptyData()
 {
     $data_empty = $this->typedDataManager->create(EntityDataDefinition::create('node'));
     // This should trigger an exception.
     $this->dataFetcher->fetchDataByPropertyPath($data_empty, 'field_integer.0.value')->getValue();
 }