• Как центрировать модальное окно BX.PopupWindow?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Центрировать popup можно с помощью его методов adjustPosition и resizeOverlay;
    Например так:
    var popup = BX.PopupWindowManager.create("sender_subscribe_component", null, {
        autoHide: true,
        offsetLeft: 0,
        offsetTop: 0,
        overlay: true,
        closeByEsc: true,
        events: {
            onAfterPopupShow: function () {
                popup.adjustPosition();
                popup.resizeOverlay();
            }
        }
    });
    
    popup.show();
    Ответ написан
    1 комментарий
  • Почему создаю $code=CCatalogDiscount::Add($arF) скидку на товар но ее нигде не видно?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    CCatalogDiscount - это старые скидки из модуля catalog.
    Вам нужен класс CSaleDiscount - это будут правила корзины (скидки из модуля sale)
    Ответ написан
    Комментировать
  • Как реализовать свою регистрацию на Bitrix?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Для проверки введеного пароля используйте метод \Bitrix\Main\Security\Password::equals($hash, $password, $original = true): bool

    $hash - хеш пароля, который хранится в таблице b_user в поле PASSWORD

    $password - пароль, который надо проверить
    Ответ написан
    Комментировать
  • Почему system.auth.forgotpasswd не отправляет письмо с контрольной строкой (в b_event нет события)?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Отправка письма на восстановление пароля идёт с помощью CEvent::SendImmediate, поэтому добавление в b_event и не происходит.

    Может у Вас вообще не работает отправка почты? проверьте с помощью функции mail или какого ни будь почтового события
    Ответ написан
  • Почему не отрабатывает init в битриксе?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Попробуйте событие OnBeforeUserAdd.
    Ответ написан
  • Что такое выделено белым?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Я так понимаю, на скрине у Вас кусок шаблона bitrix:sale.basket.basket.
    Данная запись это шаблон Mustache.js.
    Шаблон рендерится с помощью js кода. Данные которые передаются для рендера можно изменить в mutator.php в коде шаблона компонента
    Ответ написан
    Комментировать
  • Как в админке Битрикс - Заказы, разделить заказы по группе пользователей?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Можно на событии OnSaleAdminOrderList добавить фильтр. Я привожу пример на основе групп пользователей розницы и оптовиков. Можно легко адаптировать под типы плательщика.

    В примере $getListParams это то что будет передано в запрос по OrderTable.

    <?php
    
    \Bitrix\Main\EventManager::getInstance()->addEventHandler( 
        'sale', 
        'OnSaleAdminOrderList', 
        'OnSaleAdminOrderListHandler'
    ); 
    
    
    function OnSaleAdminOrderListHandler(\Bitrix\Main\Event $event) 
    {
        $getListParams = $event->getParameters();
        $reailManagerGroupId = 1; //ID группы менеджеров розницы
        $wholesaleManagerGroupId = 2; //ID группы менеджеров оптовиков
        $optUserGroup = 3; //ID группы оптовых покупателей
        $reatilUserGroup = 4; //ID группы розничных покупателей
        global $USER;
    
        $userGroups = \CUser::GetUserGroup($USER);
        if (in_array($reailManagerGroupId, $userGroups)) {
            $getListParams["filter"]["USER_GROUP.GROUP_ID"] = $reatilUserGroup;
        } else if(in_array($wholesaleManagerGroupId, $userGroups)) {
            $getListParams["filter"]["USER_GROUP.GROUP_ID"] = $optUserGroup;
        }
    
    
        $result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $getListParams);
        return $result;
    }
    Ответ написан
    4 комментария
  • Как найти какой php делает редирект?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Если дело в битриксе, то надо искать вызовы функции LocalRedirect. Добавьте логирование в тело функции (запись в файл вывода debug_backtrace).

    LocalRedirect объявлена в файле bitrix/modules/main/tools.php
    Ответ написан
    Комментировать
  • CIBlockElement::Add - как добавить свойство типа список?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Если у Вас нет возможности передать в качестве входных данных именно ID списочных элементов (внешний импорт или файл какой ни-будь), то делайте поиск по списочным значениям и уже из найденных элементов подставляйте их ID

    $iblockId = 1;//id инфоблока
    $inputValues = [44, 45, 46];//Ваши входные данные
    
    $enumIds = array_column(\Bitrix\Iblock\PropertyEnumerationTable::getList([
        "select" => ["ID"],
        "filter" => [
            "PROPERTY.CODE" => "mylist",
            "PROPERTY.IBLOCK_ID" => $iblockId,
            "VALUE" => $inputValues
        ],
        "cache" => [
            "ttl" => 86400
        ]
    ]->fetchAll()), "ID");

    $enumIds - будет массив с ID списочных значений, который нужен Вам в CIblockElement::Add
    Стоит обратить внимание на то что в примере в метод getList передан параметр cache. Это позволит каждый раз не обращаться к БД, а взять значение из кеша.
    Ответ написан
    1 комментарий
  • Ошибка Количество товара "" не может быть меньше или равным 0,Не указана валюта товара. Как избавиться?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Попробуйте очистить корзину через API.
    CModule::IncludeModule("sale");
    CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID());
    Ответ написан
  • Как найти содержимое переменной $arAddToBasketData["HTML"]?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Если нужен именно текст, то он указывается настройках в админке модуля Aspro.
    Для шаблона aspro.next - это будет /bitrix/admin/aspro.next_options.php?mid=main.
    Заходите в Рабочий стол > Аспро > Аспро: Next > Настройки
    60cc3167b04b2354915193.png

    Там будет раздел "Выражения и названия".
    Вам нужен пункт Текст под кнопкой "Под заказ"

    Если нужно что то переделать со стороны backend, то нужно найти метод \CNext::GetAddToBasketArray
    Ответ написан
    1 комментарий
  • Как передать дополнительные параметры в письмо при изменении заказа?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Вам нужно событие OnBeforeEventAdd

    В обработчике проверяйте переданный тип почтового события на тот что у вас используется для уведомления об изменении заказа, и добавляйте нужные поля
    Ответ написан
  • Как прикрепить файл в письме битрикс?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Пробую прикрепить файл таким образом в методе CEvent::Send, но письмо приходит без файла
    в чем ошибка?


    Ошибка в том что Вы не правильно передаёте файл. Файл передается 6м параметром в функцию, а у Вас 4м

    Посмотрите внимательно документацию
    Ответ написан
    Комментировать
  • Как читать объекты D7 Bitrix?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Как мне получить TRADING_PLATFORM_ID ?

    $tradeBindingCollection = $order->getTradeBindingCollection();
    
    /** @var Bitrix\Sale\TradeBindingEntity $item */
    foreach ($tradeBindingCollection as $item) {
        $tpId = $item->getField('TRADING_PLATFORM_ID');
    }


    Как вообще читать такие объекты?

    В дампе который вы привели указаны типы объектов.
    Например $order->getTradeBindingCollection(); возвращает коллекцию Bitrix\Sale\TradeBindingCollection
    Она как и другие коллекции Bitrix имеет реализацию интерфейсов \ArrayAccess, \Countable, \IteratorAggregate
    Поэтому может проходится циклом foreach.

    В свою очередь каждый объект внутри коллекции является объектом класса Bitrix\Sale\TradeBindingEntity, что так же видно из дампа. Этот класс является наследником Internals\Entity, который имеет методы для получения полей хранящихся в поле values.

    Для того чтобы разобраться нужно смотреть документацию или исходные коды. Исходные коды рекомендую смотреть через IDE (не в notePad++), для удобной навигации и облегчения работы.

    В принципе всё это приходит с опытом.
    Ответ написан
    6 комментариев
  • Как скрыть онлайн оплату картой для весовых товаров?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Вы пошли в правильное направление - реализация ограничения.
    Вот код. Написал но не проверял. По идее должен работать. Переделал по быстрому по образцу с другого ограничения.

    Подключение обработчика события:
    $bxEventManager = \Bitrix\Main\EventManager::getInstance();
    
    $bxEventManager->addEventHandler(
        'sale',
        'onSalePaySystemRestrictionsClassNamesBuildList',
        array(
            \Gricuk\Sale\Payment\Restrictions\ByMeasure::class,
            "onSalePaySystemRestrictionsClassNamesBuildList"
        )
    );


    Класс с ограничением:
    <?php
    
    namespace Gricuk\Sale\Payment\Restrictions;
    
    use Bitrix\Catalog\MeasureTable;
    use Bitrix\Sale\Internals\Entity;
    use Bitrix\Sale\Payment;
    
    /** Ограничение по единицам измерения
     * Class ByMeasure
     * @package Gricuk\Sale\Payment\Restrictions
     */
    class ByMeasure extends \Bitrix\Sale\Services\Base\Restriction
    {
        public static function onSalePaySystemRestrictionsClassNamesBuildList()
        {
            return new \Bitrix\Main\EventResult(
                \Bitrix\Main\EventResult::SUCCESS,
                array(
                    self::class => '/local/php_interface/lib/Gricuk/Sale/Payment/Restrictions/ByMeasure.php',
                )
            );
        }
    
        public static function getClassTitle()
        {
            return 'По единицам измерения товаров в корзине';
        }
    
        public static function getClassDescription()
        {
            return 'Оплата будет НЕ доступна для указанных единиц измерения';
        }
    
        /** Выполняет проверку на наличие в массиве $measures единиц измерения, указанных в настройках ограничения
         * @param $userId
         * @param array $restrictionParams
         * @param int $serviceId
         * @return bool - true нет ограничения, единиц измерения из настроек нет у товаров в корзине.
         * false - ограничение сработало, в корзине есть товары с указанными единицами измерения
         */
        public static function check($measures, array $restrictionParams, $serviceId = 0)
        {
            if (empty($restrictionParams["MEASURES"]) || empty($measures)) {
                return true;
            }
    
            if (count(array_intersect($measures, $restrictionParams["MEASURES"])) > 0) {
                return false;
            } else {
                return true;
            }
        }
    
        /**Преобразует $entity в то что будет передано в первый параметр метода self::check
         * @param Entity $paysystem
         * @return mixed|string|null
         * @throws \Bitrix\Main\ArgumentException
         * @throws \Bitrix\Main\NotImplementedException
         */
        protected static function extractParams(Entity $entity)
        {
            $measures = [];
            if ($entity instanceof Payment) {
                $order = $entity->getOrder();
                if (!$order) {
                    return $measures;
                }
    
                $products = [];
                /** @var \Bitrix\Sale\BasketItem $basketItem */
                foreach ($order->getBasket() as $basketItem) {
                    $products[] = $basketItem->getProductId();
                }
                if (!empty($products)) {
                    $measures = array_column(\Bitrix\Catalog\ProductTable::getList([
                        "select" => ["MEASURE"],
                        "filter" => [
                            "ID" => $products
                        ]
                    ])->fetchAll(), "MEASURE");
                }
            }
            return array_unique($measures);
        }
    
        /** Возвращает массив параметров, описывающий ограничение
         * @param int $entityId
         * @return array
         */
        public static function getParamsStructure($entityId = 0)
        {
            $result = array(
                "MEASURES" => array(
                    "TYPE" => "ENUM",
                    'MULTIPLE' => 'Y',
                    "LABEL" => "Единицы измерения",
                    "OPTIONS" => self::getMeasures()
                )
            );
    
            return $result;
        }
    
        /**Возвращает массив единиц измерения
         * @return array|mixed
         * @throws \Bitrix\Main\ArgumentException
         * @throws \Bitrix\Main\ObjectPropertyException
         * @throws \Bitrix\Main\SystemException
         */
        public static function getMeasures()
        {
            static $result = null;
    
            if ($result !== null)
                return $result;
    
            $result = [];
            $dbResultList = MeasureTable::getList(array(
                'select' => array("ID", "MEASURE_TITLE"),
                'order' => array("ID" => "ASC")
            ));
    
            while ($measure = $dbResultList->fetch()) {
                $result[$measure["ID"]] = $measure["MEASURE_TITLE"];
            }
    
            return $result;
        }
    }
    Ответ написан
    24 комментария
  • Как создать инструмент на сайте Битрикс для формирования документа Word и его скачивания пользователем?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Если у Вас сайт на "Bitrix Управление Сайтом", то можно воспользоваться библиотекой https://github.com/PHPOffice/PHPWord
    Этот способ подразумевает программирование функционала.

    Для Bitrix24 можно воспользоваться встроенным функционалом документов:
    https://helpdesk.bitrix24.ru/open/7622241/
    https://helpdesk.bitrix24.ru/open/7642121/
    Ответ написан
    3 комментария
  • Композитный сайт и $frame->beginStub()?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Чтобы разобраться в проблеме надо понимать как работает композит.
    Вот так размечается динамический контент и его заглушка внутри шаблона компонента:
    $frame = new \Bitrix\Main\Page\FrameBuffered("my_dynamic"); 
    $frame->begin();
      // Содержание динамической области
    $frame->beginStub();
      // Заглушка
    $frame->end();

    При первоначальной загрузке страницы, браузер получает HTML в котором отсутствует динамический контент. На его месте находятся заглушки.
    После загрузки страницы у Вас выполняется JS скрипт, который навешивает обработчик на вашу кнопку. Но кнопка у вас из заглушки.
    После уже сам Битрикс загружает на место заглушки динамический контент. В DOM модели это будет уже другая кнопка и на ней не будет вашего обработчика.

    Поэтому Вам надо либо инициализировать обработчик из динамической области, либо изначально вешать событие не на саму кнопку. Например в jQuery это можно сделать так
    $(document).on('click', '.header__link.header__link--auth', callback);
    Ответ написан
    Комментировать
  • Bitrix подмена статуса заказа при изменении заказа?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Регистрируем обработчик
    $bxEventManager = \Bitrix\Main\EventManager::getInstance();
    $bxEventManager->addEventHandler(
        "sale",
        "OnSaleOrderBeforeSaved",
        array(
            Gricuk\Sale\Order::class,
            "changeStatusOnOrderCreate"
        )
    );


    Сам обработчик. У меня в примере логика на смена статуса заказа для определенных служб. Ее можно переписать на что угодно. Основное это $event->addResult
    namespace Gricuk\Sale;
    
    class Order
    {
        public static function changeStatusOnOrderCreate(\Bitrix\Main\Event $event)
        {
            /** @var \Bitrix\Sale\Order $order */
            $order = $event->getParameter("ENTITY");
    
            $status = $order->getField("STATUS_ID");
            if ($status == "N") {
                /**  @var $paymentCollection \Bitrix\Sale\PaymentCollection */
                $paymentCollection = $order->getPaymentCollection();
    
                foreach ($paymentCollection as $payment) {
                    /**  @var $payment \Bitrix\Sale\Payment */
    
                    /**  @var $paySystem \Bitrix\Sale\PaySystem\Service */
                    $paySystem = $payment->getPaySystem();
    
                    if (!is_null($paySystem) && !$paySystem->isCash()) {
                        $order->setField("STATUS_ID", "NA");
    
                        $event->addResult(
                            new Main\EventResult(
                                Main\EventResult::SUCCESS, $order
                            )
                        );
                        break;
                    }
                }
            }
        }
    }


    Пример 100% рабочий. Взят с прода.
    Ответ написан
  • Как вывести через UF-поле свойства другого элемента в разделе?

    winer
    @winer
    занимаюсь разработкой сайтов на 1c-bitrix
    Для того чтобы в $arItem у элемента ИБ появились значения свойств, их надо добавить в параметр arSelectFields в CIblockElement::GetList

    $rsItems = CIBlockElement::GetList(array(),$arFilter, false, false, ["*", "PROPERTY_CASH", "PROPERTY_ATT_PRICE"]);


    Так же стоит обратить внимание на недоработку в коде. У вас не выполняется проверка на наличие элементов в массиве $iter. Если по тем или иным причинам $iter будет пустой, то GetList выберет все элементы из инфоблока.
    <?
    <?
    $rsResult = CIBlockSection::GetList(array("SORT" => "ASC"), array("IBLOCK_ID" => "27", 'ID' => $arResult["SECTION"]["ID"]), true, Array("UF_HITS"));
    while ($arResult = $rsResult -> GetNext())
    {
    	if (!empty($arResult["UF_HITS"])) 
    	{
    		$iter = $arResult["UF_HITS"];
    	}
    }
    
    if (!empty($iter))
    {
    	$arFilter = array('IBLOCK_ID' => 27,'ID' => $iter);
    	$rsItems = CIBlockElement::GetList(array(),$arFilter);
    	while ($arItem = $rsItems->GetNext())
    	{
    
    		$resizer = $arItem['PREVIEW_PICTURE'];
    		$file = CFile::ResizeImageGet($resizer, array('width'=>180, 'height'=>290), BX_RESIZE_IMAGE_PROPORTIONAL , true);
    		$img = $file['src'];
    		echo 
    		'<div class="hits-smallcard">
    			<img src="'.$img.'" />
    			<p><a href="'.$arItem["DETAIL_PAGE_URL"].'">'.$arItem["NAME"].'</a></p>
    			<p><a href="#modal1" class="popup-content">Заказать</a></p>
    			<p><a href="'.$arItem["DETAIL_PAGE_URL"].'">Подробнее</a></p>
    			<p>'.$arItem["CASH"].'</p> //не выводит, число
    			<p>'.$arItem["ATT_PRICE"].'</p> //не выводит, строка
    		</div>'; 
    	}
    }
    ?>
    Ответ написан