Задать вопрос
  • Как сделать добавление товаров в корзину только из одной родительской категории?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Давай поговорим немножко о другом.
    Предположим, что у тебя следующая структура:

    Москва (id: 1)
    Приборы (id: 2)
    Инструменты (id: 5)
    Санкт-Петербург (id: 3)
    Инструменты (id: 4)

    Если товар принадлежит к категории 5, то он точно из Москвы и соответственно при добавлении товара из id:2 он должен добавиться.
    А если товар у тебя есть одновременно и там и там? Ну скажем, товар был добавлен и в id:4 и в id:5 - ситуация может быть и такой. В твоем коде, если товар так был занесен, то при добавлении родительский раздел может быть как СПБ, так и Москва, тогда в одном из городов твоя логика работать не будет, а это неправильно.

    Я тут набросал пару примеров и сделал пару допущений:
    1) Какой-то товар уже в корзине
    2) Ты уже знаешь ID города, товар из которого добавлен в корзину

    Весь код (без магии), отвечающий за проверку возможности добавлять товар:
    /**
     * @var integer Идентификатор товара из CITY_PRODUCTS_IBLOCK_ID, добавляемого в корзину
     */
    $iProductId = 650;
    
    /**
     * @var integer Идентификатор города, товар которого уже добавлен в корзину
     */
    $iCityId = 91;
    
    if ( canAddByCity($iProductId, $iCityId) )
    {
    	echo "Можно добавить";
    }
    else
    {
    	echo "Нельзя добавить";
    }


    Как видишь, в этом коде нет ничего интересного. Вся магия начинается в функции canAddByCity (да-да, написано не оптимально, нужно оптимизировать и т.п. и т.д. но для пояснения сойдет):

    /**
     * @var int Уровень вложенности, где находятся города (у меня 2)
     */
    define('CITY_DEPTH_LEVEL', 2);
    
    /**
     * @var integer Идентификатор инфоблока, где ищем товары
     */
    define('CITY_PRODUCTS_IBLOCK_ID', 5);
    
    /**
     * Возвращает true, если товар $product можно добавить в корзину
     * @param integer $product 
     * @param integer $city 
     * @return boolean
     */
    function canAddByCity( $product, $city = 0 )
    {
    	if ( empty($city) )
    	{
    		return true;
    	}
    
    	if ( !\Bitrix\Main\Loader::IncludeModule('iblock') )
    	{
    		return false;
    	}
    
    	/**
    	 * @var array Список категорий верхнего уровня для сравнения
    	 */
    	$arRootGroups = [];
    
    	/**
    	 * @var CDBResult
    	 * @see https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getelementgroups.php
    	 */
    	$resGroups = \CIBlockElement::GetElementGroups($product, true);
    
    	while( $arGroup = $resGroups->fetch() )
    	{
    		/**
    		 * А вдруг товар без категории и сразу добавлен в город
    		 * т.е. без привязки?
    		 */
    		if ( $arGroup['DEPTH_LEVEL'] == \CITY_DEPTH_LEVEL )
    		{
    			$arRootGroups[] = $arGroup['ID'];
    			continue;
    		}
    
    		/**
    		 * @todo Запросы в цикле это очень плохо. 
    		 * Лучше запомнить где-то разделы и лишние уровни и дополнительным
    		 * циклом пройтись после - запросов будет меньше и будет быстрее работать
    		 */
    		$iRootSectionId = getSectionIdByDepthLevel($arGroup['ID']);
    
    		if ( !empty($iRootSectionId) )
    		{
    			$arRootGroups[] = $iRootSectionId;
    			continue;
    		}
    	}
    
    	// Какие корневые группы имеет этот товар
    	// можно посмотреть через код
    	//var_dump($arRootGroups);
    
    	return in_array($city, $arRootGroups);
    
    }
    
    /**
     * Возвращает код родительского раздела $section из инфоблока $iblockId
     * на уровне CITY_DEPTH_LEVEL. В случае отсутствия возвращает 0
     * @param integer $section 
     * @param integer $iblockId 
     * @return integer
     */
    function getSectionIdByDepthLevel( $section, $iblockId = \CITY_PRODUCTS_IBLOCK_ID )
    {
    	$section = intval($section);
    
    	if ( empty($section) )
    	{
    		return 0;
    	}
    
    	if ( empty($iblockId) )
    	{
    		return 0;
    	}
    
    	if ( !\Bitrix\Main\Loader::IncludeModule('iblock') )
    	{
    		return 0;
    	}
    
    	$resChain = \CIBlockSection::GetNavChain($iblockId, $section, ['ID','DEPTH_LEVEL','IBLOCK_SECTION_ID']); 
    
    	while( $arSection = $resChain->fetch() )
    	{
    		if ( $arSection['DEPTH_LEVEL'] == \CITY_DEPTH_LEVEL)
    		{
    			return $arSection['ID'];
    		}
    	}
    
    	return 0;
    }
    Ответ написан
    Комментировать
  • Битрикс для организаций обязаловка?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Добрый день Станислав,

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

    Тут играет роль 2 фактора:

    1) Все это должно пройти через тендеры. Ну не вот прямо все, но бОльшая часть уж точно проходит именно через тендеры. И именно тут и отваливается большинство систем - в noname системах непонятно сколько можно отпилить и где отжать, а вот с простыми системами типа Битрикса очевидно.
    К тому же, важную роль играют именно баллы, которые выдаются за все подряд - сайты на такой же платформе, работ подрядчика с такими же гос. учреждениями, профильные специалисты (т.е. те, что можно подтвердить дипломами и т.п.). Я уж не говорю о том, кто это в итоге будет обслуживать, потому что непонятно как это будет создаваться.

    2) А далее уже встает вопрос в маркетинге - битрикс очень хорошо распиарен и на нем сделано уж очень много сайтов, в том числе и для гос. учреждений.
    Вот посудите сами: Вы ген.директор МосГорЧтоТоТам и Вам нужен сайт. Какую компанию при прочих равных (для упрощения считаем так) вы выберете:
    - Богатырь, с портфолиом: МинЮст, МинСтрой, МинКомСвязь, МинСельХоз, ФАС, МинОбрНауки.
    - Иванушка, с портфолиом: Интернет-магазин Мёда, Личный сайт Пети Петина и т.п.

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

    gromdron
    @gromdron
    Работаю с Bitrix24
    В редакция Эксперт, Малый Бизнес и Бизнес есть модуль Push'n'pull

    Модуль Push and Pull позволяет организовать транспорт для отправки мгновенных команд. Реализация данного функционала в виде отдельного модуля позволяет любому другому модулю (в том числе и модулям сторонних разработчиков) используя API отправлять мгновенные нотификации и сообщения клиентам.
    Ответ написан
    Комментировать
  • Как правильно сделать фильтр со сложной логикой?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Скорее всего такую логику Битрикс уже не осилит и Вам нужно обращаться в SQL и формировать уже прямой запрос в БД. Либо, можно сделать промежуточную таблицу/инфоблок/хайлоадблок и уже искать там.
    Ответ написан
    Комментировать
  • Как генерировать orders.xml в битриксе?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Я выяснил, что файл orders.xml генерируется только при запросе со стороны 1С.

    Файл не генерируется при запросе, он формируется в 1С и отправляется в Битрикс.
    Алгоритм выгрузки данных на сайт указан в документации.
    Дополнительно можно почитать, например и у Дениса
    Можно ли самостоятельно создавать этот файл в какой-либо директории сайта?

    Самостоятельно создать можно, но для загрузки необходимо вручную пройти по шагам импорта.
    По крайней мере первые 3 шага пройти придется, а дальше вручную можно положить файл в /upload/1c_exchange/ (ну или в зависимости от того что загружаете)
    Ответ написан
    7 комментариев
  • Как из двух массивов сделать один двумерный массив?

    gromdron
    @gromdron
    Работаю с Bitrix24
    В Вашем случае есть 2 ограничения:
    1) Если у Вас будет 2 пользователя с одинаковым именем, то их данные смешаются в одну кучу
    2) Если немного изменить формат $users то будет значительно проще получить результирующий массив (не нужен будет первый цикл на ассоциативность)

    /**
     * Шаг 1 - разворачиваем $users в плоский массив
     * Если есть возможность получить его сразу ассоциативным,
     * то это было бы лучше
     */
    $usersAssoc = [];
    
    foreach ($users as $user)
    {
    	$usersAssoc[ $user['id'] ] = $user['name'];
    }
    
    /**
     * Шаг 2 - выполяем группирующее преобразование наших $punch
     */
    $result = [];
    
    foreach ($punch as $time)
    {
    	if ( !array_key_exists($time['user_id'], $usersAssoc) )
    	{
    		// В punch есть массив, который относится к пользователю
    		// о окотором мы не знаем
    		continue;
    	}
    
    	$result[ $usersAssoc[ $time['user_id'] ] ][ $time['id'] ] = $time;
    }
    
    
    echo "<pre>";
    var_dump($result);
    echo "</pre>";
    Ответ написан
  • Кто-то видел Blueprint Interface для php?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Эм.. а какой кейс это закроет?
    А UE насколько я знаю, это заменяет все - и подход стандартизирован и действия и взаимоотношения.
    В вебе нет такой проблемы - классы обычно запиливаются для конкретного ORM/DataMapper и где-то, даже есть свой скаффолдинг.
    Ответ написан
  • Почему трёхуровневая архитектура клиент-серверного приложения надёжней двухуровневой?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Эм... а почему в теме вопроса один вопрос, а в тексте другой? Это фишка такая спрашивать 2 разные вещи в одном вопросе?
    Какая архитектура быстрее трёхуровневая или двухуровневая?

    С точки зрения пользователя или разработчика?
    В частном случае, при использовании масштабирования, трехуровневая структура будет быстрее для пользователя, за счет распределения нагрузки.
    Почему трёхуровневая архитектура клиент-серверного приложения надёжней двухуровневой?

    Я процитирую многоуважаемого sim3x
    Кто сказал, что надежнее?
    Ответ написан
    Комментировать
  • На чем основывается логика ERP систем?

    gromdron
    @gromdron
    Работаю с Bitrix24
    На мой взгляд, у Вас происходит путанница двух слабосвязанных возможностей системы.

    С одной стороны, Вы говорите о НСИ (насколько я понимаю Нормативно-справочная информация), а с другой стороны о так называемом RBAC (role based access control).
    Разложить можно следующим образом:
    1) Есть пользователи, который с определенной стороны являются справочником, а с другой стороны предметом иденктификации пользователя в системе
    2) Есть роль, которая складывается из совокупоности возможных действий в системе.
    3) Пользователь может иметь несколько ролей и права пользователя считаются исходя из совокупонсти максимально доступных прав.

    Причем возможные действия системы это не полностью динамический справочник, т.е. есть те вещи, которые оттуда не удаляются.

    Приведу пример: есть у нас некая ERP в которой 300 сотрудников и 3 роли - "гость" (по факту может не существовать в системе), "сотрудник", "администратор".
    Если мы всех 300 пользователей привяжем к роли "Сотрудник", а потом попытаемся ее удалить, то тут может быть несколько вариантов решения данной ситуации (разные системы применяют разные методы)

    С точки зрения удаления роли:
    - Роль не удаляется, пока есть хотя бы один сотрудник с такой ролью
    - Роль помечается удаленной и она больше не учитывается в наборе прав, но отображается в системе
    - Роль удаляется, только если пользователь отметил в какую роль добавить существующих пользователей
    - Роль просто удаляется, оставляя систему в состоянии "сломанной целостности".

    Что касается вопроса про справочники, то в общем понимании слова под этим подразуемевается в основном пользовательская информации справочного (внезапно!) характера. Т.е. эта информация не влияет на технический аспект работы системы, но напрямую завязана на бизнес-логику системы (все можно оспорить конечно же).
    Например справочником может служить:
    - Тип формы собственности (Государственная, Муниципальная, Частная и т.п.)
    - Организационно-правовая форма (Товарищество, Общество, Акционерное общество и т.п.)
    - Сфера интересов (IT, Сельское хозяйство и т.п.)

    То есть любая информация представленная в виде списка.
    P.S. В частном случае и пользователи и роли тоже являются справочниками.
    Ответ написан
    9 комментариев
  • Как убрать редирект восстановленной копии bitrix на боевой сайт?

    gromdron
    @gromdron
    Работаю с Bitrix24
    1) Произведите очистку кеша. В 90% случаев это решает проблему.
    Если доступ в админ панель не работает, удалите содержимое папок /bitrix/managed_cache/, /bitrix/cache/ и /bitrix/stack_cache/ вручную.

    2) Проверьте настройки проактивной защиты - если на боевом сайте она включена.
    Для этого придется подключиться к СУБД и вручную произвести зачистку данных модуля (радикально, но работает).
    Ответ написан
  • Как разобрать строку в XSLT преобразовании?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Реализовать подобное можно при помощи substring.

    XML-документ:
    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="docstyle.xsl"?>
    
    <Документы>
        <Документ КНД='1102345' ДатаДок="16.01.2012" КодНО="7601" />
        <Документ КНД='1111053' ДатаДок="12.12.2016" КодНО="7601" />
    </Документы>


    XSL-схема (docstyle.xsl)
    <?xml version="1.0" encoding="UTF-8" ?>
    
    <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns="http://www.w3.org/1999/xhtml">
        <xsl:output method="xml" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
    
        <xsl:template match="Документы/Документ">
            <tr>
                <td><xsl:value-of select="@ДатаДок"/></td>
                <td><xsl:value-of select='substring(@КНД,1,1)'/></td>
                <td><xsl:value-of select='substring(@КНД,2,1)'/></td>
                <td><xsl:value-of select='substring(@КНД,3,1)'/></td>
                <td><xsl:value-of select='substring(@КНД,4,1)'/></td>
                <td><xsl:value-of select='substring(@КНД,5,1)'/></td>
                <td><xsl:value-of select='substring(@КНД,6,1)'/></td>
            </tr>
        </xsl:template>
    </xsl:stylesheet>
    Ответ написан
    Комментировать
  • Как указать условия доставки в карточке товара Битрикс?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Да как всегда способов масса :)

    Начнем с самого простого, нудного и заведомо гиблого пути - указание текста доставки напрямую в описании товара.
    Плохой вариант, едем дальше.

    Можно создать инфоблок-справочник с типами товара. У самого товара делать привязку к инфоблоку и выводить в шаблоне карточки товара.
    Хороший вариант - быстрый в реализации, совсем не геморройный.
    Однако есть ньанс - он совсем не связан с службами доставки. То есть, если в инфоблоке Вы напишете - 1-2 дня, а в Службе доставки 5-6, то на странице оформления заказа он увидит 5-6 дней, а не 1-2.

    Еще более лучшим решением, является создание ограничений на службу доставки, получение и их обработка на странице товара и уже вывод пользователю.
    Однако это очень долгий и трудный путь.

    Наилучшей комбинацией было бы создание своего ограничения в службе доставки завязанного на инфоблок-справочник. Т.е. комбинация 2 и 3 решения.

    P.S. Как прицел на будущее я бы рекомендовал последний вариант, однако ввиду начинающего знакомства с Битриксом только 2 вариант.
    Ответ написан
    Комментировать
  • Как в метатеги вставить переменную в битриксе?

    gromdron
    @gromdron
    Работаю с Bitrix24
    А эти варианты особо и не будут работать.
    Можете попробовать универсальный синтаксис конечно, но не думаю что в этой части он работает.
    $APPLICATION->SetPageProperty("title", "={$cur_city[$poddomen]}");


    Что касается именно задачи, то обычно это делается так:
    1) Разрабатываем компонент, ну например custo:header.meta
    2) В компоненте проверяем условия (например через GetPageProperty), а так же доп. параметры.
    Если по всем показателям нужно заменить - используйте конструкцию Lorem Ipsum . Если заменять не нужно - пропускаете.

    Важный вопрос: Почему делать нужно именно так?
    В Битрикс24 нельзя лишать пользователя возможности переопределять конкретные теги на страницах.
    Лучше это все делать в одном месте, чем потом искать откуда появляется $cur_city и что такое $poddomen.
    Да и к тому, же, нужно будет проходиться по каждой странице и смотреть что нет ошибок ли на других, а так - 1 компонент который целостно закрывает эту задачу.
    Ответ написан
    Комментировать
  • Битрикс. Почему ломается верстка после выхода из логина?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Все как всегда: все было хорошо, как вдруг стала ломаться верстка после разлогинивания.


    Компонент выводит данные из инфоблока? Права проверяли?
    Ответ написан
  • Как подключить мой файл js в компоненте Bitrix?

    gromdron
    @gromdron
    Работаю с Bitrix24
    1) То, что Вы делаете, должно работать (по крайне мере на первый взгляд)

    2) В компоненте автоматически подключается файл шаблона script.js.

    3) Дополнительные скрипты можно подключить:
    Ответ написан
    2 комментария
  • Как получить товары со скидкой, которые заданны с помощью условий?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы используете только товарный маркетинг то эта схема еще может прокатиться, но вот с правилами корзины это уже не прокатит.

    Дело в том, что в товарном маркетинге (устарел), использовались реляции к товарам, а вот в правилах корзины уже нет.
    Правила корзины применяются исходя из значений указанных в корзине (спс КЭП) и до момента формирования заказа их нет (т.е. нужно создать временный заказ, выполнить его просчет и Вы получите все товары, к которым применены скидки, но увы не поймете какие именно).
    Ответ написан
  • Как выполнить поиск в JSON?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы не хотите работать с json, то почему вы не пробовали работать с ним как с строкой?
    Ответ написан
    Комментировать
  • Как подключить RSS ленту яндекс?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Немного непонятен Ваш вопрос.
    По спецификации RSS они уже содержат ссылки, но Яндекс не формирует у себя новости - он содержит лишь предпросмотр и ссылки на сайты с оригинальным текстом. Т.е. при нажатии на ссылку, Вы перейдете на Яндекс, который перенаправит Вас на сайт с реальной новостью. И в RSS он уже отдает эту ссылку.
    Ответ написан
    Комментировать
  • Как установить права доступа на ссылку?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Для обоих случаев Вам поможет статическией метод \CSite::InGroup([11]), а так же условие показа пункта меню (если они конечно в меню)
    Ответ написан
    4 комментария
  • Как закодировать строку в Unicode последовательность?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы уверены что на входе будут только a-zA-Z0-9-=+- (похоже на base64) то можно упростить и не перекодировать, например так:

    $uncomingString = 'W+I4zLZyeJDAhQMe33tYRcXC+Falj9baMfjJw5yOijaPNHDYcnNlRlTGm3rvA6cn2hXMmW4ZKEyTphwzNMQlOlnNiCHK2LLpJLgXK6JHKuTYeParwqCud5Vn2dZXpxctrQf8OkbCqF12u0GcBR2or2HFBrEV13Jd5YAX4bRbUBk=';
    
    
    function forceUnicode( $str = '' )
    {
    	$result = '';
    
    	for( $i=0,$length=strlen($str); $i<$length; $i++)
    	{
    		$result .= "\\u".str_pad(bin2hex($str[$i]), 4, '0', STR_PAD_LEFT);
    	}
    
    	return $result;
    }
    
    echo forceUnicode($uncomingString);
    
    /*
    Выведет: 
    \u0057\u002b\u0049\u0034\u007a\u004c\u005a\u0079\u0065\u004a\u0044\u0041\u0068\u0051\u004d\u0065\u0033\u0033\u0074\u0059\u0052\u0063\u0058\u0043\u002b\u0046\u0061\u006c\u006a\u0039\u0062\u0061\u004d\u0066\u006a\u004a\u0077\u0035\u0079\u004f\u0069\u006a\u0061\u0050\u004e\u0048\u0044\u0059\u0063\u006e\u004e\u006c\u0052\u006c\u0054\u0047\u006d\u0033\u0072\u0076\u0041\u0036\u0063\u006e\u0032\u0068\u0058\u004d\u006d\u0057\u0034\u005a\u004b\u0045\u0079\u0054\u0070\u0068\u0077\u007a\u004e\u004d\u0051\u006c\u004f\u006c\u006e\u004e\u0069\u0043\u0048\u004b\u0032\u004c\u004c\u0070\u004a\u004c\u0067\u0058\u004b\u0036\u004a\u0048\u004b\u0075\u0054\u0059\u0065\u0050\u0061\u0072\u0077\u0071\u0043\u0075\u0064\u0035\u0056\u006e\u0032\u0064\u005a\u0058\u0070\u0078\u0063\u0074\u0072\u0051\u0066\u0038\u004f\u006b\u0062\u0043\u0071\u0046\u0031\u0032\u0075\u0030\u0047\u0063\u0042\u0052\u0032\u006f\u0072\u0032\u0048\u0046\u0042\u0072\u0045\u0056\u0031\u0033\u004a\u0064\u0035\u0059\u0041\u0058\u0034\u0062\u0052\u0062\u0055\u0042\u006b\u003d
    */


    Для конкретно Вашего примера выдает тот же результат, что и требовалось, но нужно на разных данных потестировать конечно - мог и налажать
    Ответ написан
    1 комментарий