Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Михаил Базаров (Автор тем)

Внимание! все сообщения проходят премодерацию. Ваше сообщение появится после проверки
Выбрать дату в календареВыбрать дату в календаре

Изменить тип установки редакции "Битрикс24 + интернет-магазин" на "Интернет-магазин + Битрикс24", Смена режима работы портала и магазина на 1С-Битрикс
 
Если есть необходимость сменить тип установки редакции "Битрикс24 + интернет-магазин" на "Интернет-магазин + Битрикс24"

В командной php-строке выполняем
Код
\Bitrix\Main\Config\Option::set("sale", "~IS_SALE_CRM_SITE_MASTER_FINISH", "Y");
\Bitrix\Main\Config\Option::set("sale", "~IS_SALE_BSM_SITE_MASTER_FINISH", "N");

Для чего это может понадобиться:
Например, для использования модуля обмена с 1С в старом режиме, с помощью xml файлов а не по REST-API.

В целом, меняя режим работы вы выставлете приоритет работы. Что для вас важнее портал или магазин.

Битрикс24 + интернет-магазин: в первую очередь портал, во вторую магазин
Интернет-магазин + Битрикс24: в первую очередб магазин, во вторую портал
Изменено: Михаил Базаров - 06.10.2021 09:46:18
Серия 6: Выводим и настраиваем каталог товаров- разделы, детальная карточка, оформление заказа
 
Серия 6: Выводим и настраиваем каталог товаров- разделы, детальная карточка, оформление заказа

Выводим комплексный компонент каталога, настраиваем ЧПУ и подготавливаем компонент к верстке. Настраиваем компоненты корзины и оформления заказа. Избавляемся от всего БЭМ в css
Сниппеты 1С-Битрикс компонентов для phpstorm, Что бы вставлять компоненты битрикс, прямо в PhpStorm, с помощью комбинации Cmd+J
 
Что бы вставлять компоненты битрикс, прямо в PhpStorm, с помощью комбинации Cmd+J
Или выводить автоподсказки по выводу компонентов, с выбором через TAB

Закидываем приложенный файл в

Для macOS:
~/Library/Application Support/JetBrains/PhpStorm20XX/templates

Для Windows10:
С\\Users\ВАШ_ПОЛЬЗОВАТЕЛЬ\AppData\Roaming\JetBrains\PhpStorm­XX\templates

Где XX версия шторма
https://camouf.ru/upload/fo_all/PhpStorm.xml.zip
Изменено: Михаил Базаров - 18.09.2021 19:06:06
Серия 1: Вступление и установка 1С-Битрикс на панель управления сервером Fastpanel
 
Серия 1: Вступление и установка 1С-Битрикс на панель управления сервером Fastpanel

Вступительная часть: рассказываю о целях проекта и устанавливаем 1С-Битрикс на виртуальный сервер. Установка панель управления сервером Fastpanel на чистую установку Debian10, оптимизация под 1С-Битрикс и базовые настройки панели управления
Получить информацию о заказе на D7, Как получить информацию о заказах в Битрикс. Вариант со старым ядром и с новым D7
 
Старый вариант получения информации обо всех заказах в битрикс
Код
$db_sales = CSaleOrder::GetList(
    array(), // Сортировка
    array(), // Фильтр
    array()  // Поля которые нужно вывести
);
while ($ar_sales = $db_sales->Fetch()) {
   print_r($ar_sales);
}
Если не использовать сортировку, фильтр и поля, получите вообще все заказы со всей информацией о них


Вариант в D7
Код
$dbRes = \Bitrix\Sale\Order::getList([
    'select' => [
        '*' // Поля которые нужно вывести если * вообще все
    ],
    'filter' => [
        '*' // Фильтр - если * вообще все
    ]
]);

while ($item = $dbRes->fetch())
{
    print_r($item);
}


Например: Отобрать все заказы текущего пользователя, которые в статусе Оплачен (P) и вывести только цену
Код
$dbRes = \Bitrix\Sale\Order::getList([
    'select' => [
        'PRICE' // Интересует только цена
    ],
    'filter' => [
        '=USER_ID' => $USER->GetID(), // Текущий пользователь
        '=STATUS_ID' => 'P' // Статуст оплачен
    ]
]);

while ($item = $dbRes->fetch())
{
    print_r($item);
}
Настройка обмена между 1С:Предприятие и магазином на "1С-Битрикс24: Интернет-магазин + CRM" по REST протоколу
 
