Заметка для себя. Отобразить все скидки включая скидки из Правил работы с корзиной

use Bitrix\Main\Loader;
use Bitrix\Main\SystemException;
 
class AllProductDiscount{
    /**
     * @return XML_ID|array
     * @throws SystemException
     * @throws \Bitrix\Main\LoaderException
     */
    public static function getFull($arrFilter = array(), $arSelect = array()){
        if(!Loader::includeModule('sale')) throw new SystemException('Не подключен модуль Sale');
 
    //Все товары со скидкой!!!
    // Группы пользователей
    global $USER;
    $arUserGroups = $USER->GetUserGroupArray();
    if (!is_array($arUserGroups)) $arUserGroups = array($arUserGroups);
    // Достаем старым методом только ID скидок привязанных к группам пользователей по ограничениям
    $actionsNotTemp = \CSaleDiscount::GetList(array("ID" => "ASC"),array("USER_GROUPS" => $arUserGroups),false,false,array("ID"));
    while($actionNot = $actionsNotTemp->fetch()){
      $actionIds[] = $actionNot['ID'];
    }
    $actionIds=array_unique($actionIds); sort($actionIds);
    // Подготавливаем необходимые переменные для разборчивости кода
    global $DB;
    $conditionLogic = array('Equal'=>'=','Not'=>'!','Great'=>'>','Less'=>'<','EqGr'=>'>=','EqLs'=>'<=');
    $arSelect = array_merge(array("ID","IBLOCK_ID","XML_ID"),$arSelect);
    $city='MSK';
    // Теперь достаем новым методом скидки с условиями. P.S. Старым методом этого делать не нужно из-за очень высокой нагрузки (уже тестировал)
    $actions = \Bitrix\Sale\Internals\DiscountTable::getList(array(
      'select' => array("ID","ACTIONS_LIST"),
      'filter' => array("ACTIVE"=>"Y","USE_COUPONS"=>"N","DISCOUNT_TYPE"=>"P","LID"=>SITE_ID,
      "ID"=>$actionIds,
      array(
        "LOGIC" => "OR",
        array(
          "<=ACTIVE_FROM"=>$DB->FormatDate(date("Y-m-d H:i:s"),"YYYY-MM-DD HH:MI:SS",\CSite::GetDateFormat("FULL")),
          ">=ACTIVE_TO"=>$DB->FormatDate(date("Y-m-d H:i:s"),"YYYY-MM-DD HH:MI:SS",\CSite::GetDateFormat("FULL"))
        ),
        array(
          "=ACTIVE_FROM"=>false,
          ">=ACTIVE_TO"=>$DB->FormatDate(date("Y-m-d H:i:s"),"YYYY-MM-DD HH:MI:SS",\CSite::GetDateFormat("FULL"))
        ),
        array(
          "<=ACTIVE_FROM"=>$DB->FormatDate(date("Y-m-d H:i:s"),"YYYY-MM-DD HH:MI:SS",\CSite::GetDateFormat("FULL")),
          "=ACTIVE_TO"=>false
        ),
        array(
          "=ACTIVE_FROM"=>false,
          "=ACTIVE_TO"=>false
        ),
      ))
    ));
    // Перебираем каждую скидку и подготавливаем условия фильтрации для CIBlockElement::GetList
    while($arrAction = $actions->fetch()){
      $arrActions[$arrAction['ID']] = $arrAction;
    }
    foreach($arrActions as $actionId => $action){
      $arPredFilter = array_merge(array("ACTIVE_DATE"=>"Y", "CAN_BUY"=>"Y"),$arrFilter); //Набор предустановленных параметров
      $arFilter = $arPredFilter; //Основной фильтр
      $dopArFilter = $arPredFilter; //Фильтр для доп. запроса
      $dopArFilter["=XML_ID"] = array(); //Пустое значения для первой отработки array_merge
      //Магия генерации фильтра
      foreach($action['ACTIONS_LIST']['CHILDREN'] as $condition){
        foreach($condition['CHILDREN'] as $keyConditionSub=>$conditionSub){
          $cs=$conditionSub['DATA']['value']; //Значение условия
          $cls=$conditionLogic[$conditionSub['DATA']['logic']]; //Оператор условия
          //$arFilter["LOGIC"]=$conditionSub['DATA']['All']?:'AND';
          $CLASS_ID = explode(':',$conditionSub['CLASS_ID']);
 
          if($CLASS_ID[0]=='ActSaleSubGrp') {
            foreach($conditionSub['CHILDREN'] as $keyConditionSubElem=>$conditionSubElem){
              $cse=$conditionSubElem['DATA']['value']; //Значение условия
              $clse=$conditionLogic[$conditionSubElem['DATA']['logic']]; //Оператор условия
              //$arFilter["LOGIC"]=$conditionSubElem['DATA']['All']?:'AND';
              $CLASS_ID_EL = explode(':',$conditionSubElem['CLASS_ID']);
 
              if($CLASS_ID_EL[0]=='CondIBProp') {
                $arFilter["IBLOCK_ID"]=$CLASS_ID_EL[1];
                $arFilter[$clse."PROPERTY_".$CLASS_ID_EL[2]]=array_merge((array)$arFilter[$clse."PROPERTY_".$CLASS_ID_EL[2]],(array)$cse);
                $arFilter[$clse."PROPERTY_".$CLASS_ID_EL[2]]=array_unique($arFilter[$clse."PROPERTY_".$CLASS_ID_EL[2]]);
              }elseif($CLASS_ID_EL[0]=='CondIBName') {
                $arFilter[$clse."NAME"]=array_merge((array)$arFilter[$clse."NAME"],(array)$cse);
                $arFilter[$clse."NAME"]=array_unique($arFilter[$clse."NAME"]);
              }elseif($CLASS_ID_EL[0]=='CondIBElement') {
                $arFilter[$clse."ID"]=array_merge((array)$arFilter[$clse."ID"],(array)$cse);
                $arFilter[$clse."ID"]=array_unique($arFilter[$clse."ID"]);
              }elseif($CLASS_ID_EL[0]=='CondIBTags') {
                $arFilter[$clse."TAGS"]=array_merge((array)$arFilter[$clse."TAGS"],(array)$cse);
                $arFilter[$clse."TAGS"]=array_unique($arFilter[$clse."TAGS"]);
              }elseif($CLASS_ID_EL[0]=='CondIBSection') {
                $arFilter[$clse."SECTION_ID"]=array_merge((array)$arFilter[$clse."SECTION_ID"],(array)$cse);
                $arFilter[$clse."SECTION_ID"]=array_unique($arFilter[$clse."SECTION_ID"]);
              }elseif($CLASS_ID_EL[0]=='CondIBXmlID') {
                $arFilter[$clse."XML_ID"]=array_merge((array)$arFilter[$clse."XML_ID"],(array)$cse);
                $arFilter[$clse."XML_ID"]=array_unique($arFilter[$clse."XML_ID"]);
              }elseif($CLASS_ID_EL[0]=='CondBsktAppliedDiscount') { //Условие: Были применены скидки (Y/N)
                foreach($arrActions as $tempAction){
                  if(($tempAction['SORT']<$action['SORT']&&$tempAction['PRIORITY']>$action['PRIORITY']&&$cse=='N')||($tempAction['SORT']>$action['SORT']&&$tempAction['PRIORITY']<$action['PRIORITY']&&$cse=='Y')){
                    $arFilter=false;
                    break 4;
                  }
                }
              }
            }
          }elseif($CLASS_ID[0]=='CondIBProp') {
            $arFilter["IBLOCK_ID"]=$CLASS_ID[1];
            $arFilter[$cls."PROPERTY_".$CLASS_ID[2]]=array_merge((array)$arFilter[$cls."PROPERTY_".$CLASS_ID[2]],(array)$cs);
            $arFilter[$cls."PROPERTY_".$CLASS_ID[2]]=array_unique($arFilter[$cls."PROPERTY_".$CLASS_ID[2]]);
          }elseif($CLASS_ID[0]=='CondIBName') {
            $arFilter[$cls."NAME"]=array_merge((array)$arFilter[$cls."NAME"],(array)$cs);
            $arFilter[$cls."NAME"]=array_unique($arFilter[$cls."NAME"]);
          }elseif($CLASS_ID[0]=='CondIBElement') {
            $arFilter[$cls."ID"]=array_merge((array)$arFilter[$cls."ID"],(array)$cs);
            $arFilter[$cls."ID"]=array_unique($arFilter[$cls."ID"]);
          }elseif($CLASS_ID[0]=='CondIBTags') {
            $arFilter[$cls."TAGS"]=array_merge((array)$arFilter[$cls."TAGS"],(array)$cs);
            $arFilter[$cls."TAGS"]=array_unique($arFilter[$cls."TAGS"]);
          }elseif($CLASS_ID[0]=='CondIBSection') {
            $arFilter[$cls."SECTION_ID"]=array_merge((array)$arFilter[$cls."SECTION_ID"],(array)$cs);
            $arFilter[$cls."SECTION_ID"]=array_unique($arFilter[$cls."SECTION_ID"]);
          }elseif($CLASS_ID[0]=='CondIBXmlID') {
            $arFilter[$cls."XML_ID"]=array_merge((array)$arFilter[$cls."XML_ID"],(array)$cs);
            $arFilter[$cls."XML_ID"]=array_unique($arFilter[$cls."XML_ID"]);
          }elseif($CLASS_ID[0]=='CondBsktAppliedDiscount') { //Условие: Были применены скидки (Y/N)
            foreach($arrActions as $tempAction){
              if(($tempAction['SORT']<$action['SORT']&&$tempAction['PRIORITY']>$action['PRIORITY']&&$cs=='N')||($tempAction['SORT']>$action['SORT']&&$tempAction['PRIORITY']<$action['PRIORITY']&&$cs=='Y')){
                $arFilter=false;
                break 3;
              }
            }
          }
        }
      }
      if($arFilter!==false&&$arFilter!=$arPredFilter){
        if(!isset($arFilter['=XML_ID'])){
          //Делаем запрос по каждому из фильтров, т.к. один фильтр не получится сделать из-за противоречий условий каждой скидки
          $res = \CIBlockElement::GetList(array(), $arFilter, false, false, $arSelect);
          while($ob = $res->GetNextElement()){
            $arFields = $ob->GetFields();
            $poductsArray['IDS'][] = $arFields["ID"];
          }
        }elseif(!empty($arFilter['=XML_ID'])){
          //Подготавливаем массив для отдельного запроса
          $dopArFilter['=XML_ID'] = array_unique(array_merge($arFilter['=XML_ID'],$dopArFilter['=XML_ID']));
        }
      }
    }
 
    if(isset($dopArFilter)&&!empty($dopArFilter['=XML_ID'])){
      //Делаем отдельный запрос по конкретным XML_ID
      $res = \CIBlockElement::GetList(array(), $dopArFilter, false, array("nTopCount"=>count($dopArFilter['=XML_ID'])), $arSelect);
      while($ob = $res->GetNextElement()){
        $arFields = $ob->GetFields();
        $poductsArray['IDS'][] = $arFields["ID"];
      }
    }
    $poductsArray['ids']=array_unique($poductsArray['ids']);
 
        return $poductsArray;
    }
}

 

