protected function validate(&$value) { if ($this->isNull($value)) { return $this; } if (!$this->isArray($value) && !$this->isArrayObject($value)) { $this->expected('array or ArrayObject', gettype($value)); } $value = StdObjectWrapper::toArray($value); if (!array_key_exists('lat', $value) || !array_key_exists('lng', $value)) { $ex = new ValidationException(ValidationException::VALIDATION_FAILED); $ex->addError($this->attribute, 'GeoPointAttribute value must contain `lat` and `lng`'); throw $ex; } }
/** * @param mixed $data * * @throws ValidationException */ private function validateNestedKeys($data) { $ex = new ValidationException(ValidationException::VALIDATION_FAILED, [$this->attribute]); $messages = $this->getKeyValidationMessages(); $keyValidators = $this->getKeyValidators(); $errors = []; foreach ($keyValidators as $key => $validators) { $keyValue = $this->arr($data)->keyNested($key); if ($this->isString($validators)) { $validators = explode(',', $validators); } // Do not validate if attribute value is not required and empty value is given // 'empty' function is not suitable for this check here if (!in_array('required', $validators) && (is_null($keyValue) || $keyValue === '')) { continue; } foreach ($validators as $validator) { try { $this->applyValidator($validator, $key, $keyValue, isset($messages[$key]) ? $messages[$key] : []); } catch (ValidationException $e) { foreach ($e as $key => $error) { $errors[$this->attr() . '.' . $key] = $error; } } } } if (count($errors)) { foreach ($errors as $key => $msg) { $ex->addError($key, $msg); } throw $ex; } }
private function populateAttribute($attributeName, AbstractAttribute $entityAttribute, $validation, $data, $fromDb) { // Skip population of protected attributes if data is not coming from DB if (!$fromDb && $entityAttribute->getSkipOnPopulate()) { return; } // Dynamic attributes from database should be populated without any checks, and skipped otherwise if ($this->isInstanceOf($entityAttribute, AttributeType::DYNAMIC) && isset($data[$attributeName])) { $entityAttribute->setValue($data[$attributeName], $fromDb); return; } /** * Check if attribute is required and it's value is set or maybe value was already assigned */ if (!$fromDb && $entityAttribute->isRequired() && !isset($data[$attributeName]) && !$entityAttribute->hasValue()) { $message = $entityAttribute->getValidationMessages('required'); if (!$message) { $message = ValidationException::REQUIRED; } $ex = new ValidationException(ValidationException::VALIDATION_FAILED); $ex->addError($attributeName, $message, []); $validation[$attributeName] = $ex; return; } /** * In case it is an update - if the attribute is not in new $data, it's no big deal, we already have the previous value. */ $dataIsSet = array_key_exists($attributeName, $data); if (!$dataIsSet && $this->exists()) { return; } $canPopulate = !$this->exists() || $fromDb || !$entityAttribute->getOnce(); if ($dataIsSet && $canPopulate) { $dataValue = $data[$attributeName]; try { $entityAttribute->setValue($dataValue, $fromDb); } catch (ValidationException $e) { $validation[$attributeName] = $e; } } }
/** * @param AbstractAttribute $attribute * @param ValidationException $e * * @return AttributeValidationException */ public function attributeValidationException(AbstractAttribute $attribute, ValidationException $e) { $attrException = new AttributeValidationException($e->getMessage()); $attrException->addError($attribute->getName(), $e->getMessage()); return $attrException; }
/** * Throw or return attribute validation exception * * @param string $expecting * @param string $got * @param bool $return * * @return ValidationException * @throws ValidationException */ protected function expected($expecting, $got, $return = false) { $ex = new ValidationException(ValidationException::VALIDATION_FAILED); $ex->addError($this->attribute, ValidationException::DATA_TYPE, [$expecting, $got]); if ($return) { return $ex; } throw $ex; }