3namespace Bitrix\Catalog\Controller;
5use Bitrix\Catalog\Access\ActionDictionary;
6use Bitrix\Catalog\Config\State;
7use Bitrix\Catalog\Controller\Product\SkuDeferredCalculations;
8use Bitrix\Catalog\Model\Event;
9use Bitrix\Catalog\ProductTable;
12use Bitrix\Main\Application;
13use Bitrix\Main\DB\SqlQueryException;
14use Bitrix\Main\Engine;
15use Bitrix\Main\Engine\Response\DataType\Page;
18use Bitrix\Main\ORM\Data\DataManager;
19use Bitrix\Main\Result;
20use Bitrix\Main\Engine\ActionFilter\Scope;
21use Bitrix\Main\UI\PageNavigation;
22use Bitrix\Rest\Event\EventBindInterface;
23use Bitrix\Rest\RestException;
40 'getSkuTreeProperties' => [
53 if (
$action->getName() ===
'add')
57 else if (
$action->getName() ===
'update')
61 else if (
$action->getName() ===
'getfieldsbyfilter')
68 $this->addErrors(
$result->getErrors());
78 return parent::processBeforeAction(
$action);
107 $arguments =
$action->getArguments();
109 $fields = $arguments[
'fields'];
110 $productId = $arguments[
'id'];
120 $iblockIdOrigin =
$fields[
'iblockId'] ??
null;
121 if ($iblockIdOrigin !==
null)
123 $iblockIdOrigin = (int)$iblockIdOrigin;
126 if ($iblockIdOrigin && $iblockIdOrigin !== $element[
'IBLOCK_ID'])
131 'Product - %d is not exists in catalog - %d', $productId , $iblockIdOrigin
137 if (!isset(
$fields[
'iblockId']))
139 $arguments[
'fields'][
'iblockId'] = $element[
'IBLOCK_ID'];
140 $action->setArguments($arguments);
154 $arguments =
$action->getArguments();
156 $filter = $arguments[
'filter'] ?? [];
159 $result->addError(
new Error(
'Incorrect filter format'));
163 $filter[
'productType'] = static::TYPE;
164 $arguments[
'filter'] =
$filter;
165 $action->setArguments($arguments);
171 public function getFieldsByFilterAction(
$filter): ?
array
174 $view = $this->getViewManager()
176 $r = $view->getFieldsByFilter(
$filter);
180 $this->addErrors($r->getErrors());
201 $pageNavigation ??
false,
202 array(
'ID',
'IBLOCK_ID')
206 $rawRows[$row[
'ID']] = $row;
207 $elementIds[] = $row[
'ID'];
216 in_array(
'IBLOCK_SECTION',
$select,
true)
217 || in_array(
'*',
$select,
true)
223 'IBLOCK_ID' =>
$filter[
'IBLOCK_ID'],
226 $iterator = \CIBlockElement::GetList([], $elementFilter,
false,
false,
$select);
229 $rawRows[$row[
'ID']] += $row;
235 self::attachIblockSections($rawRows);
258 bool $__calculateTotalCount =
true
270 $allProperties = isset($groupFields[
'elementFields'][
'PROPERTY_*']);
273 unset($groupFields[
'elementFields'][
'PROPERTY_*']);
277 $elementFields = array_keys($groupFields[
'elementFields']);
283 $items = self::perfGetList(
287 self::getNavData($pageNavigation->
getOffset())
302 if ($allProperties || !empty($propertyIds))
304 self::attachPropertyValues($list, (
int)
$filter[
'IBLOCK_ID'], $propertyIds);
308 if ($__calculateTotalCount)
321 $this->addErrors($r->getErrors());
333 $this->addErrors(
$result->getErrors());
342 $this->addErrors(
$result->getErrors());
357 $this->addErrors(
$result->getErrors());
362 if (isset(
$fields[
'IBLOCK_SECTION_ID']) && (
int)
$fields[
'IBLOCK_SECTION_ID'] > 0)
371 $this->addErrors(
$result->getErrors());
380 $this->addErrors(
$result->getErrors());
395 $elementFields = $groupFields[
'elementFields'];
408 $conn = Application::getConnection();
409 $conn->startTransaction();
417 $result->addError(
new Error(
'Internal error adding product. Try adding again.'));
422 $conn->rollbackTransaction();
423 $this->addErrors(
$result->getErrors());
427 $conn->commitTransaction();
429 $id =
$result->getData()[
'ID'];
432 'ELEMENT' => $this->
get($id),
441 $this->addErrors(
$result->getErrors());
447 $fields[
'IBLOCK_ID'] ??= $element[
'IBLOCK_ID'];
452 $this->addErrors(
$result->getErrors());
457 $sectionId = (int)(
$fields[
'IBLOCK_SECTION_ID'] ??
null);
461 $element[
'IBLOCK_ID'],
466 $this->addErrors(
$result->getErrors());
482 $elementFields = $groupFields[
'elementFields'];
491 $elementFieldsUpdate =
500 if (!empty($elementFieldsUpdate))
503 $elementFieldsUpdate + [
'ID' => $id]
507 $this->addErrors(
$result->getErrors());
515 || !empty($elementFieldsUpdate)
520 $conn = Application::getConnection();
521 $conn->startTransaction();
524 $result = $productService->update(
532 $result->addError(
new Error(
'Internal error updating product. Try updating again.'));
537 $conn->rollbackTransaction();
538 $this->addErrors(
$result->getErrors());
542 $conn->commitTransaction();
546 'ELEMENT' => $this->
get($id),
555 $this->addErrors(
$result->getErrors());
564 $this->addErrors(
$result->getErrors());
569 $conn = Application::getConnection();
570 $conn->startTransaction();
573 if (!\CIBlockElement::Delete($id))
575 $ex = self::getApplication()->GetException();
578 $result->addError(
new Error($ex->GetString(), $ex->GetId()));
582 $result->addError(
new Error(
'delete iBlockElement error'));
589 $result->addError(
new Error(
'Internal error deleting product. Try deleting again.'));
594 $conn->commitTransaction();
600 $conn->rollbackTransaction();
601 $this->addErrors(
$result->getErrors());
609 $productId = (int)(
$fields[
'PRODUCT_ID'] ??
null);
610 $fieldName =
$fields[
'FIELD_NAME'];
617 $this->addErrors(
$result->getErrors());
626 'NAME' => $fieldName,
627 'IBLOCK_ID' => $element[
'IBLOCK_ID'],
635 'IBLOCK_ID' => $element[
'IBLOCK_ID'],
636 '=ID' => $element[
'ID'],
637 'CHECK_PERMISSIONS' =>
'N',
649 if (isset(
$res[$fieldName]))
655 if (is_array($res[$fieldName.
"_VALUE"]))
657 $list = $res[$fieldName .
'_VALUE'];
658 \Bitrix\Main\Type\Collection::normalizeArrayValuesByInt($list);
661 $files = array_merge($files, $list);
667 $files[] = (int)$res[$fieldName.
"_VALUE"];
673 if (!in_array($id,
$files))
679 $file = \CFile::GetFileArray($id);
680 if (!is_array($file))
688 $result->addError(
new Error(
'Name file field is not available'));
693 return \Bitrix\Main\Engine\Response\BFile::createByFileId($file[
'ID']);
697 $this->addErrors(
$result->getErrors());
706 return function() use (
$filter)
708 return (
int)\CIBlockElement::GetList([],
$filter, []);
714 return \Bitrix\Catalog\Model\Product::getTabletClassName();
731 if (preg_match(
'/^(PROPERTY_\d+)$/',
$name))
737 $elementFields[
$name] = $value;
745 'elementFields'=>$elementFields
753 if (State::isUsedInventoryManagement())
755 unset(
$result[
'QUANTITY_TRACE']);
763 $singleProperties = [];
772 '@PROPERTY_TYPE' => [
788 if ((
string)$row[
'USER_TYPE'] !==
'')
793 $singleProperties[
'PROPERTY_' . $row[
'ID']] =
true;
805 isset($singleProperties[
$name])
806 && isset($value[
'VALUE'])
807 && is_array($value[
'VALUE'])
840 foreach (
$fields as $propertyId=>$value)
844 if(isset($value[
'VALUE']))
846 if(isset($value[
'VALUE_ID']))
849 $valueId=$value[
'VALUE_ID'];
850 unset($value[
'VALUE_ID']);
851 $property[$valueId]=$value;
863 if(is_array($value) &&
count($value)>0)
865 foreach ($value as $item)
867 if(isset($item[
'VALUE_ID']))
870 $valueId = $item[
'VALUE_ID'];
871 unset($item[
'VALUE_ID']);
872 $property[$valueId]=$item;
883 if(
count($property)>0)
885 $result[$propertyId]=$property;
896 if ($id > 0 &&
$iblockId > 0 && !empty($propertyValues))
898 $r = \CIBlockElement::GetProperty(
904 'CHECK_PERMISSIONS' =>
'N',
908 while ($property = $r->Fetch())
912 && !array_key_exists($property[
'ID'], $propertyValues)
915 $fields[$property[
'ID']] ??= [];
918 'VALUE_ID' => $property[
'PROPERTY_VALUE_ID'],
919 'VALUE' => $property[
'VALUE'],
920 'DESCRIPTION' => $property[
'DESCRIPTION'],
924 unset($property, $r);
955 $row[
'ID'] = (int)$row[
'ID'];
956 $row[
'IBLOCK_ID'] = (int)$row[
'IBLOCK_ID'];
962 protected function get($id)
964 $row = \CIBlockElement::getList(
984 self::attachIblockSections(
$result);
985 self::attachPropertyValues(
$result, (
int)$row[
'IBLOCK_ID']);
1004 if (isset(
$fields[
'SECTION_ID']))
1006 $section = \CIBlockSection::GetByID(
$fields[
'SECTION_ID'])->Fetch();
1007 if (!isset($section[
'ID']))
1009 $r->addError(
new Error(
'Section is not exists'));
1012 if (isset(
$fields[
'MODIFIED_BY']))
1014 $user = \CUser::GetByID(
$fields[
'MODIFIED_BY'])->Fetch();
1015 if (!isset(
$user[
'ID']))
1017 $r->addError(
new Error(
'User modifiedBy is not exists'));
1020 if (isset(
$fields[
'CREATED_BY']))
1022 $user = \CUser::GetByID(
$fields[
'CREATED_BY'])->Fetch();
1023 if (!isset(
$user[
'ID']))
1025 $r->addError(
new Error(
'User createdBy is not exists'));
1028 if (isset(
$fields[
'PURCHASING_CURRENCY']))
1033 $r->addError(
new Error(
'Currency purchasingCurrency is not exists'));
1039 if (!isset(
$user[
'ID']))
1041 $r->addError(
new Error(
'VAT vatId is not exists'));
1051 'DATE_ACTIVE_FROM' =>
'ACTIVE_FROM',
1052 'DATE_ACTIVE_TO' =>
'ACTIVE_TO',
1055 foreach ($dateAlias as $alias =>
$name)
1086 $listIds = array_keys(
$result);
1087 foreach ($listIds as $id)
1089 $result[$id][
'IBLOCK_SECTION'] = [];
1093 $filter->whereNull(
'ADDITIONAL_PROPERTY_ID');
1096 $filter->whereIn(
'IBLOCK_ELEMENT_ID', $pageIds);
1097 $iterator = Iblock\SectionElementTable::getList([
1099 'IBLOCK_ELEMENT_ID',
1100 'IBLOCK_SECTION_ID',
1106 $id = (int)$row[
'IBLOCK_ELEMENT_ID'];
1107 $result[$id][
'IBLOCK_SECTION'][] = (int)$row[
'IBLOCK_SECTION_ID'];
1129 $propertyFilter = !empty($propertyIds) ? [
'ID' => $propertyIds] : [];
1131 $propertyValues = [];
1132 \CIBlockElement::getPropertyValuesArray(
1135 [
'ID' => array_keys(
$result)],
1137 [
'USE_PROPERTY_ID' =>
'Y']
1142 if (isset($propertyValues[
$k]))
1144 foreach ($propertyValues[
$k] as $propId =>
$fields)
1148 if (isset(
$fields[
'PROPERTY_VALUE_ID']))
1152 if (
$fields[
'MULTIPLE'] ===
'Y')
1154 if (is_array(
$fields[
'PROPERTY_VALUE_ID']))
1156 foreach (
$fields[
'PROPERTY_VALUE_ID'] as
$i => $item)
1159 'VALUE' =>
$fields[
'VALUE_ENUM_ID'][
$i],
1160 'VALUE_ENUM' =>
$fields[
'VALUE_ENUM'][
$i],
1161 'VALUE_ID' =>
$fields[
'PROPERTY_VALUE_ID'][
$i],
1169 'VALUE' =>
$fields[
'VALUE_ENUM_ID'],
1170 'VALUE_ENUM' =>
$fields[
'VALUE_ENUM'],
1171 'VALUE_ID' =>
$fields[
'PROPERTY_VALUE_ID']
1177 if (
$fields[
'MULTIPLE'] ===
'Y')
1179 if (is_array(
$fields[
'PROPERTY_VALUE_ID']))
1181 foreach (
$fields[
'PROPERTY_VALUE_ID'] as
$i => $item)
1185 'VALUE_ID' =>
$fields[
'PROPERTY_VALUE_ID'][
$i]
1194 'VALUE_ID' =>
$fields[
'PROPERTY_VALUE_ID']
1200 $result[
$k][
'PROPERTY_' . $propId] = $value;
1203 elseif (!empty($propertyIds))
1209 foreach ($propertyIds as $propId)
1211 $result[
$k][
'PROPERTY_' . $propId] =
null;
1221 if(
$name ==
'getfieldsbyfilter'
1222 ||
$name ==
'download'
1229 $r = parent::checkPermissionEntity(
$name);
1245 'QUANTITY_RESERVED',
1257 'RECUR_SCHEME_LENGTH',
1258 'RECUR_SCHEME_TYPE',
1261 'QUANTITY_TRACE_RAW',
1267 if ($this->accessController->check(ActionDictionary::ACTION_PRODUCT_PURCHASE_INFO_VIEW))
1269 array_push(
$result,
'PURCHASING_PRICE',
'PURCHASING_CURRENCY');
1280 if (
$name ===
"DETAIL_PICTURE")
1292 elseif (!preg_match(
"/^PROPERTY_(.+)\$/",
$name, $match))
1298 $property = \CIBlockProperty::GetPropertyArray($match[1],
$iblockId);
1312 $this->addErrors(
$result->getErrors());
1317 $iblockProperty = new \CIBlockProperty();
1321 'IBLOCK_ID' =>
$fields[
'IBLOCK_ID'],
1323 'SORT' =>
$fields[
'SORT'] ?? 100,
1324 'CODE' =>
$fields[
'CODE'] ??
'',
1325 'MULTIPLE' => (
$fields[
'MULTIPLE'] ===
'Y') ?
'Y' :
'N',
1326 'IS_REQUIRED'=> (
$fields[
'IS_REQUIRED'] ===
'Y') ?
'Y' :
'N',
1327 'SECTION_PROPERTY'=>
'N',
1333 $this->addError(
new Error($iblockProperty->getLastError()));
1340 'CONTROL_ID' =>
'PROPERTY_' . $newId
1355 !$this->accessController->check(ActionDictionary::ACTION_CATALOG_READ)
1356 && !$this->accessController->check(ActionDictionary::ACTION_PRICE_EDIT)
1357 && !$this->accessController->check(ActionDictionary::ACTION_CATALOG_VIEW)
1371 $iblockName = \CIBlock::GetArrayByID(
$iblockId,
'NAME');
1372 if (empty($iblockName))
1374 $result->addError(
new Error(
'Iblock Not Found', 200040300000));
1398 if (!$this->accessController->check(ActionDictionary::ACTION_PRODUCT_ADD))
1400 $result->addError(
new Error(
'Access Denied', 200040300040));
1430 if (!$this->accessController->check(ActionDictionary::ACTION_PRODUCT_EDIT))
1432 $result->addError(
new Error(
'Access Denied', 200040300040));
1448 if (!$r->isSuccess())
1455 $r->addError(
new Error(
'Access Denied', 200040300040));
1466 if (!$r->isSuccess())
1473 $badBlock = !\CIBlockElementRights::UserHasRightTo(
$iblockId, $elementId, self::IBLOCK_ELEMENT_EDIT);
1477 $badBlock = !\CIBlockRights::UserHasRightTo(
$iblockId,
$iblockId, self::IBLOCK_ELEMENT_EDIT);
1482 $r->addError(
new Error(
'Access Denied', 200040300043));
1506 if (!$this->accessController->check(ActionDictionary::ACTION_PRODUCT_DELETE))
1508 $result->addError(
new Error(
'Access Denied', 200040300040));
1517 if (!$r->isSuccess())
1522 if (!\CIBlockElementRights::UserHasRightTo(
$iblockId, $elementId, self::IBLOCK_ELEMENT_DELETE))
1524 $r->addError(
new Error(
'Access Denied', 200040300040));
1533 if (!$r->isSuccess())
1538 if (!\CIBlockElementRights::UserHasRightTo(
$iblockId, $elementId, self::IBLOCK_ELEMENT_READ))
1540 $r->addError(
new Error(
'Access Denied', 200040300040));
1550 if (!$r->isSuccess())
1557 $r->addError(
new Error(
'Access Denied', 200040300030));
1567 if (!$r->isSuccess())
1572 if (!\CIBlockSectionRights::UserHasRightTo(
1575 self::IBLOCK_ELEMENT_SECTION_BIND
1578 $r->addError(
new Error(
'Access Denied', 200040300050));
1597 return [self::class,
'processItemEvent'];
1607 throw new RestException(
'event object not found trying to process event');
1612 $id =
$event->getParameter(
'id');
1616 $item =
$event->getParameter(
'id');
1617 $id = is_array($item) ? $item[
'ID']: $item;
1622 throw new RestException(
'id not found trying to process event');
1627 $type = $product[
'TYPE'] ??
null;
1631 throw new RestException(
'type is not specified trying to process event');
1646 $model = \Bitrix\Catalog\Model\Product::class;
1649 v2\
Event\Event::ENTITY_PRODUCT,
1650 v2\
Event\Event::METHOD_UPDATE,
1655 Event::makeEventName($model,DataManager::EVENT_ON_AFTER_ADD) =>
$entity->getModule().
'.'.
$entity->getName().
'.on.add',
1656 $updateEventName =>
$entity->getModule().
'.'.
$entity->getName().
'.on.update',
1657 Event::makeEventName($class,DataManager::EVENT_ON_DELETE) =>
$entity->getModule().
'.'.
$entity->getName().
'.on.delete',
if($strVal !='') $productFields
getErrorEntityNotExists()
getErrorReadAccessDenied()
prepareFieldsForAdd(array $fields)
checkPermissionIBlockElementModify($iblockId, $elementId)
checkModifyPermissionEntity()
static getCallbackRestEvent()
splitFieldsByEntity($fields)
listAction(PageNavigation $pageNavigation, array $select=[], array $filter=[], array $order=[], bool $__calculateTotalCount=true)
checkPermissionCatalogProductUpdate()
checkReadPermissionEntity()
checkPermissionIBlockElementUpdate(int $iblockId, int $elementId)
static attachPropertyValues(array &$result, int $iblockId, array $propertyIds=[])
prepareFieldsForUpdate(array $fields)
processBeforeAdd(Engine\Action $action)
checkPermissionIBlockElementSectionBindUpdate(int $iblockId, $iblockSectionId)
preparePropertyFieldsUpdate($fields)
checkPermissionIBlockElementAdd(int $iblockId)
processBeforeAction(Engine\Action $action)
trait SkuDeferredCalculations
checkPermissionIBlockModify($iblockId)
processBeforeUpdate(Engine\Action $action)
checkPermissionCatalogProductDelete()
downloadAction(array $fields)
checkFieldsDownload($fields)
processAfterAction(Engine\Action $action, $result)
checkPermissionIBlockElementList($iblockId)
updateAction(int $id, array $fields)
preparePropertyFields($fields)
processBeforeGetFieldsByFilter(Engine\Action $action)
prepareDateAliases(array $fields)
static processItemEvent(array $params, array $handler)
fillPropertyFieldsDefaultPropertyValues($id, $iblockId, $propertyValues)
checkPermissionUpdate(int $iblockId, int $elementId)
static attachIblockSections(array &$result)
checkPermissionIBlockElementGet(int $iblockId, int $elementId)
prepareProductFields(array $fields)
existsIblock(int $iblockId)
checkPermissionDelete(int $iblockId, int $elementId)
checkPermissionEntity($name, $arguments=[])
checkPermissionAdd(int $iblockId)
addPropertyAction($fields)
checkPermissionIBlockElementDelete(int $iblockId, int $elementId)
getAllowedFieldsProduct()
checkPermissionIBlockElementSectionBindModify($iblockId, $iblockSectionId)
checkPermissionCatalogProductAdd()
static getCacheItem($id, bool $load=false)
static makeEventName(string $entity, string $method, string $stage)
static getRow(array $parameters)
static getList(array $parameters=array())
static GetByID($currency)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
isActionWithDefferedCalculation(Action $action)
processAfterDeferredCalculationAction()
processBeforeDeferredCalculationAction()
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']