You are here

public function SelectOtherAllowedValuesConstraintValidator::validateFallback in CCK Select Other 8

Fallback to what core does.

Parameters

mixed $value: The value to check.

\Symfony\Component\Validator\Constraint $constraint: Constraint object.

Throws

\Drupal\Core\TypedData\Exception\MissingDataException

\LogicException

1 call to SelectOtherAllowedValuesConstraintValidator::validateFallback()
SelectOtherAllowedValuesConstraintValidator::validate in src/Validation/Plugin/Validation/Constraint/SelectOtherAllowedValuesConstraintValidator.php
Checks if the passed value is valid.

File

src/Validation/Plugin/Validation/Constraint/SelectOtherAllowedValuesConstraintValidator.php, line 120

Class

SelectOtherAllowedValuesConstraintValidator
Bypass AllowedValuesConstraintValidator by rewriting it.

Namespace

Drupal\cck_select_other\Validation\Plugin\Validation\Constraint

Code

public function validateFallback($value, Constraint $constraint) {
  $typed_data = $this
    ->getTypedData();
  if ($typed_data instanceof OptionsProviderInterface) {
    $allowed_values = $typed_data
      ->getSettableValues($this->currentUser);
    $constraint->choices = $allowed_values;

    // If the data is complex, we have to validate its main property.
    if ($typed_data instanceof ComplexDataInterface) {
      $name = $typed_data
        ->getDataDefinition()
        ->getMainPropertyName();
      if (!isset($name)) {
        throw new \LogicException('Cannot validate allowed values for complex data without a main property.');
      }
      $typed_data = $typed_data
        ->get($name);
      $value = $typed_data
        ->getValue();
    }
  }

  // The parent implementation ignores values that are not set, but makes
  // sure some choices are available firstly. However, we want to support
  // empty choices for undefined values; for instance, if a term reference
  // field points to an empty vocabulary.
  if (!isset($value)) {
    return;
  }

  // Get the value with the proper datatype in order to make strict
  // comparisons using in_array().
  if (!$typed_data instanceof PrimitiveInterface) {
    throw new \LogicException('The data type must be a PrimitiveInterface at this point.');
  }
  $value = $typed_data
    ->getCastedValue();

  // In a better world where typed data just returns typed values, we could
  // set a constraint callback to use the OptionsProviderInterface.
  // This is not possible right now though because we do the typecasting
  // further down.
  if ($constraint->callback) {
    if (!\is_callable($choices = [
      $this->context
        ->getObject(),
      $constraint->callback,
    ]) && !\is_callable($choices = [
      $this->context
        ->getClassName(),
      $constraint->callback,
    ]) && !\is_callable($choices = $constraint->callback)) {
      throw new ConstraintDefinitionException('The AllowedValuesConstraint constraint expects a valid callback');
    }
    $allowed_values = \call_user_func($choices);
    $constraint->choices = $allowed_values;

    // parent::validate() does not need to invoke the callback again.
    $constraint->callback = NULL;
  }

  // Force the choices to be the same type as the value.
  $type = gettype($value);
  foreach ($constraint->choices as &$choice) {
    settype($choice, $type);
  }
  parent::validate($value, $constraint);
}