Настройка обмена между 1С:Предприятие и магазином на "1С-Битрикс24: Интернет-магазин + CRM" по REST протоколу

В этой заметке расскажу как настроить синхронизацию между 1С:предприятие и "1С-Битрикс24: Интернет-магазин + CRM". Она же актуальна для коробочных версий "CRM Битрикс-24".
Все воспроизводиться с помощью нового модуля обмена для 1С:Предприятие.
Красивый календарь для формы ввода даты в input
 
В битриксе е сть встроенный инструмент для ввода даты в поля input
Похож на datepicker, но более удобный
Есть функционал отдельного выбора годов и месяцев

Просто, к нужному input добавляем
Код
onclick="BX.calendar({node: this, field: this, bTime: false});"

<input type="text" name="INPUTNAME" onclick="BX.calendar({node: this, field: this, bTime: false});"/>

Если изменить bTime на true - будет еще и выбор времени.

Изменено: Михаил Базаров - 02.07.2021 09:47:43
Вывести переключатель сайтов при многосайтовой структуре, Переключатель сайтов в Битрикс
 
Вывести переключатель сайтов при многосайтовой структуре
Добавить во все шаблоны (если не один)
Код
<?$APPLICATION->IncludeComponent(
   "bitrix:main.site.selector",
   "",
   Array(
       "SITE_LIST" => array(),
       "CACHE_TYPE" => "A",
       "CACHE_TIME" => "3600"
   ),
   false
);?>
Пересоздать картинки анонса из детальных в инфоблоке, Если нужно пересоздать все картинки анонсов товаров каталога (или любого другого инфоблока) из детальных картинок Подойдет вот такой код
 
Пересоздать картинки анонса из детальных в каталоге.

Если нужно пересоздать все картинки анонсов товаров каталога (или любого другого инфоблока) из детальных картинок
Подойдет вот такой код
Код
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
CModule::IncludeModule("iblock");
CModule::IncludeModule("file");

$ID = 11;//id инфоблока

$arFilter = Array("IBLOCK_ID"=>$ID);
$rsEl = CIBlockElement::GetList(Array(), $arFilter);
while($arEl = $rsEl->GetNext()){
  $el = new CIBlockElement;
       $arFields = Array();
  if($arEl["DETAIL_PICTURE"]){
     $arFields['PREVIEW_PICTURE'] = CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"] . CFile::GetFileArray($arEl["DETAIL_PICTURE"])["SRC"]);
     $arFields['PREVIEW_PICTURE']["del"] = "Y";
        $el->Update($arEl["ID"], $arFields);
  }
}
Для прогрева кеша сайта на битрикс., Создать весь кеш в битриксе, в автоматическом режиме
 
Для Прогрева кеша сайта на битрикс. Создать весь кеш в битриксе, в автоматическом режиме

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

А хотите сразу же ускорить сайт, просто обойдя все страницы. Можно воспользоваться таким способом:
Запускаем виртуальную машину, на любом unix дистрибутиве (как вариант, если сайт и так на сервере, можно прямо на этом же)

и в терминале выполняем команду:
wget -r --spider test.site http://адрес.ru

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

Вариация с использованием UserAgent

wget -r -k -l 7 -p -E -nc --user-agent="Mozilla/5.0 (Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/5З7.З6 (KHTML, like Gecko) Chrome/55.0.288З.75 Safari/5З7.З6" http://ВАШСАЙТ.ru

КЛЮЧИ

--spider - Не сохранять сайт в файлы

-r — указывает на то, что нужно рекурсивно переходить по ссылкам на сайте, чтобы скачивать страницы.

-k — используется для того, чтобы wget преобразовал все ссылки в скаченных файлах таким образом, чтобы по ним можно было переходить на локальном компьютере (в автономном режиме).

-p — указывает на то, что нужно загрузить все файлы, которые требуются для отображения страниц (изображения, css и т.д.).

-l — определяет максимальную глубину вложенности страниц, которые wget должен скачать (по умолчанию значение равно 5, в примере мы установили 7). В большинстве случаев сайты имеют страницы с большой степенью вложенности и wget может просто «закопаться», скачивая новые страницы. Чтобы этого не произошло можно использовать параметр -l.

-E — добавлять к загруженным файлам расширение .html.

-nc — при использовании данного параметра существующие файлы не будут перезаписаны. Это удобно, когда нужно продолжить загрузку сайта, прерванную в предыдущий раз.
Узнать базовую цену товара, зная его ID
 
Узнать базовую цену элемента, зная его ID

