/** * @dataProvider provideInvalidValues */ public function testRejectionOfInvalidValues($invalid_value, $assert_message = '') { $rule = new ScalarRule('scalar', []); $this->assertFalse($rule->apply($invalid_value), $assert_message . ' should be rejected'); $this->assertNull($rule->getSanitizedValue(), $assert_message . ' should be null for an invalid value'); }
protected function execute($value, EntityInterface $entity = null) { if (!is_array($value)) { $this->throwError('non_array_value', [], IncidentInterface::CRITICAL); return false; } if (!empty($value) && !$this->isAssoc($value)) { $this->throwError('non_assoc_array', [], IncidentInterface::CRITICAL); return false; } $allowed_values = []; if ($this->hasOption(self::OPTION_ALLOWED_VALUES)) { $allowed_values = $this->getAllowedValues(); } $allowed_keys = []; if ($this->hasOption(self::OPTION_ALLOWED_KEYS)) { $allowed_keys = $this->getAllowedKeys(); } $allowed_pairs = []; if ($this->hasOption(self::OPTION_ALLOWED_PAIRS)) { $allowed_pairs = $this->getAllowedPairs(); } $sanitized = []; $options = $this->getOptions(); $value_type = $this->getOption(self::OPTION_VALUE_TYPE, self::VALUE_TYPE_SCALAR); $rule = null; switch ($value_type) { case self::VALUE_TYPE_INTEGER: $rule = new IntegerRule('integer', $this->getIntegerOptions()); break; case self::VALUE_TYPE_FLOAT: $rule = new FloatRule('float', $this->getFloatOptions()); break; case self::VALUE_TYPE_BOOLEAN: $rule = new BooleanRule('boolean', $this->getOptions()); break; case self::VALUE_TYPE_TEXT: $rule = new TextRule('text', $this->getOptions()); break; case self::VALUE_TYPE_SCALAR: default: $rule = new ScalarRule('scalar', $this->getOptions()); break; } foreach ($value as $key => $val) { if (is_numeric($key)) { $this->throwError('numeric_key', [], IncidentInterface::NOTICE); } $key = trim($key); if (!strlen($key)) { $this->throwError('empty_key', [], IncidentInterface::CRITICAL); return false; } // check for allowed keys if ($this->hasOption(self::OPTION_ALLOWED_KEYS)) { if (!in_array($key, $allowed_keys, true)) { $this->throwError(self::OPTION_ALLOWED_KEYS, [self::OPTION_ALLOWED_KEYS => $allowed_keys, 'key' => $key]); return false; } } if (is_null($val)) { $val = ''; } if (!is_scalar($val)) { $this->throwError('non_scalar_value', ['key' => $key], IncidentInterface::CRITICAL); return false; } // we accept simple scalar types to be casted to strings if ($value_type === self::VALUE_TYPE_TEXT) { $val = (string) $val; } // validate value to be string, integer, float or boolean if (!$rule->apply($val)) { $this->throwIncidentsAsErrors($rule); return false; } $val = $rule->getSanitizedValue(); // check for allowed values if ($this->hasOption(self::OPTION_ALLOWED_VALUES)) { // use FloatAttribute if equal value comparison of float values if important if (!in_array($val, $allowed_values, true)) { $this->throwError(self::OPTION_ALLOWED_VALUES, [self::OPTION_ALLOWED_VALUES => $allowed_values, 'value' => $val]); return false; } } // check for allowed key => values pairs if ($this->hasOption(self::OPTION_ALLOWED_PAIRS)) { // use FloatAttribute if equal value comparison of float values is important (w/ precision) if (!(array_key_exists($key, $allowed_pairs) && $allowed_pairs[$key] === $val)) { $this->throwError(self::OPTION_ALLOWED_PAIRS, [self::OPTION_ALLOWED_PAIRS => $allowed_pairs, 'key' => $key, 'value' => $val]); return false; } } $sanitized[$key] = $val; } $this->setSanitizedValue($sanitized); return true; }