1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
BaseEntity.php
См. документацию.
1<?php
2
3namespace Bitrix\Catalog\v2;
4
5use Bitrix\Catalog\v2\Fields\FieldStorage;
6use Bitrix\Catalog\v2\Fields\TypeCasters\MapTypeCaster;
7use Bitrix\Catalog\v2\Fields\TypeCasters\NullTypeCaster;
8use Bitrix\Main\Application;
9use Bitrix\Main\DB\SqlException;
10use Bitrix\Main\Error;
11use Bitrix\Main\Result;
12
21abstract class BaseEntity
22{
25
27 private $fieldStorage;
29 private $parentCollection;
30
31 // ToDo do we need $repository for every base entity?
32 public function __construct(RepositoryContract $repository = null)
33 {
34 $this->entityRepository = $repository;
35 }
36
37 protected function getFieldStorage(): FieldStorage
38 {
39 if ($this->fieldStorage === null)
40 {
41 $this->fieldStorage = $this->createFieldStorage();
42 }
43
44 return $this->fieldStorage;
45 }
46
47 protected function createFieldStorage(): FieldStorage
48 {
49 $fieldMap = $this->getFieldsMap();
50
51 if ($fieldMap === null)
52 {
53 $typeCaster = new NullTypeCaster();
54 }
55 else
56 {
57 $typeCaster = new MapTypeCaster($fieldMap);
58 }
59
60 return new FieldStorage($typeCaster);
61 }
62
63 public function initFields(array $fields): self
64 {
65 if (!empty($fields))
66 {
67 $this->getFieldStorage()->initFields($fields);
68 }
69
70 return $this;
71 }
72
73 public function setParentCollection(?BaseCollection $collection): self
74 {
75 $this->parentCollection = $collection;
76
77 return $this;
78 }
79
81 {
82 return $this->parentCollection;
83 }
84
85 public function getParent(): ?self
86 {
87 $collection = $this->getParentCollection();
88
89 if ($collection)
90 {
91 return $collection->getParent();
92 }
93
94 return null;
95 }
96
97 public function getHash(): string
98 {
99 return spl_object_hash($this);
100 }
101
102 public function setField(string $name, $value): self
103 {
104 return $this->setFieldNoDemand($name, $value);
105 }
106
107 public function setFieldNoDemand(string $name, $value): self
108 {
109 $this->getFieldStorage()->setField($name, $value);
110
111 return $this;
112 }
113
114 public function hasField(string $name): bool
115 {
116 return $this->getFieldStorage()->hasField($name);
117 }
118
119 public function getField(string $name)
120 {
121 return $this->getFieldStorage()->getField($name);
122 }
123
124 // ToDo make map to execute set{$name} instead of setField($name) to check each field limitations? e.g. price with setFields is string instead of float
125 public function setFields(array $fields): self
126 {
127 foreach ($fields as $name => $value)
128 {
129 $this->setField($name, $value);
130 }
131
132 return $this;
133 }
134
135 public function getFields(): array
136 {
137 return $this->getFieldStorage()->toArray();
138 }
139
140 public function getChangedFields(): array
141 {
142 return array_intersect_key($this->getFields(), $this->getFieldStorage()->getChangedFields());
143 }
144
145 public function hasChangedFields(): bool
146 {
147 return $this->getFieldStorage()->hasChangedFields();
148 }
149
150 public function isChanged(): bool
151 {
152 if ($this->hasChangedFields())
153 {
154 return true;
155 }
156
157 foreach ($this->getChildCollections() as $childCollection)
158 {
159 if ($childCollection->isChanged())
160 {
161 return true;
162 }
163 }
164
165 return false;
166 }
167
168 public function isNew(): bool
169 {
170 return $this->getId() === null;
171 }
172
173 public function getId(): ?int
174 {
175 return (int)$this->getField('ID') ?: null;
176 }
177
178 public function setId(int $id): self
179 {
180 return $this->setField('ID', $id);
181 }
182
183 public function remove(): self
184 {
185 $collection = $this->getParentCollection();
186
187 if ($collection)
188 {
189 $collection->remove($this);
190 }
191
192 return $this;
193 }
194
195 public function save(): Result
196 {
197 if ($parent = $this->getParent())
198 {
199 return $parent->save();
200 }
201
202 return $this->saveInternal();
203 }
204
205 protected function getFieldsMap(): ?array
206 {
207 return null;
208 }
209
216 public function saveInternal(): Result
217 {
218 $result = new Result();
219
220 if ($this->hasChangedFields())
221 {
222 $res = $this->saveInternalEntity();
223
224 if (!$res->isSuccess())
225 {
226 $result->addErrors($res->getErrors());
227 }
228 }
229
230 if ($result->isSuccess())
231 {
232 foreach ($this->getChildCollections() as $childCollection)
233 {
234 $res = $childCollection->saveInternal();
235
236 if (!$res->isSuccess())
237 {
238 $result->addErrors($res->getErrors());
239 }
240 }
241 }
242
243 return $result;
244 }
245
246 protected function saveInternalEntity(): Result
247 {
248 $result = $this->entityRepository->save($this);
249
250 if ($result->isSuccess())
251 {
252 $this->clearChangedFields();
253 }
254
255 return $result;
256 }
257
261 public function deleteInternal(): Result
262 {
263 $result = $this->entityRepository->delete($this);
264
265 if ($result->isSuccess())
266 {
267 foreach ($this->getChildCollections(true) as $childCollection)
268 {
269 $res = $childCollection->deleteInternal();
270
271 if (!$res->isSuccess())
272 {
273 $result->addErrors($res->getErrors());
274 }
275 }
276 }
277
278 return $result;
279 }
280
285 final protected function getChildCollections(bool $initCollections = false): \Generator
286 {
287 $collectionPostfix = 'Collection';
288 $collectionPostfixLength = mb_strlen($collectionPostfix);
289 $parentCollection = "parent{$collectionPostfix}";
290
291 foreach ((new \ReflectionObject($this))->getProperties() as $property)
292 {
293 $propertyName = $property->getName();
294
295 if (
296 $propertyName !== $parentCollection
297 && mb_substr($propertyName, -$collectionPostfixLength) === $collectionPostfix
298 )
299 {
300 $property->setAccessible(true);
301 $value = $property->getValue($this);
302
303 if ($value === null && $initCollections)
304 {
305 $propertyGetter = "get{$propertyName}";
306
307 if (is_callable([$this, $propertyGetter]))
308 {
309 $value = $this->$propertyGetter();
310 }
311 }
312
313 if ($value instanceof BaseCollection)
314 {
315 yield $value;
316 }
317 }
318 }
319 }
320
325 public function clearChangedFields(): self
326 {
327 $this->getFieldStorage()->clearChanged();
328
329 return $this;
330 }
331}
__construct(RepositoryContract $repository=null)
Определения BaseEntity.php:32
getChildCollections(bool $initCollections=false)
Определения BaseEntity.php:285
initFields(array $fields)
Определения BaseEntity.php:63
hasField(string $name)
Определения BaseEntity.php:114
createFieldStorage()
Определения BaseEntity.php:47
getParentCollection()
Определения BaseEntity.php:80
setFieldNoDemand(string $name, $value)
Определения BaseEntity.php:107
setField(string $name, $value)
Определения BaseEntity.php:102
getField(string $name)
Определения BaseEntity.php:119
setFields(array $fields)
Определения BaseEntity.php:125
setParentCollection(?BaseCollection $collection)
Определения BaseEntity.php:73
setId(int $id)
Определения BaseEntity.php:178
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$name
Определения menu_edit.php:35
$fields
Определения yandex_run.php:501