Если Вы, как и я, столкнулись с реализацией списка товаров, в компоненте "catalog" на компоненте списка новостей
Просто, "великолепный" разработчик воткнул news.list в section.php комплексного компонента "каталог"
Это конечно же, полная дичь: но предположим, что переделывать все не вариант и не входит в бюджет

Задача, просто вывести цену текущего элемента каталога в news.list
Используем метод CPrice::GetBasePrice - достаточно знать только ID элемента (его мы знаем в ключе $arItem['ID'] )
Код
<?
$ar_res = CPrice::GetBasePrice($arItem['ID']);
echo $ar_res['PRICE'].' р.';
?>
PS Переделывайте это, при первой же возможности. Использовать исключительно в рамках ограниченного бюджета и времени.
Компонент который умеет выводить разделы инфоблока с элементами., Битрикс компонент который выводит разделы и вложенные в них элементы
 
Компонент который умеет выводить разделы инфоблока с элементами.
Черновик, сделал за часок. Настройки и шаблон немного не гибкие, будет дорабатываться.

Выводит:
- название и ссылку на раздел,
- название и ссылку на элемент,
- картинку анонса элемента,
- описание анонса элемента
- цену элемента (если установлен торговый каталог)

Пока плохо выводит свойства. В принципе выводит и дает их выбрать в параметрах. Но в шаблон нужно добавлять вручную.
Что бы работали ссылки, они должны быть обязательно указаны в настройках инфоблока (прописывание в ручную будет позже).
Дает указать количество выводимых элементов.

ВАЖНО! работает с версии Битрикс 18.5 (ниже нет)

Размещать в своем пространстве имен
Будет доступен в Контент=>Каталог

Скачать
https://camouf.ru/upload/fo_all/catalog.section.elements.zip
Изменено: Михаил Базаров - 25.06.2021 11:54:41
Получить группу текущего авторизованного пользователя в битрикс, Показать пользователю группу, к которой он принадлежит
 
Получить группу текущего авторизованного пользователя в битрикс

Если нужно вывести где-то на странице или в кабинете группу, к которой относится текущий авторизованный пользователь. Можно получить ее методом
CGroup::GetByID

Сначала, методом CUser::GetUserGroup - получаем ID всех групп, к которым относится пользователь.
Затем, раздербаниваем массив foreach-ем и получаем названия всех групп по их ID
Код
<?
global $USER;
   $curUserId = $USER->GetID(); // ID текущего пользователя
   $arGroups = CUser::GetUserGroup($curUserId); // ID групп текущего пользователя
   foreach ($arGroups as $curUserGroups) {
    $rsGroup = CGroup::GetByID($curUserGroups); // Получаем названия всех групп
    $arGroup = $rsGroup->Fetch();
    if ($arGroup['ID'] !== '2') {
            echo $arGroup['NAME'];  // И выводим
     }
   }
?>
В моем примере, я еще выполняю проверку ( if ($arGroup['ID'] !== '2') ). Не вывожу группу "Все пользователи" - у меня ее ID=2
По сути, все пользователи состоят в этой группе- выводить ее ни к чему
Pull to refresh, не большой скрипт для обновления страницы, Скрипт который иммитирует обновление страницы при протягивании. Годится для мобильных версий сайтов и приложений на cordova
 
Pull to refresh, не большой скрипт  для обновления страницы, при перетягивании, на мобильных телефонах.
Можно использовать и в мобильном приложении на cordova/phonegap

API методы тут
https://github.com/BoxFactura/pulltorefresh.js
Код
/*!
 * pulltorefreshjs v0.1.18
 * (c) Rafael Soto
 * Released under the MIT License.
 */