<?
    $res = AllProductDiscount::getFull(
    array("ACTIVE" => "Y", "SITE_ID" => SITE_ID),
    array()
    );
    foreach($res['IDS'] as $ID) {
    	$sale_id[] = $ID;
    }
    $GLOBALS['arrFilter'] = array("ID"=>$sale_id);
?>

Спасибо за публикацию:

https://dd-blog.ru/bitrix-creating-a-partition-discounts/

Оставляю этот код у себя для простоты поиска.

На самом деле всё просто. Идём по пути:

/bitrix/modules/main/include/

И ищем там файл prolog_after.php

После этого находим строчку:

if(COption::GetOptionString("main", "site_stopped", "N")=="Y" && !$USER->CanDoOperation('edit_other_settings'))

 

Редактируем на:

if(COption::GetOptionString("main", "site_stopped", "N")=="Y" && !$USER->CanDoOperation('edit_own_profile'))

 

Даём пользователям группы возможность редактировать свой профиль. Вуаля.

Данное решение не мое, нашел на просторах интернета.

Если нужно больше полей – добавляйте

$html .= '<td><input type="text" size="25" placeholder="Количество" name="'.$strHTMLControlName['VALUE'].'[]" value="'.$value['VALUE'][КОЛИЧЕСТВО].'" /></td>';

 

