/** * {@inheritdoc} */ public function filter(DataDefinitionInterface $definition, $value, array $arguments, BubbleableMetadata $bubbleable_metadata = NULL) { if ($definition->getDataType() != 'timestamp') { // Convert the date to an timestamp. $value = $this->getTypedDataManager()->create($definition, $value)->getDateTime()->getTimestamp(); } $arguments += [0 => 'medium', 1 => '', 2 => NULL, 3 => NULL]; if ($arguments[0] != 'custom' && $bubbleable_metadata) { $config = $this->dateFormatStorage->load($arguments[0]); if (!$config) { throw new \InvalidArgumentException("Unknown date format {$arguments['0']} given."); } $bubbleable_metadata->addCacheableDependency($config); } return $this->dateFormatter->format($value, $arguments[0], $arguments[1], $arguments[2], $arguments[3]); }
/** * Gets default constraints for the given data definition. * * This generates default constraint definitions based on the data definition; * e.g. a NotNull constraint is generated if the data is defined as required. * Besides that any constraints defined for the data type, i.e. below the * 'constraint' key of the type's plugin definition, are taken into account. * * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition * A data definition. * * @return array * An array of validation constraint definitions, keyed by constraint name. * Each constraint definition can be used for instantiating * \Symfony\Component\Validator\Constraint objects. */ public function getDefaultConstraints(DataDefinitionInterface $definition) { $constraints = array(); $type_definition = $this->getDefinition($definition->getDataType()); // Auto-generate a constraint for data types implementing a primitive // interface. if (is_subclass_of($type_definition['class'], '\\Drupal\\Core\\TypedData\\PrimitiveInterface')) { $constraints['PrimitiveType'] = array(); } // Add in constraints specified by the data type. if (isset($type_definition['constraints'])) { $constraints += $type_definition['constraints']; } // Add the NotNull constraint for required data. if ($definition->isRequired()) { $constraints['NotNull'] = array(); } // Check if the class provides allowed values. if (is_subclass_of($definition->getClass(), 'Drupal\\Core\\TypedData\\OptionsProviderInterface')) { $constraints['AllowedValues'] = array(); } // Add any constraints about referenced data. if ($definition instanceof DataReferenceDefinitionInterface) { $constraints += $definition->getTargetDefinition()->getConstraints(); } return $constraints; }
/** * Creates a new field on an index based on a property. * * Will find and set a new unique field identifier for the field on the index. * * @param \Drupal\search_api\IndexInterface $index * The search index. * @param \Drupal\Core\TypedData\DataDefinitionInterface $property * The data definition of the property. * @param string|null $datasource_id * The ID of the index's datasource this property belongs to, or NULL if it * is a datasource-independent property. * @param string $property_path * The property's property path within the property structure of the * datasource. * @param string|null $field_id * (optional) The identifier to use for the field. If not set, a new unique * field identifier on the index will be chosen automatically. * @param string|null $type * (optional) The type to set for the field, or NULL to determine a default * type automatically. * * @return \Drupal\search_api\Item\FieldInterface * A new field object for the index, based on the given property. * * @throws \Drupal\search_api\SearchApiException * Thrown if no type was given and no default could be determined. */ public static function createFieldFromProperty(IndexInterface $index, DataDefinitionInterface $property, $datasource_id, $property_path, $field_id = NULL, $type = NULL) { if (!isset($field_id)) { $field_id = static::getNewFieldId($index, $property_path); } if (!isset($type)) { $type_mapping = static::getFieldTypeMapping(); $property_type = $property->getDataType(); if (isset($type_mapping[$property_type])) { $type = $type_mapping[$property_type]; } else { $args['%property'] = $property->getLabel(); $args['%property_path'] = $property_path; $args['%type'] = $property_type; $message = new FormattableMarkup('No default data type mapping could be found for property %property (%property_path) of type %type.', $args); throw new SearchApiException($message); } } $field_info = array('label' => $property->getLabel(), 'datasource_id' => $datasource_id, 'property_path' => $property_path, 'type' => $type); return self::createField($index, $field_id, $field_info); }
/** * {@inheritdoc} */ public function getPluginDefinition() { return \Drupal::typedDataManager()->getDefinition($this->definition->getDataType()); }
/** * {@inheritdoc} */ public function getMatchingContexts(array $contexts, DataDefinitionInterface $definition) { return array_filter($contexts, function (ContextInterface $context) use($definition) { $context_definition = $context->getContextDefinition()->getDataDefinition(); // If the data types do not match, this context is invalid. if ($definition->getDataType() != $context_definition->getDataType()) { return FALSE; } // If any constraint does not match, this context is invalid. // @todo This is too restrictive, consider only relying on data types. foreach ($definition->getConstraints() as $constraint_name => $constraint) { if ($context_definition->getConstraint($constraint_name) != $constraint) { return FALSE; } } // All contexts with matching data type and contexts are valid. return TRUE; }); }
/** * Checks that the data type of a mapped variable matches the expectation. * * @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context_definition * The context definition of the context on the plugin. * @param \Drupal\Core\TypedData\DataDefinitionInterface $provided * The data definition of the mapped variable to the context. * @param string $context_name * The name of the context on the plugin. * @param \Drupal\rules\Engine\IntegrityViolationList $violation_list * The list of violations where new ones will be added. */ protected function checkDataTypeCompatible(ContextDefinitionInterface $context_definition, DataDefinitionInterface $provided, $context_name, IntegrityViolationList $violation_list) { $expected_class = $context_definition->getDataDefinition()->getClass(); $provided_class = $provided->getClass(); $expected_type_problem = NULL; if (is_subclass_of($expected_class, PrimitiveInterface::class) && !is_subclass_of($provided_class, PrimitiveInterface::class)) { $expected_type_problem = $this->t('primitive'); } elseif (is_subclass_of($expected_class, ListInterface::class) && !is_subclass_of($provided_class, ListInterface::class)) { $expected_type_problem = $this->t('list'); } elseif (is_subclass_of($expected_class, ComplexDataInterface::class) && !is_subclass_of($provided_class, ComplexDataInterface::class)) { $expected_type_problem = $this->t('complex'); } if ($expected_type_problem) { $violation = new IntegrityViolation(); $violation->setMessage($this->t('Expected a @expected_type data type for context %context_name but got a @provided_type data type instead.', ['@expected_type' => $expected_type_problem, '%context_name' => $context_definition->getLabel(), '@provided_type' => $provided->getDataType()])); $violation->setContextName($context_name); $violation_list->add($violation); } }
/** * {@inheritdoc} */ public function getDataType() { if (!$this->wrappedProperty) { return NULL; } return $this->wrappedProperty->getDataType(); }
/** * Checks that the data type of a mapped variable matches the expectation. * * @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context_definition * The context definition of the context on the plugin. * @param \Drupal\Core\TypedData\DataDefinitionInterface $provided * The data definition of the mapped variable to the context. * @param string $context_name * The name of the context on the plugin. * @param \Drupal\rules\Engine\IntegrityViolationList $violation_list * The list of violations where new ones will be added. */ protected function checkDataTypeCompatible(CoreContextDefinitionInterface $context_definition, DataDefinitionInterface $provided, $context_name, IntegrityViolationList $violation_list) { // Compare data types. For now, fail if they are not equal. // @todo: Add support for matching based upon type-inheritance. $target_type = $context_definition->getDataDefinition()->getDataType(); // Special case any and entity target types for now. if ($target_type == 'any' || $target_type == 'entity' && strpos($provided->getDataType(), 'entity:') !== FALSE) { return; } if ($target_type != $provided->getDataType()) { $expected_type_problem = $context_definition->getDataDefinition()->getDataType(); $violation = new IntegrityViolation(); $violation->setMessage($this->t('Expected a @expected_type data type for context %context_name but got a @provided_type data type instead.', ['@expected_type' => $expected_type_problem, '%context_name' => $context_definition->getLabel(), '@provided_type' => $provided->getDataType()])); $violation->setContextName($context_name); $violation->setUuid($this->getUuid()); $violation_list->add($violation); } }