;!function (b, a) {
    "object" == typeof exports && "undefined" != typeof module ? module.exports = a() : "function" == typeof define && define.amd ? define(a) : (b = b || self).PullToRefresh = a()
}(this, function () {
    var f = {
        pullStartY: null,
        pullMoveY: null,
        handlers: [],
        styleEl: null,
        events: null,
        dist: 0,
        state: "pending",
        timeout: null,
        distResisted: 0,
        supportsPassive: !1,
        supportsPointerEvents: !!window.PointerEvent
    };
    try {
        window.addEventListener("test", null, {
            get passive() {
                f.supportsPassive = !0
            }
        })
    } catch (f) {
    }
    var b = {
        setupDOM: function (e) {
            if (!e.ptrElement) {
                var i = document.createElement("div");
                e.mainElement !== document.body ? e.mainElement.parentNode.insertBefore(i, e.mainElement) : document.body.insertBefore(i, document.body.firstChild), i.classList.add(e.classPrefix + "ptr"), i.innerHTML = e.getMarkup().replace(/__PREFIX__/g, e.classPrefix), e.ptrElement = i, "function" == typeof e.onInit && e.onInit(e), f.styleEl || (f.styleEl = document.createElement("style"), f.styleEl.setAttribute("id", "pull-to-refresh-js-style"), document.head.appendChild(f.styleEl)), f.styleEl.textContent = e.getStyles().replace(/__PREFIX__/g, e.classPrefix).replace(/\s+/g, " ")
            }
            return e
        }, onReset: function (e) {
            e.ptrElement.classList.remove(e.classPrefix + "refresh"), e.ptrElement.style[e.cssProp] = "0px", setTimeout(function () {
                e.ptrElement && e.ptrElement.parentNode && (e.ptrElement.parentNode.removeChild(e.ptrElement), e.ptrElement = null), f.state = "pending"
            }, e.refreshTimeout)
        }, update: function (e) {
            var j = e.ptrElement.querySelector("." + e.classPrefix + "icon"),
                i = e.ptrElement.querySelector("." + e.classPrefix + "text");
            j && ("refreshing" === f.state ? j.innerHTML = e.iconRefreshing : j.innerHTML = e.iconArrow), i && ("releasing" === f.state && (i.innerHTML = e.instructionsReleaseToRefresh), "pulling" !== f.state && "pending" !== f.state || (i.innerHTML = e.instructionsPullToRefresh), "refreshing" === f.state && (i.innerHTML = e.instructionsRefreshing))
        }
    }, h = function (e) {
        return f.pointerEventsEnabled && f.supportsPointerEvents ? e.screenY : e.touches[0].screenY
    }, c = function () {
        var m;

        function n(o) {
            var l = f.handlers.filter(function (i) {
                return i.contains(o.target)
            })[0];
            f.enable = !!l, l && "pending" === f.state && (m = b.setupDOM(l), l.shouldPullToRefresh() && (f.pullStartY = h(o)), clearTimeout(f.timeout), b.update(l))
        }

        function k(i) {
            m && m.ptrElement && f.enable && (f.pullStartY ? f.pullMoveY = h(i) : m.shouldPullToRefresh() && (f.pullStartY = h(i)), "refreshing" !== f.state ? ("pending" === f.state && (m.ptrElement.classList.add(m.classPrefix + "pull"), f.state = "pulling", b.update(m)), f.pullStartY && f.pullMoveY && (f.dist = f.pullMoveY - f.pullStartY), f.distExtra = f.dist - m.distIgnore, f.distExtra > 0 && (i.cancelable && i.preventDefault(), m.ptrElement.style[m.cssProp] = f.distResisted + "px", f.distResisted = m.resistanceFunction(f.distExtra / m.distThreshold) * Math.min(m.distMax, f.distExtra), "pulling" === f.state && f.distResisted > m.distThreshold && (m.ptrElement.classList.add(m.classPrefix + "release"), f.state = "releasing", b.update(m)), "releasing" === f.state && f.distResisted < m.distThreshold && (m.ptrElement.classList.remove(m.classPrefix + "release"), f.state = "pulling", b.update(m)))) : i.cancelable && m.shouldPullToRefresh() && f.pullStartY < f.pullMoveY && i.preventDefault())
        }

        function p() {
            if (m && m.ptrElement && f.enable) {
                if ("releasing" === f.state && f.distResisted > m.distThreshold) {
                    f.state = "refreshing", m.ptrElement.style[m.cssProp] = m.distReload + "px", m.ptrElement.classList.add(m.classPrefix + "refresh"), f.timeout = setTimeout(function () {
                        var i = m.onRefresh(function () {
                            return b.onReset(m)
                        });
                        i && "function" == typeof i.then && i.then(function () {
                            return b.onReset(m)
                        }), i || m.onRefresh.length || b.onReset(m)
                    }, m.refreshTimeout)
                } else {
                    if ("refreshing" === f.state) {
                        return
                    }
                    m.ptrElement.style[m.cssProp] = "0px", f.state = "pending"
                }
                b.update(m), m.ptrElement.classList.remove(m.classPrefix + "release"), m.ptrElement.classList.remove(m.classPrefix + "pull"), f.pullStartY = f.pullMoveY = null, f.dist = f.distResisted = 0
            }
        }

        function j() {
            m && m.mainElement.classList.toggle(m.classPrefix + "top", m.shouldPullToRefresh())
        }

        var e = f.supportsPassive ? {passive: f.passive || !1} : void 0;
        return f.pointerEventsEnabled && f.supportsPointerEvents ? (window.addEventListener("pointerup", p), window.addEventListener("pointerdown", n), window.addEventListener("pointermove", k, e)) : (window.addEventListener("touchend", p), window.addEventListener("touchstart", n), window.addEventListener("touchmove", k, e)), window.addEventListener("scroll", j), {
            onTouchEnd: p,
            onTouchStart: n,
            onTouchMove: k,
            onScroll: j,
            destroy: function () {
                f.pointerEventsEnabled && f.supportsPointerEvents ? (window.removeEventListener("pointerdown", n), window.removeEventListener("pointerup", p), window.removeEventListener("pointermove", k, e)) : (window.removeEventListener("touchstart", n), window.removeEventListener("touchend", p), window.removeEventListener("touchmove", k, e)), window.removeEventListener("scroll", j)
            }
        }
    }, d = {
        distThreshold: 60,
        distMax: 80,
        distReload: 50,
        distIgnore: 0,
        mainElement: "body",
        triggerElement: "body",
        ptrElement: ".ptr",
        classPrefix: "ptr--",
        cssProp: "min-height",
        iconArrow: "⇣",
        iconRefreshing: "…",
        instructionsPullToRefresh: "Pull down to refresh",
        instructionsReleaseToRefresh: "Release to refresh",
        instructionsRefreshing: "Refreshing",
        refreshTimeout: 500,
        getMarkup: function () {
            return '\n<div class="__PREFIX__box">\n  <div class="__PREFIX__content">\n    <div class="__PREFIX__icon"></div>\n    <div class="__PREFIX__text"></div>\n  </div>\n</div>\n'
        },
        getStyles: function () {
            return "\n.__PREFIX__ptr {\n  box-shadow: inset 0 -3px 5px rgba(0, 0, 0, 0.12);\n  pointer-events: none;\n  font-size: 0.85em;\n  font-weight: bold;\n  top: 0;\n  height: 0;\n  transition: height 0.3s, min-height 0.3s;\n  text-align: center;\n  width: 100%;\n  overflow: hidden;\n  display: flex;\n  align-items: flex-end;\n  align-content: stretch;\n}\n\n.__PREFIX__box {\n  padding: 10px;\n  flex-basis: 100%;\n}\n\n.__PREFIX__pull {\n  transition: none;\n}\n\n.__PREFIX__text {\n  margin-top: .33em;\n  color: rgba(0, 0, 0, 0.3);\n}\n\n.__PREFIX__icon {\n  color: rgba(0, 0, 0, 0.3);\n  transition: transform .3s;\n}\n\n/*\nWhen at the top of the page, disable vertical overscroll so passive touch\nlisteners can take over.\n*/\n.__PREFIX__top {\n  touch-action: pan-x pan-down pinch-zoom;\n}\n\n.__PREFIX__release {\n  .__PREFIX__icon {\n    transform: rotate(180deg);\n  }\n}\n"
        },
        onInit: function () {
        },
        onRefresh: function () {
            return location.reload()
        },
        resistanceFunction: function (i) {
            return Math.min(1, i / 2.5)
        },
        shouldPullToRefresh: function () {
            return !window.scrollY
        }
    }, a = ["mainElement", "ptrElement", "triggerElement"], g = function (e) {
        var i = {};
        return Object.keys(d).forEach(function (j) {
            i[j] = e[j] || d[j]
        }), i.refreshTimeout = "number" == typeof e.refreshTimeout ? e.refreshTimeout : d.refreshTimeout, a.forEach(function (j) {
            "string" == typeof i[j] && (i[j] = document.querySelector(i[j]))
        }), f.events || (f.events = c()), i.contains = function (j) {
            return i.triggerElement.contains(j)
        }, i.destroy = function () {
            clearTimeout(f.timeout);
            var j = f.handlers.indexOf(i);
            f.handlers.splice(j, 1)
        }, i
    };
    return {
        setPassiveMode: function (e) {
            f.passive = e
        }, setPointerEventsMode: function (e) {
            f.pointerEventsEnabled = e
        }, destroyAll: function () {
            f.events && (f.events.destroy(), f.events = null), f.handlers.forEach(function (i) {
                i.destroy()
            })
        }, init: function (e) {
            void 0 === e && (e = {});
            var i = g(e);
            return f.handlers.push(i), i
        }, _: {setupHandler: g, setupEvents: c, setupDOM: b.setupDOM, onReset: b.onReset, update: b.update}
    }
});
PullToRefresh.init({
    mainElement: ".app_container", onRefresh: function () {
        window.location.reload()
    }
});
Скрипт для иммитации боковой панели, выезжающей\исчезающей при протягивании пальцем по экрану.
 