и ниже в GetAdminListViewHTML

." - ".$value['VALUE'][N]

 

 

Исходный код:

AddEventHandler("iblock","OnIBlockPropertyBuildList",array("Property_Service_List_Class","GetUserTypeDescription"));

if(!class_exists("Property_Service_List_Class"))
{
class Property_Service_List_Class
{
function GetUserTypeDescription()
{
return array(
"PROPERTY_TYPE" => "S",
"USER_TYPE" => "EServiceList",
"DESCRIPTION" => "Выбор",
"GetPropertyFieldHtml" => array("Property_Service_List_Class","GetPropertyFieldHtml"),
"GetPublicEditHTML" => array("Property_Service_List_Class","GetPropertyFieldHtml"),
"ConvertToDB" => array("Property_Service_List_Class","ConvertToDB"),
"ConvertFromDB" => array("Property_Service_List_Class","ConvertFromDB"),
"GetAdminListViewHTML" => array("Property_Service_List_Class","GetAdminListViewHTML"),
);
}

function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName)
{

$arResult = array();

$cache[$IBLOCK_ID] = array();

$html = '';
$html = "<table>";
$html .= "<tr>";
$html .= '<td><input type="text" size="2" placeholder="Уровень (1 - первый, 2 - второй)" name="'.$strHTMLControlName['VALUE'].'[]" value="'.$value['VALUE'][0].'" /></td>';
$html .= '<td><input type="text" size="25" placeholder="Название" name="'.$strHTMLControlName['VALUE'].'[]" value="'.$value['VALUE'][1].'" /></td>';
$html .= '<td><input type="text" size="25" placeholder="Количество" name="'.$strHTMLControlName['VALUE'].'[]" value="'.$value['VALUE'][2].'" /></td>';
$html .= '</tr>';
$html .= "</table>";

return $html;
}

function ConvertToDB($arProperty, $value)
{
if($value['VALUE'][0]!='') {
$value['VALUE'] = serialize($value['VALUE']);
} else {
$value['VALUE'] = null;
}
return $value;
}

function ConvertFromDB($arProperty, $value){
if(strlen($value["VALUE"])>0) {
$tmpArr = unserialize($value["VALUE"]);
if(is_array($tmpArr) && count($tmpArr))
$value["VALUE"] = $tmpArr;
} else {
$value["VALUE"] = null;
}
return $value;
}

function GetAdminListViewHTML($arProperty, $value, $strHTMLControlName) {
if(is_array($value["VALUE"]) && count($value["VALUE"])) {
$tmpArr = array();
$tmpArr[] = "[".$value['VALUE'][0]."] - ".$value['VALUE'][1]." - ".$value['VALUE'][2];

return implode(" /\n",$tmpArr);
}
else
{
return htmlspecialcharsex($value["VALUE"]);
}
}

}
}

 

