Ответы пользователя по тегу 1С-Битрикс
  • Как в Битриксе записать последние изменения в свойство?

    @r_zaycev
    Нужно навешать обработчик на OnBeforeIBlockElementUpdate, потому что при OnIBlockElementUpdate нельзя делать CIBlockElement:Update() (это вызовет циклический вызов обработчика). При OnIBlockElementUpdate значения в changes нужно будет писать через SetPropertyValuesEx. Хотя с OnIBlockElementUpdate/SetPropertyValuesEx вариант вполне рабочий.

    Примерный код с OnBeforeIBlockElementUpdate:

    <?php
    
    AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", ["MyClass", "OnBeforeIBlockElementUpdateHandler"]);
    
    class MyClass {
        public static function OnBeforeIBlockElementUpdateHandler(&$arFields)
        {
            if ($arFields['IBLOCK_ID'] == 1) { // Проверяем на нужный ИБ
                $userId = $arFields["MODIFIED_BY"];
                $propValues = $arFields["PROPERTY_VALUES"];
                $propMap = [ // Массив полей, за которым следим в виде ID св-ва => тайтл
                    8 => "Some prop",
                ];
                $changesPropId = 9; // ID свойства changes
    
                $resOldElem = CIBlockElement::GetList(
                    [],
                    ["IBLOCK_ID" => $arFields["IBLOCK_ID"], "ID" => $arFields["ID"]],
                    false,
                    false,
                    array_map(function($propId) {
                        return "PROPERTY_{$propId}";
                    }, array_keys($propMap))
                )->Fetch();
    
                $newChanges = [];
    
                foreach ($propMap as $propId => $propTitle) {
                    $propValueKey = "PROPERTY_{$propId}_VALUE";
                    $oldPropValue = $resOldElem[$propValueKey];
                    $newPropValue = $propValues[$propId][array_key_first($propValues[$propId])]["VALUE"]; // Для множественных свойств нужна своя логика обработки
    
                    if ($oldPropValue != $newPropValue) { // Если значение из справочника, то его надо разыменовать, достать значение из ИБ/Хайлоад ИБ
                        $newChanges[] = "Юзер {$userId} изменил {$propTitle}: {$oldPropValue} -> {$newPropValue}";
                    }
                }
    
                if (!empty($newChanges)) {
                    $arFields['PROPERTY_VALUES'][$changesPropId] = array_merge($arFields['PROPERTY_VALUES'][$changesPropId], $newChanges);
                }
            }
        }
    }


    Решение так себе, потому что:
    a) множественных значений свойств
    b) некрасиво сработает со значениями из справочников
    c) захардкоженные ID свойств и их заголовки
    d) не достает имя пользователя

    Но, как старт для запила фичи дает, я думаю

    PS: Хранить изменения товара в самом товаре так себе идея, лучше завести отдельную таблицу с быстрым чтением и записью (HL-инфблоки подойдут) и сделать кастомный вывод истории в админке в карточке редактирования товара
    Ответ написан
  • Как вывести сумму заказа?

    @r_zaycev
    Дока

    <?php
    
    // Include Sale module 
    Bitrix\Main\Loader::includeModule("sale"); 
    
    // Query: Get all cart items for current user
    $res = CSaleBasket::GetList(
    	array(),
    	array(
    		"FUSER_ID" => CSaleBasket::GetBasketUserID(),
    		"LID" => SITE_ID,
    		"ORDER_ID" => NULL,
    		"CAN_BUY" => "Y"
    	),
    	false,
    	false,
    	array(
    		"QUANTITY",
    		"BASE_PRICE",
    		"PRICE",
    		"DISCOUNT_PRICE"
    	)
    );
    
    $totalPrice = 0;
    
    // Temp array with cart items
    $arItems = array();
    
    // Fetching query
    while($arFields = $res->Fetch()){
    	// Check for base price
    	if(!isset($arFields['BASE_PRICE']) || (float)$arFields['BASE_PRICE'] <= 0){
    		$arFields['BASE_PRICE'] = $arFields['PRICE'] + $arFields['DISCOUNT_PRICE'];
    	}
    	
    	// Calculate total price without discount
    	$totalPrice += $arFields["PRICE"] * $arFields["QUANTITY"];
    
    	$arItems[] = $arFields;
    }
    
    // Make array for discount calculation
    $arOrder = array(
    	'SITE_ID' => SITE_ID,
    	'ORDER_PRICE' => $totalPrice,
    	'BASKET_ITEMS' => $arItems
    );
    
    // Checking for authorized user
    if(is_object($GLOBALS["USER"])){
    	$arOrder['USER_ID'] = $GLOBALS["USER"]->GetID();
    	$arErrors = array();
    	// Calculate discount
    	CSaleDiscount::DoProcessOrder($arOrder, array(), $arErrors);
    }
    
    // All done!
    echo $arOrder['ORDER_PRICE'];
    Ответ написан
    1 комментарий
  • При запросе файлов добавляется заголовок Cache-control: no-cache. Почему?

    @r_zaycev
    У вас nginx отдает статику. Т.е. до апача и до .htaccess дело даже не доходит.
    Ответ написан
    1 комментарий
  • Как получить ссылки на файлы?

    @r_zaycev
    Если вы пишете свой в компонент (что вряд ли), то делайте так:

    $res = CIBlockElement::GetList(
     array(),
     array(
     'IBLOCK_ID' = 1, // Идентификатор ИБ статей
     ),
     false,
     false,
     array(
      'PROPERTY_FILES.PROPERTY_DOC', // Коды свойств с файлами
      'PROPERTY_FILES.PROPERTY_PDF'
     )
    );
    
    while($arFields = $res->GetNext()){
     // Смотрите, что тут находится в $arFields, и доставайте файлы по идентификатору, с помощью метода CFile::GetByID либо CFile::GetPath
    }


    Ссылки на документацию: https://dev.1c-bitrix.ru/api_help/iblock/classes/c...
    https://dev.1c-bitrix.ru/api_help/main/reference/c...
    https://dev.1c-bitrix.ru/api_help/main/reference/c...

    Если вы хотите отобразить в шаблоне стандартного компонента, (news.detail, судя по всему), тогда используйте файл result_modifier.php шаблона компонента, доставайте ссылки на файлы там и записывайте в $arResult (дока). Примерно так:

    result_modifier.php:
    if(!empty($arResult['PROPERTIES']['FILES']['VALUE'])){
     $res = CIBlockElement::GetList(
      array(),
      array(
       'IBLOCK_ID' => $arResult['PROPERTIES']['FILES']['IBLOCK_ID'],
       'ID' => $arResult['PROPERTIES']['FILES']['VALUE'],
       'ACTIVE' => 'Y' 
      ),
      false,
      false,
      array(
       'PROPERTY_DOC', // Коды свойств с файлами
       'PROPERTY_PDF'
      )
     );
    
     $files = array();
    
     while($arFields = $res->GetNext()){
      foreach(array('PDF', 'DOC') as $code){
       $fullCode = "PROPERTY_$code_VALUE";
       if($filePath = CFile::GetPath($arFields[$fullCode])){
        $files[] = $filePath;
       }
      }
     }
     $arResult['PROPERTIES']['FILES']['LINKS'] = $files;
    }


    Работоспособность кода не гарантирую, писал по памяти, но идея, я думаю, ясна.
    Ответ написан
    Комментировать
  • Как вытянуть все товары со всех разделов по определенному свойству в bitrix?

    @r_zaycev
    CIBlockElement::GetList, передать в аргументе групировки arGroupBy массив такого вида:

    array(
    'PROPERTY_BRAND' // Где BRAND это код свойсва "БРЕНД"
    )
    Ответ написан
    1 комментарий
  • Как встроить в компонент bitrix news.detail компонента bitrix:form?

    @r_zaycev
    Самое правильное решение: не делать вызовов стороннего компонента из шаблона компонента (вот такая вот тавтология).

    Можете попробовать использовать отложенные функции (CMain::ShowViewContent и CComponentTemplate::SetViewTarget): https://dev.1c-bitrix.ru/api_help/main/reference/c...
    Ответ написан
    Комментировать
  • Как в bitrix получить все уроки по ид курса?

    @r_zaycev
    Из дока:
    ID - идентификатор урока;
    ...
    COURSE_ID - идентификатор курса;


    Ну и метод-то deprecated, попробуйте CLearnLesson::GetList
    Ответ написан
  • Bitrix | Как сделать однотипную приписку ко всем description на сайте?

    @r_zaycev
    Замените
    <?$APPLICATION->ShowHead();?>

    на аналогичные вызовы
    <title><?$APPLICATION->ShowTitle();?></title>
    <?
    $APPLICATION->ShowMeta("keywords");
    $APPLICATION->ShowMeta("description");
    $APPLICATION->ShowCSS();
    $APPLICATION->ShowHeadStrings();
    $APPLICATION->ShowHeadScripts();
    ?>
    Ответ написан
  • Как лучше темизировать шаблоны компонента каталог в Битрикс?

    @r_zaycev
    Вот вы два варианта и описали, как можно делать (это же Битрикс). Другой вопрос что для вас лучше? Есть время, выкидывайте шаблон компонента и пишите свой. Нет времени: кастомизируйте дефолтный. Если со временем вообще хорошо: пишите свой компонент.

    Это касается не только компонентов каталога
    Ответ написан
    5 комментариев