echo "hello from mail.com.ru." | msmtp --debug -a site.ru test@site.ruгде site.ru - значение account в конфиге .msmtprc
пример конфига для яндекса
# smtp account configuration for site.ru account site.ru logfile /home/bitrix/msmtp_site.ru.log host smtp.yandex.ru port 587 from noreply@site.ru keepbcc on auth on user noreply@site.ru password *********** tls on tls_starttls on tls_certcheck off
Не помогают вариации настроек главного модуля для отправки почты и т.д.
Укажите тут /bitrix/admin/settings.php?lang=ru&mid=main&tabControl_active_tab=tab_mail&back_url_settings= "Дополнительный параметр для передачи функции mail:" -a site.ru (см. скрин)
Чтобы гуглю было проще искать: SUCCESS_EXEC='F' , b_event, не работает почта msmtprc
После восстановления пароля, пользователь нажимает на кнопку авторизации, вводит свой логин и новый пароль, но авторизация не происходит. Ошибок не выдает, просто обновляется страница и на этом все. После повторного нажатия на кнопку авторизации - аторизует. В чем может быть проблема?
Всем привет! У меня вот такой вопрос, какие можете посоветовать курсы по битриксу? И вообще что думаете по перспективам развития битрикса в Казахстане? Стоит ли сейчас ставить фокус на его изучение, либо работать лучше с Российскими партнерами? все таки если быть откровенным в России разработчики битрикса куда более продвинутые и фрилансера найти гораздо легче? Спасибо заранее за ответ)
Иногда плавающая "панель управления Битрикс" вызывает трудности. Это бывает, когда на сайте сделана плавающая шапка. Тогда либо (чаще всего) панель Битрикса перекрывает шапку либо наоборот и доступ другой панели становится затруднительным. Да, для неавторизованных и других пользователей, которым не доступна панель администрирования - проблем нет. Вот и приходится заниматься изобретением колеса! Вот если бы была возможность "прятать за край" панель администратора Битрикс и показывать при подводе мышки к краю экрана - вот это было бы очень удобно! Помните была подобная функция в Windows, позволяющая прятать за край экрана "Панель задач"?
Я так понял, пока гуглил, что CUSTOM_PRICE очень "любим" многими за то, что ведёт себя как FINAL_PRICE (которого нет, но суть передаёт лучше). Знаю ситуации, когда такое поведение необходимо. Но так получилось, что чаще мне надо добавить кастомную цену на товар не отключая при этом последующие правила работы с корзиной. И вот я нашёл способ добавлять заранее известную наценку (так можно и понижать цену, но я только про наценку буду говорить) не используя CUSTOM_PRICE. Пропишу основные моменты.
Раз у меня все такие товары всё равно добавляются через кастомный ajax запрос, и наценка известна в момент добавления, то могу спокойно её передавать свойством товара в корзине.
Просто в шаблоне корзины её не выводим для пользователя отдельно, раз она уже считается, тогда никого она смущать не будет. Будем использовать кастомный CatalogProvider (это слишком легко гуглится, чтобы дополнительно расписывать) и слегка дополним getProductData.
/**
* @param array $products
*
* @return Sale\Result
*/
public function getProductData(array $products)
{
$result = parent::getProductData($products);
// Во избежании казусов при работе с командной строкой PHP
if(!Bitrix\Main\Context::getCurrent()->getSite())
return $result;
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), Bitrix\Main\Context::getCurrent()->getSite());
$productDataList = array();
foreach($result->getData()['PRODUCT_DATA_LIST'] as $productId => $arProduct)
{
foreach($arProduct['PRICE_LIST'] as $basketItemId => &$arItem)
{
// При добавлении в корзину нет у товара ID, мы не сможем его свойства тут посмотреть
if((int)$basketItemId !== 0)
{
if($basketItem = $basket->getItemById($basketItemId))
{
$properties = $basketItem->getPropertyCollection()->getPropertyValues();
// Если есть наценка, добавляем её к цене
if(!empty($properties['PRICE_ADD']) && isset($properties['PRICE_ADD']['VALUE']))
{
$arItem['BASE_PRICE'] = $arItem['BASE_PRICE'] + (float)$properties['PRICE_ADD']['VALUE'];
$arItem['PRICE'] = $arItem['PRICE'] + (float)$properties['PRICE_ADD']['VALUE'];
}
}
}
}
$productDataList[$productId] = $arProduct;
unset($arItem);
}
$result->setData(['PRODUCT_DATA_LIST' => $productDataList]);
return $result;
}
Тут всё просто. При вызове обработчика, в корзине находятся товары со свойством наценки, их цена обновляется. Но если товар только добавили, он игнорируется (не достать его свойства пока что в этой функции, их вообще может ещё не быть у товара). На этом моменте компонент bitrix:sale.basket.basket при загрузке страницы уже работает как надо. И если раньше (у вас на проекте) обновление количества товара в корзине происходило через
$item->setField('QUANTITY', $value);
придётся его поменять на
$item->setFieldNoDemand('QUANTITY', $value);
(у меня переделанный шаблон, скопированный ещё тогда, когда цена пересчитывалась при нажатии кнопки "Пересчитать", и ajax обновление количества ручками писанное)
К сожалению, у меня не получилось заставить компонент плавающей корзины bitrix:sale.basket.basket.line обновлять цену при добавлении. Но если копировать его в своё пространство имён и наследовать, то в ajax.php перед вызовом компонента добавляем пересчёт корзины
// Не надо нам при удалении ничего пересчитывать здесь. Таков путь.
if(!$_POST['sbblRemoveItemFromCart'])
{
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(\Bitrix\Sale\Fuser::getId(), SITE_ID);
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$result = $basket->refresh($refreshStrategy);
$basket->save();
}
И где-нибудь повыше модуль sale подключаем (чего стесняться в компоненте корзины, он всё равно там будет). В стандартном шаблоне SITE_ID задаётся выше, так что он определён. И у меня нельзя в плавающей корзине менять количество, только удалять. Не знаю, как себя поведёт при другом раскладе, но теоретически никаких проблем быть не должно.
Собственно всё. Теперь наша наценка - полноценная часть цены. Без всяких блокирующих скидки CUSTOM_PRICE'ов. Единственное, что не делает этот способ совсем незаметным, так это вывод свойства наценки в заказе в админке менеджерам. Но лично я могу этим пренебречь.
Очередное обновление не прошло гладко. При установке обновления очередного модуля выскочила ошибка 504. Это уже не первый раз происходит.
Причина такой ошибки - создание индексов, на довольно большом объеме данных. Из-за чего база может затянуть время выполнения скрипта больше чем таймаут nginx. В этот раз виновником был модуль voximplant, при обновлении он зарядил создание индекса CREATE FULLTEXT INDEX IXF_VI_STATS_1 ON b_voximplant_statistic_index(CONTENT)
Приходится через SHOW PROCESSLIST смотреть когда база справится с этим, и продолжать установку обновлений, в надежде что скрипт последней установки закончил выполнение корректно.
Почему нельзя вынести создание индексов на агенты, уже после установки обновления, не понятно.
Идеально было бы вынести установку обновлений в отдельный фоновый процесс на сервере, а не устанавливать их дергая сервер ajax запросами.
Добрый день, всем! Необходимо реализовать функцию SEO шаблонов less, и использовать следующим образом {=less iblock_element_property.70 "0.30" iblock_element_property.191.PROPERTY_183 iblock_element_property.191.PROPERTY_184}.
Сейчас в инфоблоке iblock_element_property.70 есть свойство типа строка с разными значениями веса изделия, например, 0.12, 1.12 и т.д.
Т.е. если есть свойство инфоблока iblock_element_property.70 и его значение меньше числа 0.30, то выводить значение свойства PROPERTY_183. если больше либо равно 0.30, то выводить значение другого свойства PROPERTY_184 из другого инфоблока, как это реализовать в пользовательской функции, зарегистрировать обработчик события этой функции в файле init.php и использовать ее в шаблоне?
Помогите реализовать очень нужно, заранее спасибо!
здравствуйте. подскажите пожалуйста. у меня на почту приходят заказы с файлом. я настроил почтовый ящик, чтоб письма с этой почты автоматически создавался лид. Создался лид, в комментариях у лида есть файл заказа с почты. как мне обратиться через REST к лиду который создался недавно. Делаю по фильтру, но у меня выводит все лиды за все время.
Всем добрый вечер. Нудна очень помощь - сломался. Битрикс коробка на VirtualBox. При увеличении диска sda3 в момент указания начального сектора была допущена ошибка в одной цифре и теперь виртуальная машина не поднимается, выдает ошибку warning /dev/disk/by-label/bxroot does not exist и все в таком духе (скриншот прикрепил). Помогите пожалуйста, как мне исправить данную ситуацию? Сразу должен оговориться, я не программист и простые фразы из серии "запусти это " или зайти в "конфиг и поправь строку где есть что-то" вызовет еще тысячу вопросов, но помощь очень нужна...
Группировка свойств по разделам или проблема порядка в инфо-блоке с разнородными товарами. В админке есть интерфейс для группировки свойств по разделам. Задача фактически достать эту связку если где-то нужно в публичке или в каких-то алгоритмах импорта или в кабинете.
Существует таблица связей. Интересный у неё mysql-запрос DR OP TABLE if exists b_iblock_section_property; cre ate table if not exists b_iblock_section_property ( IBLOCK_ID int(11) not null, SECTION_ID int(11) not null, PROPERTY_ID int(11) not null, SMART_FILTER char(1), DISPLAY_TYPE char(1), DISPLAY_EXPANDED char(1), FILTER_HINT varchar(255), PRIMARY KEY pk_b_iblock_section_property (IBLOCK_ID, SECTION_ID, PROPERTY_ID), INDEX ix_b_iblock_section_property_1 (PROPERTY_ID), INDEX ix_b_iblock_section_property_2 (SECTION_ID) );
Но так это фреймворк, переходим на уровень абстракции, но всё таки посмотрев на таблицу b_iblock_section_property, можно отметить следующее. Существую записи с SECTION_ID = 0 это основные свойства, то есть выборка списка должна влючать записи как без раздела так и с заданным разделом, так и свойства наследников.
Тут предстоит получить всех родителей заданного раздела.
Мне же нужно просто свойства, не для умного фильтра а для кабинета, ну то есть в админке интерфейс же управления есть и клиент набравший аккуратно свойства, должен же их и при выводе видеть. Больше возможностей будет если работать с новым ядром и так use Bitrix\Iblock\SectionPropertyTable
Всё выводит, и главное что даёт порядок, для каталогов где разнородный товар.
OnBeforeEventSend - замена данных для макроса в почтовом шаблоне
Что то я долго искал решение, а как оказалось проблема была в том что входные переменные нужно передавать по ссылке!
Если нужно подставить свое значение в макрос (к примеру #AUTHOR#) почтового шаблона, например компонента обратной связи bitrix:main.feedback то делается это так:
AddEventHandler('main', 'OnBeforeEventSend', "OnBeforeEventSendHandler"); function OnBeforeEventSendHandler(&$arFields, &$arTemplate) { global $USER;
if($USER->IsAuthorized()) { $arFields["AUTHOR"] = 'Юзер залогинен: '.$USER->GetID().' ('.$USER->GetLogin().') '.$USER->GetFullName().', поле формы: '.$arFields["AUTHOR"]; }else{ $arFields["AUTHOR"] = 'Юзер не залогинен, поле формы: '.$arFields["AUTHOR"]; } }
Сегодня после установки двух новых сайтов, столкнулся с проблемой: при настройки обмена (самописный) с 1С, обмен не стартовал, журнал обмена 1С при проверке соединения выдавал ошибку - "Произошла ошибка авторизации".
Проверка авторизации происходила следующим образом:
Из 1С приходили данные пользователя (логин/пароль) в открытом виде.
Пользователь (админ для обмена), был записан в системной таблице "Список пользователей" (b_user).
Для того, чтобы проверить данные (сравнить логин/пароль), необходимо было получить MD5-хеш от пароля.
API Битрикса не использовалось, т.к. не покрывало все потребности. Например $USERcheck->Login()возвращает true или false и не понятно, что ввел пользователь не так логин или пароль? Или же если кто то авторизован под пользователем и под ним идет проверка функцией она всегда будет возвращать true.
Что удалось выяснить
Первым делом необходимо было выяснить, какие критические изменения были в релизе, обратившись к Истории версий, было найдено следующее изменение:
v20.5.400 2020-07-24 Пароли пользователей теперь хешируются по алгоритму SHA-512.
Таким образом необходимо было переписать функцию. Вот обновленная функция, для последней версии Битрикс:
//проверяем, является ли $password текущим паролем пользователя
function isUserPassword($userId, $password){
$userData = CUser::GetByID($userId)->Fetch();
$salt = substr($userData['PASSWORD'], 3, 16);
$password = crypt($password, '$6$'.$salt.'$');
return ($password == $userData['PASSWORD']);
}
Кому интересно, как формируется пароль и записывается в БД Битрикс, можно посмотреть теперь тут:
Сегодня письмо пришло, с такой отметкой. Только проблем в том, что я во вторник обновился и эти методы уже на 06.10.2020 были изменены, и стали вызывать ошибку при их статическом методе. Спасибо за такой подробный своевременный чейнджлог команда битрикс.
Теперь только нужно использовать так:
global $USER;
$USER->GetID();
И даже в этой отметке информация не полная, помимо методов CUser::GetID() и CUser::IsAuthorized(), так же недоступными для статичного вызова стали следующие методы класса CUser:
Но это же не важно указывать , а ещё уважаемые разработчики битрикс, у вас в файле /login/index.php вашего готового решения современный Интернет-магазин есть вот такой кусок кода:
Надеюсь вы там его не забудите поправить и включить в обновление.
ПС Кто знает что в чейнджлогах скрывается за пунктами: - Незначительные исправления. - Незначительные изменения. , которые от версии к версии появляются, может быть очередное исправление, которое заставит перелопатить наш код.
Модуль интеграции с iiko предоставляет возможность ресторанам и кафе, автоматизация рабочего процесса которых основана на системе iiko, организовывать предзаказы и заказы на доставку блюд с сайта на 1С-Битрикс.
Модуль позволяет организовать обмен меню (в том числе картинок, свойств, модификаторов) и заказами с сайтом на 1С-Битрикс. Модуль может работать как с одним рестораном, так и сетью ресторанов.
Полный список возможностей модуля:
Полная синхронизация ресторанов, меню с сайтом
Синхронизация и поддержка модификаторов iiko, с выбором в при заказе и возможностью отключения ненужных (или внутренних модификаторов на стороне сайта) - выгрузка заказов в систему iiko
Выгрузка заказов в систему iiko
Поддержка сети ресторанов с индивидуальным меню для каждого ресторана
Специально разработанный с учетом потребностей ресторанов компонент оформления заказа (включает корзину)
Возможность настроить оплату заказа любым способом (эквайринг, другое) с использованием любого совместимого с битрикс обработчика платежей
Cинхронизация зон доставки с автоматизированным выбором адреса в процедуре заказа
Возможность задавать скидки в системе битрикс с возможностью их выгрузки в заказ iiko как в виде скидки с произвольной суммой, так и в виде отдельного платежа в бонусной валюте
Удобные для кастомизации в современный дизайн bootstrap 4+ шаблоны компонентов
Подробное логирование всех действий, ошибок синхронизации и др. в журнал событий
Вы можете связаться (в том числе договориться о консультации через скайп, телеграм и др.) со мной через страницу контактов. Общий вопрос по модулю можно задать на форуме.
Нужно сделать в обоих вариантах переключатель Клиент - Партнёр (по-умолчанию стоит клиент)
Если переключатель установлен в положение "Клиент" - то ничего не меняется, всё работает как и раньше.
Но если переключатель поставить в положение "Партнёр", в форме запрашивается "id партнёра" и "пароль" По введению этих данных появляется таблица состоящая из 2х вкладок: текущие ремонты и архив.
На вкладке "Текущие ремонты" - список ремонтов данного партнёра, которые он передал в сервис. Отфильтровать эти ремонты можно по свойству "Код партнёра" (которое и является "id партнёра")в элементе инфоблока Треккер (Контент-Сервисы-Треккер).
Единственный момент, было бы здорово сделать так, чтобы это свойство не попадало в отображение на сайте. Я в выгрузку добавил к каждому свойству описание (тег: "description" - нужно сделать в local/modules/enter.tracker/lib/controller/send.php - обработку этого тэга). Это не касается свойства "Статус", у него выгружается своё описание. В описание могут выгружать 4 предустановленных варианта: Нет, Клиенты, Партнеры, Все - в зависимости от того, что в поле описание, мы будем разрешать показ данных всем или ограничивать показ этих данных для клиентов, партнёров или вообще всех в формах проверки.
Свойства "Код партнёра" и "Пароль партнёра" будем использовать для авторизация партнёров на вкладке "Партнёр".
Таблица Текущие ремонты: Состоит из списка ремонтов, отобранных по свойству "Код партнёра" и отсортированных по датам создания (самая ранняя сверху). В строке ремонта выводятся данные: "Заказ партнёра", "Адрес партнёра", "Название", "Вид оборудования", "Модель, s/n", "IMEI" (если есть), последний "Статус", Кнопка "Подробней". По нажатию на кнопку открывается окно с данными по конкретному заказу, такое же как и сейчас работает на сайте.
Вкладка "Архив" выглядит так же как и вкладка "Текущие ремонты", но в неё ремонты попадают только тогда, когда у них установлен последний статус "Заказ закрыт (Выдан)" (сейчас обдумываю, как передать эту информацию на сайт...на крайний случай привяжемся к конкретному названию состояния "Заказ закрыт (Выдан)" - но это не самое гибкое решение). Естественно, что ремонты попадая во вкладку архив исчезают со вкладки "Текущие ремонты".
Еще было бы круто сделать фильтр на обоих вкладках для партнера по свойствам: "Заказ партнёра" - строка, в которую вводится значение, при совпадении появляется результат, совпадение сверяются с тем что вводишь; "Адрес партнёра" - выбор списком из всех адресов, которые присутствуют в свойстве: "Адрес партнёра" [/SPOILER]
Функция создает оверлей (затемнение фона) и на нем отображает анимацию прелоадера. Вызывает функция (обычно во время загрузки данных) с параметрами:
let paramsShow = {
node: BX(document.querySelector('body')), //node внутри которой нужно отобразить прелоадер
loader: null, //если прелоадер уже существует, то отправляем его в этот параметр
size: 150, //размер прелоадера (px)
opacity: .7, прозрачность затемнения (от 0 до 1)
color: '#fff', цвет затемнения
}
let loader = showLoader(paramsShow);
После того, как выши данные загрузились скрываем прелоадер. Функция скрытия:
function hideLoader (params) {
if (params.loader !== null) {
params.loader.hide();
}
if (params.loader.currentTarget) {
BX.remove(params.loader.currentTarget);
}
if (params.loader !== null) {
params.loader = null;
}
}
и вызывается:
let paramsHide = {
loader: loader, // лоадер который мы получили при отображении
}
hideLoader(paramsHide);