Есть несколько решений.

  1. Посмотрите в настройках инфоблока качество сжатия изображений и поставьте 100%.
  2. В карточке товара или где Вам необходимо исправить проблему с качеством фото надо выполнить следующую команду.
<? $renderImage = CFile::ResizeImageGet($section['DETAIL_PICTURE'], Array("width" => "572", "height" => "378"), BX_RESIZE_IMAGE_PROPORTIONAL,true, Array("name" => "sharpen", "precision" => 0),false,100); ?>

 

Это отключит сжатие, и улучшит качество фотографий. Где width, height,$section[‘DETAIL_PICTURE’] задаете свое.

Недавно столкнулся с проблемой вывода пользовательского свойства в разделе. Задача была либо изменить вывод “привязки к элементам” либо заменить на свое свойство. Но информации было мало. Нашел пост от 2010 года где добавляли пользовательское свойство (ранее его не было). Взял шаблон оттуда и добавил.

Было вот так:

Стало вот так:

Собственно что и требовалось.

Вот ссылка:

https://dev.1c-bitrix.ru/community/webdev/user/2854/blog/2193/

Архив

 

Ну и при добавлении свойства писать не :

AddEventHandler(“iblock”, “OnIBlockPropertyBuildList”, Array(…))

а использовать обращение к основному модулю:

