1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ValidationService.php
См. документацию.
1<?php
2
3declare(strict_types=1);
4
5namespace Bitrix\Main\Validation;
6
7use Bitrix\Main\ArgumentException;
8use Bitrix\Main\Localization\LocalizableMessage;
9use Bitrix\Main\Validation\Rule\ClassValidationAttributeInterface;
10use Bitrix\Main\Validation\Rule\Recursive\Validatable;
11use Bitrix\Main\Validation\Rule\PropertyValidationAttributeInterface;
12use Generator;
13use ReflectionAttribute;
14use ReflectionClass;
15use ReflectionParameter;
16use ReflectionProperty;
17
19{
20 public function validate(object $object): ValidationResult
21 {
23
24 $propertyResult = $this->validateByPropertyAttributes($object);
25 $result->addErrors($propertyResult->getErrors());
26
27 $classResult = $this->validateByClassAttributes($object);
28 $result->addErrors($classResult->getErrors());
29
30 return $result;
31 }
32
33 public function validateParameter(ReflectionParameter $parameter, mixed $value): ValidationResult
34 {
36
37 $attributes = $this->getValidationAttributes($parameter);
38
39 $name = $parameter->getName();
40
41 $generator = $this->validateValue($value, $name, $attributes);
42 $errors = iterator_to_array($generator);
43
44 return $result->addErrors($errors);
45 }
46
47 private function validateByClassAttributes(object $object): ValidationResult
48 {
50
51 $class = new ReflectionClass($object);
52 $attributes = $class->getAttributes(ClassValidationAttributeInterface::class, ReflectionAttribute::IS_INSTANCEOF);
53
54 if (empty($attributes))
55 {
56 return $result;
57 }
58
59 foreach ($attributes as $attribute)
60 {
61 $attributeInstance = $attribute->newInstance();
62 $attributeErrors = $attributeInstance->validateObject($object)->getErrors();
63 $result->addErrors($attributeErrors);
64 }
65
66 return $result;
67 }
68
69 private function validateByPropertyAttributes(object $object): ValidationResult
70 {
71 $result = new ValidationResult();
72
73 $properties = (new ReflectionClass($object))->getProperties();
74 foreach ($properties as $property)
75 {
76 if ($property->isInitialized($object))
77 {
78 $generator = $this->validateProperty($property, $object);
79 $errors = iterator_to_array($generator);
80 $result->addErrors($errors);
81
82 continue;
83 }
84
85 $type = $property->getType();
86 if (null === $type)
87 {
88 continue;
89 }
90
91 if ($type->allowsNull())
92 {
93 continue;
94 }
95
96 if (!$type->allowsNull())
97 {
98 $result->addError(new ValidationError(
99 new LocalizableMessage('MAIN_VALIDATION_EMPTY_PROPERTY'),
100 $property->getName()
101 ));
102 }
103 }
104
105 return $result;
106 }
107
108 private function validateProperty(ReflectionProperty $property, object $object): Generator
109 {
110 $attributes = $this->getValidationAttributes($property);
111
112 $name = $property->getName();
113 $value = $property->getValue($object);
114
115 yield from $this->validateValue($value, $name, $attributes);
116 }
117
118 private function validateValue(mixed $value, string $name, array $attributes): Generator
119 {
120 foreach ($attributes as $attribute)
121 {
122 $attributeInstance = $attribute->newInstance();
123
124 if ($attributeInstance instanceof Validatable)
125 {
126 yield from $this->setErrorCodes(
127 $name,
128 $this->validateValidatableProperty($value, $attributeInstance)
129 );
130 }
131 elseif ($attributeInstance instanceof PropertyValidationAttributeInterface)
132 {
133 yield from $this->setErrorCodes(
134 $name,
135 $attributeInstance->validateProperty($value)->getErrors()
136 );
137 }
138 }
139 }
140
141 private function validateValidatableProperty(mixed $value, Validatable $attributeInstance): Generator
142 {
143 if ($value === null)
144 {
145 return;
146 }
147
148 if (!$attributeInstance->iterable)
149 {
150 if (!is_object($value))
151 {
152 throw new ArgumentException('Only objects can be marked as Validatable');
153 }
154
155 yield from $this->validate($value)->getErrors();
156
157 return;
158 }
159
160 if (!is_iterable($value))
161 {
162 throw new ArgumentException('Only iterable values can be marked as Validatable when "iterable" is true');
163 }
164
165 foreach ($value as $i => $item)
166 {
167 if (!is_object($item))
168 {
169 throw new ArgumentException('Only objects can be Validatable inside an iterable');
170 }
171
172 $attributeErrors = $this->validate($item)->getErrors();
173
174 yield from $this->setErrorCodes((string)$i, $attributeErrors);
175 }
176 }
177
178 private function setErrorCodes(string $name, iterable $errors): Generator
179 {
180 foreach ($errors as $error)
181 {
182 if ($error instanceof ValidationError)
183 {
184 $error->setCode($name);
185 }
186
187 yield $error;
188 }
189 }
190
191 private function getValidationAttributes(ReflectionParameter|ReflectionProperty $parameter): array
192 {
193 return array_merge(
194 $parameter->getAttributes(Validatable::class, ReflectionAttribute::IS_INSTANCEOF),
195 $parameter->getAttributes(PropertyValidationAttributeInterface::class, ReflectionAttribute::IS_INSTANCEOF)
196 );
197 }
198}
$type
Определения options.php:106
validateParameter(ReflectionParameter $parameter, mixed $value)
Определения ValidationService.php:33
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$errors
Определения iblock_catalog_edit.php:74
$name
Определения menu_edit.php:35
$value
Определения Param.php:39
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$i
Определения factura.php:643
$error
Определения subscription_card_product.php:20