Скрипт для иммитации боковой панели, выезжающей\исчезающей при протягивании пальцем по экрану.
Пригодится для мобильных версий сайтов или мобильных приложений на cordova
Подробнее тут https://github.com/mango/slideout/releases/

Скачать
https://camouf.ru/upload/fo_all/slideout_1.0.1.zip
Изменено: Михаил Базаров - 23.06.2021 13:10:53
Вывести разделы инфоблока по первым буквам не меняя структуру каталога. Алфавитный указатель
 
Вывести разделы инфоблока по первым буквам не меняя структуру каталога. Алфавитный указатель

Например: у нас есть инфоблок с большим количеством разделов. И мы хотим, на сайте разбить разделы по буквам. Самый простой способ, это конечно же добавить буквы в разделы каталога, и перераспределить сами разделы по своим буквам.
Но... а если и разделов более 2000-яч и вообще не вариант, так менять структуру инфоблока.
Компонент добавления элемента в инфоблок, с отправкой письма о добавлении и AJAX., Битрикс компонент для реализации формы добавления элемента инфоблока
 
Сделан по быстрому, в качестве базовой заготовки для дальнейшего развития.
Развиваться будет, в полноценный компонент, в рамках видеокурса "Разработка доски объявлений на Битрикс" https://bxstore.ru/