AddEventHandler(‘main’, ‘OnUserTypeBuildList’,array(…));

Если вы пользуетесь стандартными веб формами и используете свой шаблон, иногда необходимо внести изменения в файл вывода input,select и пр блоков.

Я столкнулся с задачей изменить radio. Копался в коде form.result.new. Но он работает только когда вы используете шаблоны по умолчанию. При изучении компонента столкнулся с таким кодом:

// get template
if ($strReturn = $FORM->IncludeFormCustomTemplate())
{
// add icons
$back_url = $_SERVER['REQUEST_URI'];

$editor = "/bitrix/admin/fileman_file_edit.php?full_src=Y&site=".SITE_ID."&";
$href = "javascript:window.location='".$editor."path=".urlencode($path)."&lang=".LANGUAGE_ID."&back_url=".urlencode($back_url)."'";

if ($arParams['USE_EXTENDED_ERRORS'] == 'Y')
$APPLICATION->SetAdditionalCSS($this->GetPath()."/error.css");

// output template
echo $strReturn;

return;
}

 

 

И тут работа компонента останавливается. Все данные лежат в $strReturn. Если выполняем print_r($strReturn) то выводится та же форма. Куда копать дальше? А вот сюда – $FORM->IncludeFormCustomTemplate().

Эта команда приводит нас к CFormOutput::IncludeFormCustomTemplate.

Оттуда ищем подобные элементы, натыкаемся на CFormOutput::ShowInput. Ага, это то что нам нужно.

//if ($key > 0) $res .= "<br />"; отключаем эту строчку чтобы убрать <br>

switch ($arAnswer["FIELD_TYPE"])
{
case "radio":
$ans_id = "form_checkbox_".$FIELD_SID."_".$arAnswer['ID'];
$arAnswer['FIELD_PARAM'] .= ' id="'.$ans_id.'"';

$value = CForm::GetRadioValue($FIELD_SID, $arAnswer, $arrVALUES);
$input = CForm::GetRadioField(
$FIELD_SID,
$arAnswer["ID"],
$value,
$arAnswer["FIELD_PARAM"]
);

$res.='<div class="col-xl-6 col-lg-6 col-md-6 col-sm-6 col-6 no-padding">';  //выводим обертку если нам необходима
$bodytag = str_replace("<label>", "", $input);
$bodytag = str_replace("</label>", "", $bodytag);

if (strlen($ans_id) > 0)
{
$res .= $bodytag;
$res .= "<label for=\"".$ans_id."\" class='label-sec'>";
$res .= "&nbsp;".$arAnswer["MESSAGE"]."</label>";
}
else
{
$res .= "<label>";
$res .= $input;
$res .= "<span class=\"".$caption_css_class."\">&nbsp;".$arAnswer["MESSAGE"]."</span></label>";
}
$res.='</div>';

break;

 

Вот тут собственно и всё. Конечно не очень хорошо лезть в ядро модуля form, но что поделать. Необходимо решить задачу вывода. Если необходимо убрать только <label>…</label> можно было бы модифицировать InputType но это совсем лезть в ядро main поэтому решил заменить в формах.

Информацию о структуре можно найти на официальном сайте. Во вложении простой компонент, который выводит в произвольном месте строку с информацией, которая необходима. Возможно задать фон, цвет текста и сам текст.

Предпочтительно использовать для вывода в шапке.

Необходимо подключение font-awesome. Используется как пример.

архив