You are here

class EntityConditionNormalizer in JSON:API 8

The normalizer used for entity conditions.

@internal

Hierarchy

  • class \Drupal\jsonapi\Normalizer\EntityConditionNormalizer implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface

Expanded class hierarchy of EntityConditionNormalizer

1 file declares its use of EntityConditionNormalizer
EntityConditionNormalizerTest.php in tests/src/Kernel/Normalizer/EntityConditionNormalizerTest.php
1 string reference to 'EntityConditionNormalizer'
jsonapi.services.yml in ./jsonapi.services.yml
jsonapi.services.yml
1 service uses EntityConditionNormalizer
serializer.normalizer.entity_condition.jsonapi in ./jsonapi.services.yml
Drupal\jsonapi\Normalizer\EntityConditionNormalizer

File

src/Normalizer/EntityConditionNormalizer.php, line 14

Namespace

Drupal\jsonapi\Normalizer
View source
class EntityConditionNormalizer implements DenormalizerInterface {

  /**
   * The field key in the filter condition: filter[lorem][condition][<field>].
   *
   * @var string
   */
  const PATH_KEY = 'path';

  /**
   * The value key in the filter condition: filter[lorem][condition][<value>].
   *
   * @var string
   */
  const VALUE_KEY = 'value';

  /**
   * The operator key in the condition: filter[lorem][condition][<operator>].
   *
   * @var string
   */
  const OPERATOR_KEY = 'operator';

  /**
   * {@inheritdoc}
   */
  protected $supportedInterfaceOrClass = EntityCondition::class;

  /**
   * {@inheritdoc}
   */
  protected $formats = [
    'api_json',
  ];

  /**
   * {@inheritdoc}
   */
  public function supportsDenormalization($data, $type, $format = NULL) {
    return $type === $this->supportedInterfaceOrClass;
  }

  /**
   * {@inheritdoc}
   */
  public function denormalize($data, $class, $format = NULL, array $context = []) {
    $this
      ->validate($data);
    $field = $data[static::PATH_KEY];
    $value = isset($data[static::VALUE_KEY]) ? $data[static::VALUE_KEY] : NULL;
    $operator = isset($data[static::OPERATOR_KEY]) ? $data[static::OPERATOR_KEY] : NULL;
    return new EntityCondition($field, $value, $operator);
  }

  /**
   * Validates the filter has the required fields.
   */
  protected function validate($data) {
    $valid_key_combinations = [
      [
        static::PATH_KEY,
        static::VALUE_KEY,
      ],
      [
        static::PATH_KEY,
        static::OPERATOR_KEY,
      ],
      [
        static::PATH_KEY,
        static::VALUE_KEY,
        static::OPERATOR_KEY,
      ],
    ];
    $given_keys = array_keys($data);
    $valid_key_set = array_reduce($valid_key_combinations, function ($valid, $set) use ($given_keys) {
      return $valid ? $valid : count(array_diff($set, $given_keys)) === 0;
    }, FALSE);
    $has_operator_key = isset($data[static::OPERATOR_KEY]);
    $has_path_key = isset($data[static::PATH_KEY]);
    $has_value_key = isset($data[static::VALUE_KEY]);
    if (!$valid_key_set) {

      // Try to provide a more specific exception is a key is missing.
      if (!$has_operator_key) {
        if (!$has_path_key) {
          throw new BadRequestHttpException("Filter parameter is missing a '" . static::PATH_KEY . "' key.");
        }
        if (!$has_value_key) {
          throw new BadRequestHttpException("Filter parameter is missing a '" . static::VALUE_KEY . "' key.");
        }
      }

      // Catchall exception.
      $reason = "You must provide a valid filter condition. Check that you have set the required keys for your filter.";
      throw new BadRequestHttpException($reason);
    }
    if ($has_operator_key) {
      $operator = $data[static::OPERATOR_KEY];
      if (!in_array($operator, EntityCondition::$allowedOperators)) {
        $reason = "The '" . $operator . "' operator is not allowed in a filter parameter.";
        throw new BadRequestHttpException($reason);
      }
      if (in_array($operator, [
        'IS NULL',
        'IS NOT NULL',
      ]) && $has_value_key) {
        $reason = "Filters using the '" . $operator . "' operator should not provide a value.";
        throw new BadRequestHttpException($reason);
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntityConditionNormalizer::$formats protected property
EntityConditionNormalizer::$supportedInterfaceOrClass protected property
EntityConditionNormalizer::denormalize public function Denormalizes data back into an object of the given class.
EntityConditionNormalizer::OPERATOR_KEY constant The operator key in the condition: filter[lorem][condition][<operator>].
EntityConditionNormalizer::PATH_KEY constant The field key in the filter condition: filter[lorem][condition][<field>].
EntityConditionNormalizer::supportsDenormalization public function Checks whether the given class is supported for denormalization by this normalizer.
EntityConditionNormalizer::validate protected function Validates the filter has the required fields.
EntityConditionNormalizer::VALUE_KEY constant The value key in the filter condition: filter[lorem][condition][<value>].