Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
field.php
1<?
2namespace Bitrix\Lists\Entity;
3
9
10class Field implements Controllable, Errorable
11{
13
14 const ERROR_SAVE_FIELD = "ERROR_SAVE_FIELD";
15 const ERROR_UPDATE_FIELD = "ERROR_UPDATE_FIELD";
16
17 private $param;
18 private $params = [];
19 private $fieldList = [];
20
21 private $iblockId;
22
23 public function __construct(Param $param)
24 {
25 $this->param = $param;
26 $this->params = $param->getParams();
27
28 $this->fieldList = ["NAME", "IS_REQUIRED", "MULTIPLE", "TYPE", "SORT", "DEFAULT_VALUE", "LIST",
29 "USER_TYPE_SETTINGS", "LIST_TEXT_VALUES", "LIST_DEF", "CODE", "SETTINGS", "ROW_COUNT",
30 "COL_COUNT", "LINK_IBLOCK_ID"];
31
32 $this->iblockId = Utils::getIblockId($this->params);
33
34 $this->errorCollection = new ErrorCollection;
35 }
36
37 public function add()
38 {
39 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID", ["FIELDS" => ["NAME", "TYPE"]]]);
40 if ($this->param->hasErrors())
41 {
42 $this->errorCollection->add($this->param->getErrors());
43 return false;
44 }
45
46 $fields = $this->getFields();
47 $this->validateFields($fields);
48 if ($this->hasErrors())
49 {
50 return false;
51 }
52
53 $object = new \CList($this->iblockId);
54
55 if (!$object->is_field($fields["TYPE"]))
56 {
57 if (!empty($fields["CODE"]))
58 {
59 $property = $this->getProperty($this->iblockId, $fields["CODE"]);
60 if (!empty($property) && is_array($property))
61 {
62 $this->errorCollection->setError(new Error("Property already exists", self::ERROR_SAVE_FIELD));
63 return false;
64 }
65 }
66 else
67 {
68 $this->errorCollection->setError(new Error("Please fill the code fields", self::ERROR_SAVE_FIELD));
69 }
70 }
71
72 $result = $object->addField($fields);
73
74 if ($result)
75 {
76 global $CACHE_MANAGER;
77 $CACHE_MANAGER->clearByTag("lists_list_".$this->iblockId);
78 return $result;
79 }
80 else
81 {
82 $this->errorCollection->setError(new Error("Error saving the field", self::ERROR_SAVE_FIELD));
83 return false;
84 }
85 }
86
87 public function get(array $navData = [])
88 {
89 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID"]);
90 if ($this->param->hasErrors())
91 {
92 $this->errorCollection->add($this->param->getErrors());
93 return [];
94 }
95
96 $fields = [];
97
98 if (!empty($this->params["FIELD_ID"]))
99 {
100 $object = new \CListFieldList($this->iblockId);
101 $fieldsObject = $object->getByID($this->params["FIELD_ID"]);
102 if ($fieldsObject)
103 {
104 $fieldData = $fieldsObject->getArray();
105 $fields = [$fieldData["TYPE"] => $fieldData];
106 }
107 }
108 else
109 {
110 $object = new \CList($this->iblockId);
111 $fields = $object->getFields();
112 }
113
114 return $this->adjustmentFields($fields);
115 }
116
117 public function update()
118 {
119 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID",
120 "FIELD_ID", ["FIELDS" => ["NAME", "TYPE"]]]);
121 if ($this->param->hasErrors())
122 {
123 $this->errorCollection->add($this->param->getErrors());
124 return [];
125 }
126
127 $fields = $this->getFields();
128 $this->validateFields($fields);
129 if ($this->hasErrors())
130 {
131 return false;
132 }
133
134 $object = new \CList($this->iblockId);
135 if (!$this->canChangeField($fields["TYPE"]))
136 {
137 return false;
138 }
139
140 $result = $object->updateField($this->params["FIELD_ID"], $fields);
141
142 if ($result)
143 {
144 global $CACHE_MANAGER;
145 $CACHE_MANAGER->clearByTag("lists_list_".$this->iblockId);
146 return $result;
147 }
148 else
149 {
150 $this->errorCollection->setError(new Error("Error update the field", self::ERROR_UPDATE_FIELD));
151 return false;
152 }
153 }
154
155 public function delete()
156 {
157 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID", "FIELD_ID"]);
158 if ($this->param->hasErrors())
159 {
160 $this->errorCollection->add($this->param->getErrors());
161 return [];
162 }
163
164 $object = new \CList($this->iblockId);
165 $object->deleteField($this->params["FIELD_ID"]);
166 $object->save();
167
168 global $CACHE_MANAGER;
169 $CACHE_MANAGER->clearByTag('lists_list_'.$this->iblockId);
170
171 return true;
172 }
173
174 public function getAvailableTypes()
175 {
176 $this->param->checkRequiredInputParams(["IBLOCK_CODE", "IBLOCK_ID"]);
177 if ($this->param->hasErrors())
178 {
179 $this->errorCollection->add($this->param->getErrors());
180 return [];
181 }
182
183 $fieldId = (!empty($this->params["FIELD_ID"]) ? $this->params["FIELD_ID"] : "");
184 $object = new \CList($this->iblockId);
185 return $object->getAvailableTypes($fieldId);
186 }
187
188 private function getFields()
189 {
190 $fields = [];
191
192 foreach ($this->params["FIELDS"] as $fieldId => $fieldValue)
193 {
194 if (!in_array($fieldId, $this->fieldList))
195 {
196 continue;
197 }
198
199 if (is_array($fieldValue))
200 {
201 $fieldValue = array_change_key_case($fieldValue, CASE_UPPER);
202 }
203
204 $fields[$fieldId] = $fieldValue;
205 }
206
207 if (!is_array($fields["LIST"]))
208 {
209 $fields["LIST"] = [];
210 }
211 if (!empty($fields["LIST_TEXT_VALUES"]))
212 {
213 $maxSort = 0;
214 $listMap = array();
215 foreach ($fields["LIST"] as $key => $enum)
216 {
217 if ($enum["SORT"] > $maxSort)
218 {
219 $maxSort = intval($enum["SORT"]);
220 }
221 $listMap[trim($enum["VALUE"], " \t\n\r")] = $enum["ID"];
222 }
223 foreach (explode("\n", $fields["LIST_TEXT_VALUES"]) as $valueLine)
224 {
225 $value = trim($valueLine, " \t\n\r");
226 if ((string) $value <> '' && !isset($listMap[$value]))
227 {
228 $maxSort += 10;
229 $listMap[$value] = "m".$maxSort;
230 $fields["LIST"]["m".$maxSort] = array(
231 "SORT" => $maxSort,
232 "VALUE" => $value,
233 );
234 }
235 }
236 }
237 if (!empty($fields["LIST_DEF"]) && is_array($fields["LIST_DEF"]))
238 {
239 foreach ($fields["LIST"] as $key => $enum)
240 {
241 $fields["LIST"][$key]["DEF"] = "N";
242 }
243 foreach ($fields["LIST_DEF"] as $def)
244 {
245 $def = intval($def);
246 if ($def > 0 && isset($fields["LIST"][$def]))
247 {
248 $fields["LIST"][$def]["DEF"] = "Y";
249 }
250 }
251 }
252
253 return $fields;
254 }
255
256 private function canChangeField($type)
257 {
258 $objectFieldList = new \CListFieldList($this->iblockId);
259 $fieldObject = $objectFieldList->getByID($this->params["FIELD_ID"]);
260 if ($fieldObject)
261 {
262 $oldType = $fieldObject->getTypeID();
263 if ($oldType != $type)
264 {
265 $this->errorCollection->setError(new Error("Field type can not be changed", self::ERROR_UPDATE_FIELD));
266 return false;
267 }
268 }
269 return true;
270 }
271
272 private function validateFields($fields)
273 {
274 if (isset($fields["SETTINGS"]["ADD_READ_ONLY_FIELD"]) && $fields["SETTINGS"]["ADD_READ_ONLY_FIELD"] == "Y")
275 {
276 $defaultValueError = false;
277 switch ($fields["TYPE"])
278 {
279 case "SORT":
280 $defaultValueError = ($fields["DEFAULT_VALUE"] == '');
281 break;
282 case "L":
283 if (is_array($fields["LIST_DEF"]))
284 {
285 $defaultValueError = (empty(current($fields["LIST_DEF"])));
286 }
287 break;
288 case "S:HTML":
289 $defaultValueError = (empty($fields["DEFAULT_VALUE"]["TEXT"]));
290 break;
291 default:
292 $defaultValueError = (empty($fields["DEFAULT_VALUE"]));
293 }
294 if ($defaultValueError)
295 {
296 $this->errorCollection->setError(new Error(
297 "The default value of the field \"".$fields["NAME"]."\" is required", self::ERROR_SAVE_FIELD));
298 }
299 }
300
301 $formatError = "";
302 if ($fields["TYPE"] == "PREVIEW_PICTURE")
303 {
304 $fields["DEFAULT_VALUE"]["METHOD"] = "resample";
305 $fields["DEFAULT_VALUE"]["COMPRESSION"] = intval(\COption::getOptionString("main", "image_resize_quality", "95"));
306 }
307 elseif ($fields["TYPE"] == "S:Date")
308 {
309 if (!empty($fields["DEFAULT_VALUE"]) && !CheckDateTime($fields["DEFAULT_VALUE"], FORMAT_DATE))
310 {
311 $formatError = "The default value of the field \"".$fields["NAME"]."\" is incorrect";
312 }
313 }
314 elseif($fields["TYPE"] == "S:DateTime")
315 {
316 if(!empty($fields["DEFAULT_VALUE"]) && !CheckDateTime($fields["DEFAULT_VALUE"]))
317 {
318 $formatError = "The default value of the field \"".$fields["NAME"]."\" is incorrect";
319 }
320 }
321 if (preg_match("/^(G|G:|E|E:)/", $fields["TYPE"]))
322 {
323 $blocks = \CLists::getIBlocks($this->params["IBLOCK_TYPE_ID"], "Y", $this->params["SOCNET_GROUP_ID"]);
324 if (mb_substr($fields["TYPE"], 0, 1) == "G")
325 {
326 unset($blocks[$this->params["IBLOCK_ID"]]);
327 }
328 if (!array_key_exists($fields["LINK_IBLOCK_ID"], $blocks))
329 {
330 $formatError = "Incorrect lists specified for \"".$fields["NAME"]."\" property";
331 }
332 }
333 if ($formatError)
334 {
335 $this->errorCollection->setError(new Error(
336 "The default value of the field \"".$fields["NAME"]."\" is required", self::ERROR_SAVE_FIELD));
337 }
338 }
339
340 private function adjustmentFields($fields)
341 {
342 foreach ($fields as $fieldId => &$field)
343 {
344 if ($field["TYPE"] == "ACTIVE_FROM")
345 {
346 if ($field["DEFAULT_VALUE"] === "=now")
347 $field["DEFAULT_VALUE"] = ConvertTimeStamp(time()+\CTimeZone::getOffset(), "FULL");
348 elseif ($field["DEFAULT_VALUE"] === "=today")
349 $field["DEFAULT_VALUE"] = ConvertTimeStamp(time()+\CTimeZone::getOffset(), "SHORT");
350 }
351 elseif ($field["TYPE"] == "L")
352 {
353 $option = [];
354 $propertyEnum = \CIBlockProperty::getPropertyEnum($field["ID"]);
355 while ($listEnum = $propertyEnum->fetch())
356 {
357 if ($listEnum["DEF"] === "Y")
358 {
359 $field["DEFAULT_VALUE"] = $listEnum["ID"];
360 }
361 $option[$listEnum["ID"]] = $listEnum["VALUE"];
362 }
363 $field["DISPLAY_VALUES_FORM"] = $option;
364 }
365 elseif ($field["TYPE"] == "G")
366 {
367 $option = [];
368 $sections = \CIBlockSection::getTreeList(["IBLOCK_ID" => $field["LINK_IBLOCK_ID"]]);
369 while ($section = $sections->getNext())
370 $option[$section["ID"]] = str_repeat(" . ", $section["DEPTH_LEVEL"]).$section["~NAME"];
371 $field["DISPLAY_VALUES_FORM"] = $option;
372 }
373 elseif (preg_match("/^(E|E:)/", $field["TYPE"]))
374 {
375 $option = [];
376 $elements = \CIBlockElement::getList(["NAME"=>"ASC"],
377 ["IBLOCK_ID" => $field["LINK_IBLOCK_ID"]], false, false, ["ID", "NAME"]);
378 while ($element = $elements->fetch())
379 $option[$element["ID"]] = $element["NAME"];
380 $field["DISPLAY_VALUES_FORM"] = $option;
381 }
382 elseif ($field["TYPE"] == "N:Sequence")
383 {
384 $sequence = new \CIBlockSequence($field["IBLOCK_ID"], $field["ID"]);
385 $field["USER_TYPE_SETTINGS"]["VALUE"] = $sequence->getNext();
386 }
387 }
388
389 return $fields;
390 }
391
392 private function getProperty($iblockId, $code)
393 {
394 $queryObject = \CIBlockProperty::getList(array(), array("IBLOCK_ID" => $iblockId, "CODE" => $code));
395 return $queryObject->fetch();
396 }
397}
__construct(Param $param)
Definition field.php:23
static getIblockId(array $params)
Definition utils.php:13