Пока, можно использовать как форму обратной связи, с записью в инфоблок и отправкой письма.

На данный момент умеет:
- Выводить, на заполнение,  свойства инфоблока. Только не множественные.
- Загружать файлы в свойство "Файл". Использует штатный компонент main.file.input (dragn_n_drop).
- Защита, от совсем простых ботов (проверка скрытого поля на заполнение)
- Поддерживает AJAX
- Отправляет письмо о добавлении элемента
- Все параметры управляемые (картинка 1)
- Шаблон маскимально простой (картинка 2)
- Легко дорабатывается, управляется и расширяется.

Письма отправляет обычной функцией php-mail, но в файле component.php есть закомментированый участок
(картинка 3):
Можно использовать штатный метод Битрикс Event::send - который передаст поля в штатное же почтовое событие FEEDBACK_FORM

Пример работы: https://camouf.ru/pricenew/#order_tz_form

PS: В рамках видеокурса будет превращен в полноценный компонент добавления объявления на доску. С гугло капчей, работой с любыми типами полей И так далее.

Скачать: https://camouf.ru/upload/fo_all/feedback.form.element.zip
Изменено: Михаил Базаров - 03.07.2021 11:54:33
Вывести минимальную и максимальную цену в разделе каталога Битрикс.
 
Вывести минимальную и максимальную цену в разделе каталога Битрикс.

Что бы вывести минимальную и максимальную стоимость товаров, из каталога 1С-Битрикс, достаточно получить все товары методом CIBlockElement::GetList  и загнать цены в массив
Вывести количество не прочитанных, персональных сообщений форума в любом месте сайта., Вывести количество не прочитанных, персональных сообщений форума в любом месте сайта.
 
Что бы вывести количество не прочитанных (именно персональных) сообщений из модуля форума.
В любом, нужном, месте сайта вызываем метод
Код
<?
CModule::IncludeModule("forum");
      $messs = CForumPrivateMessage::GetNewPM(
              array("FOLDER_ID" => 1)
     );
 echo $messs['UNREAD_PM']
?>
Скелет-шаблон для создания мобильного приложения в Cordova.
 
Базовая верстка для 1С-Битрикс, включены js плагины:
- SNAP : боковая панель при протягивании по контенту
- Pull To Refresh : Обновление контейнера с контентом при протягивании вниз

Видео работы:
https://www.youtube.com/watch?v=XJ2q86-LAWE

Скачать:
https://camouf.ru/upload/fo_all/mobile...late-bx.7z

Плейлист - создание мобильного приложения для любого сайта:
https://www.youtube.com/playlist?list=...SGZcyhbgx3

https://youtu.be/XJ2q86-LAWE
Изменено: Михаил Базаров - 21.06.2021 10:58:25
Заметки разработчика

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

Заказaть разработку attention