Final Class Yiisoft\Validator\DataSet\ObjectDataSet
A data set for object data. The object passed to this data set can provide rules and data by implementing {@see RulesProviderInterface} and {@see DataSetInterface}. Alternatively this data set allows getting rules from PHP attributes (attached to class properties and class itself) and data from object properties.
An example of object implementing {@see \Yiisoft\Validator\RulesProviderInterface}:
final class Author implements RulesProviderInterface
{
public function getRules(): iterable
{
return ['age' => [new Number(min: 18)]];
}
}
An example of object implementing {@see \Yiisoft\Validator\DataSetInterface}:
final class Author implements DataSetInterface
{
public function getPropertyValue(string $property): mixed
{
return $this->getData()[$property] ?? null;
}
public function getData(): mixed
{
return ['name' => 'John', 'age' => 18];
}
public function hasProperty(string $property): bool
{
return array_key_exists($property, $this->getData());
}
}
These two can be combined and used at the same time.
The attributes introduced in PHP 8 simplify rules' configuration process, especially for nested data and relations. This way the validated structures can be presented as DTO classes with references to each other.
An example of DTO with both one-to-one (requires PHP > 8.0) and one-to-many (requires PHP > 8.1) relations:
final class Post
{
#[Length(max: 255)]
public string $title = '';
#[Nested]
public Author|null $author = null;
// Passing instances is available only since PHP 8.1.
#[Each(new Nested(File::class))]
public array $files = [];
public function __construct()
{
$this->author = new Author();
}
}
final class Author
{
#[Length(min: 1)]
public string $name = '';
}
// Some rules, like "Nested" can be also configured through the class attribute.
#[Nested(['url' => new Url()])]
final class File
{
public string $url = '';
}
$post = new Post(title: 'Yii3 Overview 3', author: 'Dmitriy');
$parser = new ObjectParser($post);
$rules = $parser->getRules();
$data = $parser->getData();
The $rules will contain:
[
new Nested([
'title' => [new Length(max: 255)],
'author' => new Nested([
'name' => [new Length(min: 1)],
]),
'files' => new Each([
new Nested([
'url' => [new Url()],
]),
]),
]);
];
And the result of $data will be:
[
'title' => 'Yii3 Overview 3',
'author' => 'John',
'files' => [],
];
Note that the rule attributes can be combined with others without affecting parsing. Which properties to parse can be configured via {@see \Yiisoft\Validator\DataSet\ObjectDataSet::$propertyVisibility} and {@see \Yiisoft\Validator\DataSet\ObjectDataSet::$skipStaticProperties} options.
The other combinations of rules / data are also possible, for example: the data is provided by implementing {@see \Yiisoft\Validator\DataSetInterface} and rules are parsed from the attributes.
Please refer to the guide for more examples.
Rules and data provided via separate methods have a higher priority over attributes and properties, so, when used together, the latter ones will be ignored without exception.
When {@see \Yiisoft\Validator\RulesProviderInterface} / {@see \Yiisoft\Validator\DataSetInterface} are not implemented, uses {@see \Yiisoft\Validator\Helper\ObjectParser} and supports caching for data and attribute methods (partially) and rules (completely) which can be disabled on demand.
For getting only rules by a class name string or to be able to skip static properties, use {@see \Yiisoft\Validator\RulesProvider\AttributesRulesProvider} instead.
Public Methods
| Method | Description | Defined By |
|---|---|---|
| __construct() | Yiisoft\Validator\DataSet\ObjectDataSet | |
| getData() | Returns the validated data as array. | Yiisoft\Validator\DataSet\ObjectDataSet |
| getPropertyTranslator() | An optional property names translator. It's taken from the {@see $object} when
{@see PropertyTranslatorProviderInterface} is implemented. In case of it's missing, a null value is returned. |
Yiisoft\Validator\DataSet\ObjectDataSet |
| getPropertyValue() | Returns a property value by its name. | Yiisoft\Validator\DataSet\ObjectDataSet |
| getRules() | Returns {@see $object} rules specified via {@see RulesProviderInterface::getRules()} implementation or/and parsed from attributes attached to class properties and class itself. For the latter case repetitive calls utilize cache if it's enabled in {@see $useCache}. Rules provided via separate method have a lower priority over PHP attributes, so, when used together, all rules will be merged, but rules from PHP attributes will be applied first. | Yiisoft\Validator\DataSet\ObjectDataSet |
| getSource() | Yiisoft\Validator\DataSet\ObjectDataSet | |
| getValidationPropertyLabels() | Yiisoft\Validator\DataSet\ObjectDataSet | |
| hasProperty() | Whether this data set has the property with a given name. Note that this means existence only and properties with empty values are treated as present too. | Yiisoft\Validator\DataSet\ObjectDataSet |
Method Details
| public mixed __construct ( object $object, integer $propertyVisibility = ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PUBLIC, boolean $useCache = true ) | ||
| $object | object | |
| $propertyVisibility | integer |
Visibility levels the properties with rules / data must have. For example: public and protected only, this means that the rest (private ones) will be skipped. Defaults to all visibility levels (public, protected and private). |
| $useCache | boolean |
Whether to use cache for data and attribute methods (partially) and rules (completely). |
public function __construct(
/**
* @var object An object containing rules and data.
*/
private readonly object $object,
int $propertyVisibility = ReflectionProperty::IS_PRIVATE
| ReflectionProperty::IS_PROTECTED
| ReflectionProperty::IS_PUBLIC,
bool $useCache = true,
) {
$this->dataSetProvided = $this->object instanceof DataSetInterface;
$this->rulesProvided = $this->object instanceof RulesProviderInterface;
$this->parser = new ObjectParser(
source: $object,
propertyVisibility: $propertyVisibility,
useCache: $useCache,
);
}
Returns the validated data as array.
| public array|null getData ( ) | ||
| return | array|null |
Result of object {@see \Yiisoft\Validator\DataSetInterface::getData()} method, if it was implemented {@see \Yiisoft\Validator\DataSetInterface}, otherwise returns the validated data as an associative array - a mapping between property names and their values. |
|---|---|---|
public function getData(): ?array
{
if ($this->dataSetProvided) {
/** @var DataSetInterface $object */
$object = $this->object;
return $object->getData();
}
return $this->parser->getData();
}
An optional property names translator. It's taken from the {@see $object} when
{@see PropertyTranslatorProviderInterface} is implemented. In case of it's missing, a null value is returned.
| public Yiisoft\Validator\PropertyTranslatorInterface|null getPropertyTranslator ( ) | ||
| return | Yiisoft\Validator\PropertyTranslatorInterface|null |
A property translator instance or |
|---|---|---|
public function getPropertyTranslator(): ?PropertyTranslatorInterface
{
return $this->parser->getPropertyTranslator();
}
Returns a property value by its name.
Note that in case of non-existing property a default null value is returned. If you need to check the presence
of property or return a different default value, use {@see \Yiisoft\Validator\DataSet\hasProperty()} instead.
| public mixed getPropertyValue ( string $property ) | ||
| $property | string |
Property name. |
| return | mixed |
Property value. |
|---|---|---|
public function getPropertyValue(string $property): mixed
{
if ($this->dataSetProvided) {
/** @var DataSetInterface $object */
$object = $this->object;
return $object->getPropertyValue($property);
}
return $this->parser->getPropertyValue($property);
}
Returns {@see $object} rules specified via {@see RulesProviderInterface::getRules()} implementation or/and parsed from attributes attached to class properties and class itself. For the latter case repetitive calls utilize cache if it's enabled in {@see $useCache}. Rules provided via separate method have a lower priority over PHP attributes, so, when used together, all rules will be merged, but rules from PHP attributes will be applied first.
| public iterable getRules ( ) | ||
| return | iterable |
The resulting rules is an array with the following structure: |
|---|---|---|
public function getRules(): iterable
{
if ($this->rulesProvided) {
/** @var RulesProviderInterface $object */
$object = $this->object;
$rules = $object->getRules();
} else {
$rules = [];
}
// Providing data set assumes object has its own rules getting logic.
// So further parsing of rules is skipped intentionally.
if ($this->dataSetProvided) {
return $rules;
}
// Merge rules from `RulesProviderInterface` implementation and parsed from PHP attributes.
$rules = $rules instanceof Traversable ? iterator_to_array($rules) : $rules;
foreach ($this->parser->getRules() as $key => $value) {
if (is_int($key)) {
array_unshift($rules, $value);
continue;
}
/**
* @psalm-var list<RuleInterface> $value If `$key` is string, then `$value` is array of rules
* @see ObjectParser::getRules()
*/
if (!isset($rules[$key])) {
$rules[$key] = $value;
continue;
}
$rules[$key] = is_iterable($rules[$key])
? [...$value, ...$rules[$key]]
: [...$value, $rules[$key]];
}
return $rules;
}
| public array getValidationPropertyLabels ( ) |
public function getValidationPropertyLabels(): array
{
if ($this->object instanceof LabelsProviderInterface) {
/** @var LabelsProviderInterface $object */
$object = $this->object;
return $object->getValidationPropertyLabels();
}
return $this->parser->getLabels();
}
Whether this data set has the property with a given name. Note that this means existence only and properties with empty values are treated as present too.
| public boolean hasProperty ( string $property ) | ||
| $property | string |
Property name. |
| return | boolean |
Whether the property exists: |
|---|---|---|
public function hasProperty(string $property): bool
{
if ($this->dataSetProvided) {
/** @var DataSetInterface $object */
$object = $this->object;
return $object->hasProperty($property);
}
return $this->parser->hasProperty($property);
}
Signup or Login in order to comment.