Коллеги, Добрый день! Пожалуйста подскажите как решить проблему. Задача: Создать комментарий к сделке с прикрепленным файлом. Использую вот такой код: URL_OCENKA = URL файла с диска для загрузки Помогите пожалуйста
При отправке запроса веб-сервису, возникла проблема с типами передаваемых параметров. Мне необходимо было передать дату. Сначала я подумал, что отправлю ее обычно как элемент массива, SoapClient "переварит" массив и все будет окей. Но веб-сервис вернул ошибку, код ошибки гласит: "параметр передан в структуру, но по типу не подходит ко входным параметрам".
Посмотрев внимательней на описание входных значений, стало понятно, что веб-сервис ждет параметр типа ДатаВремя, формат - DateTime::ATOM. Чтобы отправить через Soap параметр с указанием типа, необходимо использовать SoapVar.
class MyStructure
{
public $Params;
}
$date = new DateTime();
$param = new MyStructure();
$param->Params->Property->name = 'nameParams';
$param->Params->Property->Value = new SoapVar($date->format('c'), XSD_DATETIME, 'dateTime', 'http://www.w3.org/2001/XMLSchema', 'Value');
good afternoon people. I'm starting my company and I'm trying to use the Bitrix Site Manager sales systems development tool and I have some doubts and based on the information in the documentation it's not helping much. Anyone available to help me who speaks English or Portuguese?
Добрый день. Настроил NTLM авторизацию , сделал всё по инструкции. Если в админке включаю (Включить переадресацию NTLM авторизации) перебрасывает на 8891 порт и после ввода логина и пароля - Не удается получить доступ к сайту. Через пару секунд запрашивает логин и пароль опять , и так до бесконечности. В логах записей нет. Что это может быть?
Здравствуйте, в последнее время на моем сайте стали регистрироваться по 10 в день и больше какие-то пользователи с абракадабрами вместо нормальных логинов ,StevenmekVD, AngelodafUI и т.п. Пытались удалять из регистрации на сайте, они снова присылают. Что посоветуете? Похоже на спам,но какой-то необычный.
Добрый день! Нужно обновлять остатки товаров по связке Артикул (свойство товара) и Производитель (свойство товара).csv прикрепляю. При обновлении есть только поля артикул, производитель, остаток. Подскажите, пожалуйста, как это можно сделать? Если это невозможно сделать, обоснуйте почему, пожалуйста.
Проконсультируйте меня, пожалуйста. Вопрос такой: На сайте (в настройках главного модуля) подключено объединение стилей в один общий файл. Это дает приличный прирост скорости загрузки. Но проблема вот в чем: периодически(при жесткой очистке кеша) этот объединенный файл стилей становится недоступен и страница предстает без стилизации (Прилагаю скриншот).
Над этой задачей я бьюсь 2-й месяц, и не могу понять, почему подобное происходит. Подскажите, пожалуйста.
В битриксе можно создавать свои модули. Начальник хочет, чтобы этот модуль можно было запустить из конкретной задачи. К примеру, вошел в задачу, нажал меню и там был вызов нужного модуля. По кнопке "ЕЩЁ" И чтобы в модуль передавался номер задачи. Не могу найти образец как это сделать. Сейчас меню модуля появляется в "Администрирование" -> "Контент" в боковом меню.
Уже как только ни пытался, гуглил, лазил по этому форуму. Никак не получается прицепить купон к заказу. Везде примерно один и тот же код предлагают, но оно не работает - купон не появляется на странице заказа в админке.
Пользователи начали жаловаться что зависает приложение битрикс, помогает только завершение процесса и перезапуск. Диагностика проблемы показала что зависание происходит при обращении к поиску, а конкретно при выполнении вот этого запроса:
Проверил через последний хром, открыв desktop_app, он тоже зависает, конечно не весь как приложение битрикс, а только вкладка, которую он заботливо предлагает закрыть. Значит проблема не в приложении.
А оказалась проблема в функции быстрого поиска чатов. Эта функция загружает с сервера ВСЕ чаты, контакты, сотрудников и телефоны, доступные пользователю. А после она видимо формирует из них html контейнеры чтобы оперативно выводить при поиске.
Но дело в том, что при разработке не учитывалось масштабирование системы, и то что пользователей и чатов может быть очень много. Так например произошло в моем случае, и формирование ответа сервера мало того что занимало >9 секунд, так ещё и ответ весил 2,6 Мб, это всё был json с сотрудниками и чатами открытых линий и CRM:
Решение Сначала попытался отключить параметр "Включить предварительную загрузку всех пользователей портала для быстрого поиска" в настройках модуля Веб-мессенджер. Но это не помогло, так как отключился только запрос сотрудников, а чаты так и продолжили загружаться, плюс проявился ещё один баг, после отключения этой функции, но о нем ниже.
Пришлось опять лезть в ядро что бы поправить ошибку, оказалось что данные для ответа собирает метод \CIMContactList::GetList() Находится он в этом файле /home/bitrix/www/bitrix/modules/im/classes/general/im_contact_list.php:22 И оказывается он принимает параметр LOAD_CHATS который отвечает за загрузку всех доступных пользователю чатов, но видимо забыли вывести этот параметр в настройки модуля.
Предлагаю костылить следующе, в файле обработчике ajax запросов из веб-мессенджера /home/bitrix/www/bitrix/components/bitrix/im.messenger/im.ajax.php в строке 1165 добавляем передачу параметра LOAD_CHATS в метод \CIMContactList::GetList():
Добавляем так же что бы параметр брался из настроек, как и с сотрудниками, что бы можно было отключить. Соблюдаем странный перегон логической переменной в Y/N, что метод нас понял.
На этом всё, ждем исправлений от разработчиков, а пока они их не сделают придётся костылить это после каждого обновления модуля.
Дополнительный баг
А теперь баг о котором написал выше. Если отключить загрузку сотрудников в настройках модуля, то тогда перестаёт работать поиск при делегировании чатов открытых линий, так как он производит поиск только по локально сохранённым сотрудникам.
При этом при добавлении сотрудника в чат, поиск производится так же через запрос на сервер, но при делегировании только локально, забыли наверное. Я лезть в js не стал, включил загрузку сотрудников, без загрузки всех чатов зависания нет, так как чатов грузилось аж 45998. При этом, без чатов, запрос выполняется всё равно долго >7 секунд, но там есть кэширование, которое более менее выручает. В общем ждём исправлений.
Добавление меток (точек) на изображениях элементов инфоблока
Метки на изображениях элементов инфоблока - это бесплатный модуль, который расширяет базовый инструмент административной панели и позволяет управлять метками на изображениях непосредственно на страницах редактирования элементов. Модуль позволяет получить в результирующий массив arResult все координаты точек для дальнейшего позиционирования в шаблоне.
Возможности:
Создание меток для детального изображения
Создание меток пользовательского свойства типа файл
Создание меток для пользовательского свойства типа файл (множественное)
Получение меток в шаблоне компонента.
Метки не привязаны к шаблону, что позволит Вам выполнить любой дизайн отображения меток.
Примечание: модуль не выведет точки автоматически в шаблон, в связи с тем, что это просто невозможно (у всех шаблон разный). Он лишь позволяет получить их в результирующем массиве arResult Достаточно небольших познаний в области верстки и Вы сможете реализовать любой подходящий для Вашего проекта дизайн отображения меток на изображениях.
autoloader собственных классов и подключение событий работая одновременно с несколькими крупными проектами, в которых используется кастомизация бизнес-процессов, может возникнуть вопрос реализации удобной структуры собственных классов и событий в php_interface. У меня такой вопрос возник, и вот что получилось:
init.php создал в папке /bitrix/php_interface. Это сделано, чтобы учесть проекты с многосайтовостью и сохранить новую структуру как для папки /local, так и для /bitrix.
в данном решение обрабатываются 4 основных, но не обязательных файла: functions.php - записываем функции, которые будут везде использоваться, например для debug adminHandlers.php - добавляются события, которые будут отработаны в административной части сайта publicHandlers.php - добавляются события, которые будут отработаны только на публичной части сайта handlers.php - добавляются события, которые будут отрабатываться всегда
в данном примере подключается метод addJsLibrary из класса Custom\PublicSection\Jsinit. Класс подгружается по принципу autoloader'а. Т.е. в папке php_interface/classes/public создан файл jsinit.php:
<?php
namespace Custom\PublicSection;
class Jsinit
{
public function addJsLibrary()
{
$arJsConfig = array(
'owl_carousel' => array(
'js' => '/local/js/owl_carousel/owl.carousel.js',
'css' => '/local/js/owl_carousel/assets/owl.carousel.css',
'rel' => array('jquery'),
),
);
foreach ($arJsConfig as $ext => $arExt) {
\CJSCore::RegisterExt($ext, $arExt);
}
}
}
По такой же схеме можно создать любой файл с собственным классом, например: /local/php_interface/classes/handlers/test.php с namespace Custom\Handlers, где класс будет Test. Далее методы класса можно использовать как в событиях, добавляя их в handlers.php, так и в любом необходимом месте, например, собственном компоненте.
В итогемы получаем отдельные файлы классов, которые подключаются автоматически, и файлы со списками методов подключаемых в события. При этом используем встроенный функционал Bitrix'а.
Добрый день,такой вопрос,у меня есть универсальный список и он заполняется параметрами,по средствам бизнес-процесса, соответственно в нём не срабатывает бизнес-процесс на создание элементов,необходимо через код запускать бизнес-процесса на все новые элементы в этом списке,как это реализуемо,возможно уже есть готовые статьи? Я поискал в интернете примеры,но ничего достойного не нашёл,коробка если что.
Кроссавторизация на поддоменах на одном ядре В продолжение статьи "Авторизация при поддоменности на разных установках" ()написал пример своего решения проблемы с кроссавторизацией на поддоменах на одном ядре:
Установил 28.07.2021 обновление, в том числе обновился и модуль календаря, сотрудники начали ругаться на неудобство, почему при планировании встречи убрали отображение отсутствий у участников встречи.
Сначала подумал что это новая фича, а потом решил проверить ))) Оказалось баг. В файле: /home/bitrix/www/bitrix/modules/calendar/classes/general/calendar_planner.php в строке 161, 162, 167 и 172 перепутаны имена ключей массива, и вместо DT_TO и DT_FROM, которые приходят из метода CCalendar::GetAccessibilityForUsers вписаны DATE_TO и DATE_FROM.
Решение
Нужно исправить имена ключей, или просто вставить в 160 строку перенос значений в нужные ключи:
Зачастую нужно реализовать следующий сценарий: - Контент-менеджер загружает файлы (картинки товара или раздела каталога) как есть. С кириллическим названием или пробелами. Как результат при валидации кода (если придет дотошный сеошник) могут вылезти куча ошибок связанных с разрывами в имени файла. Ниже публикую 2 скрипта, которые позволяют поправить эту ошибку перезаписав имена на корректные с точки зрения seo. !!! ВАЖНО !!! Перед выполнением скрипта в настройках главного модуля должны быть следующие настройки (см. скриншот). И не забывайте указать свой ID инфоблока.
1. Для разделов
$start = microtime(true);
// включение модуля
\Bitrix\Main\Loader::includeModule('iblock');
$arOrder = array('ID' => 'ASC');
$arFilter = array('IBLOCK_ID' => 60); // указать id инфоблока
$arSelect = array('ID', 'NAME', 'PICTURE');
$countSection = 0;
$countPicture = 0;
// достаем список разделов
$res = CIBlockSection::GetList($arOrder, $arFilter, false, $arSelect, false);
// цикл перебора разделов
while($arSection = $res->Fetch()){
$countSection += 1;
// получаем id файла в системе
$fileID = $arSection['PICTURE'];
// если id файла не получен, значит раздел без картинки
if(isset($fileID)){
$countPicture += 1;
// получим картинку как объект по id
$fileInfo = CFile::GetByID($fileID);
if($fileArr = $fileInfo->Fetch()){
// указываем расположение для временного хранения в склейке с именем файла
// !!! путь к папке задается от корня /upload/
$newFilePath = 'user_files/'.$fileArr['FILE_NAME'];
// копируем файл во временную папку
$fileCopy = CFile::CopyFile($fileID, true, $newFilePath);
}
// получаем информацию в массиве
$arrTmp = CFile::MakeFileArray($fileCopy);
// начинаем обновлять картинку
$bs = new CIBlockSection;
// определим данные для корректной записи массива 'PICTURE'
$picture = array(
'name' => $arrTmp['name'],
'type' => $arrTmp['type'],
'tmp_name' => $arrTmp['tmp_name'],
'error' => 0,
'size' => $arrTmp['size'],
'MODULE_ID' => 'iblock',
);
$arFields = array(
'PICTURE' => $picture,
);
// обновляем раздел
$bs->Update($arSection['ID'], $arFields, false, false, true);
unset($fileID);
}
}
$time = microtime(true) - $start;
echo 'Всего найдено ' . $countSection . ' разделов <br>';
echo 'Обновлено ' . $countPicture . ' картинок <br>';
echo 'Время выполнения ' . $time . ' секунд';
2. Для элементов
$start = microtime(true);
// включение модуля
\Bitrix\Main\Loader::includeModule('iblock');
$arOrder = array('ID' => 'ASC');
$arFilter = array('IBLOCK_ID' => 55); // указать id инфоблока
$arSelect = array('ID', 'NAME', 'PREVIEW_PICTURE', 'DETAIL_PICTURE');
$countElement = 0;
$countPicture = 0;
// достаем список элементов
$ar_res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelect);
// цикл перебора элементов
while($arElement = $ar_res->Fetch()){
$countElement += 1;
$res = CIBlockElement::GetByID($arElement['ID']);
if($arElement = $res->GetNext()){
/*КАРТИНКА АНОНСА*/
if(isset($arElement['PREVIEW_PICTURE'])){
$countPicture += 1;
// получим картинку как объект по id
$fileInfo = CFile::GetByID($arElement['PREVIEW_PICTURE']);
if($fileArr = $fileInfo->Fetch()){
// указываем расположение для временного хранения в склейке с именем файла
// !!! путь к папке задается от корня /upload/
$newFilePath = 'user_files/'.$fileArr['FILE_NAME'];
// копируем файл во временную папку
$fileCopy = CFile::CopyFile($arElement['PREVIEW_PICTURE'], true, $newFilePath);
}
// получаем информацию в массиве
$arrTmp = CFile::MakeFileArray($fileCopy);
// обновляем элемент
$el = new CIBlockElement;
// определим данные для корректной записи массива 'PICTURE'
$picture = array(
'name' => $arrTmp['name'],
'type' => $arrTmp['type'],
'tmp_name' => $arrTmp['tmp_name'],
'error' => 0,
'size' => $arrTmp['size'],
'MODULE_ID' => 'iblock',
);
$arFields = array(
'PREVIEW_PICTURE' => $picture,
);
$res = $el->Update($arElement['ID'], $arFields);
}
/*КАРТИНКА ДЕТАЛЬНАЯ*/
if(isset($arElement['DETAIL_PICTURE'])){
$countPicture += 1;
// получим картинку как объект по id
$fileInfo = CFile::GetByID($arElement['DETAIL_PICTURE']);
if($fileArr = $fileInfo->Fetch()){
// указываем расположение для временного хранения в склейке с именем файла
// !!! путь к папке задается от корня /upload/
$newFilePath = 'user_files/'.$fileArr['FILE_NAME'];
// копируем файл во временную папку
$fileCopy = CFile::CopyFile($arElement['DETAIL_PICTURE'], true, $newFilePath);
}
// получаем информацию в массиве
$arrTmp = CFile::MakeFileArray($fileCopy);
// обновляем элемент
$el = new CIBlockElement;
// определим данные для корректной записи массива 'PICTURE'
$picture = array(
'name' => $arrTmp['name'],
'type' => $arrTmp['type'],
'tmp_name' => $arrTmp['tmp_name'],
'error' => 0,
'size' => $arrTmp['size'],
'MODULE_ID' => 'iblock',
);
$arFields = array(
'DETAIL_PICTURE' => $picture,
);
$res = $el->Update($arElement['ID'], $arFields);
}
}
}
$time = microtime(true) - $start;
echo 'Всего найдено ' . $countElement . ' элементов <br>';
echo 'Обновлено ' . $countPicture . ' картинок <br>';
echo 'Время выполнения ' . $time . ' секунд';
Писалось на скорую руку, так что как есть)) Оставлю это тут на всякий случай.
Когда-то давно я наткнулся на статью "" который помогал формировать страницы опций. С тех пор он прочно осел в проектах, значительно упрощая работу. В том числе файл встречался различных коммерческих модулях что показало актуальность его существования.
К сожалению, оригинальная статья датирована 2012 годом и код несколько устарел. Стали видны слабые момент в виду сложности добавления новых типов полей в классе, да и в плане внешнего вида UI Bitrix продвинулся вперёд.
С учетом этих проблем сделана более улучшенная версия, позволяющая легко добавлять новые типы полей, и испольщую . Создан и, если кому-то зачем-то нужно - был опубликован . Проблема добавления новых типов полей закрыта, внешний вид значительно улчшился (по моему мнению).
Как это выглядит в админке:
Уже реализованы поля типов: строка, число, текст, чекбокс, выпадающий и множественный списки. Можно вешать различные модификаторы на поля, добавлять теги. В будущем планирую добавить добавление файлов, размещение кнопок на которые можно вешать свои скрипты.
Не буду описывать особенности установки и настройки - они детально описаны как на гитхабе, так и в маркетплейсе. Буду рад, если решение будет полезно, проект открыт для доработок как по самому коду, так и по добавлению новых типов полей.
Отдельное спасибо Андрею Новикову, за класс, служивший до этого долгие годы.
В коде происходит выборка 30 элементов, первыми из которых пойдут элементы у которых есть совпадения тегов "Personal" и "2020", далее хотя бы одного из этих двух Тегов, и в конце статьи, не имеющие совпадений.
По желанию можно добавить условие фильтра для выборки только тех элементов, которые содержат хоть один Тег. Например, условие по одному Тегу будет выглядеть так:
array(
"LOGIC" => "OR",
array(
'%TAGS' => " ".$sTagName."," // строка целиком в середине
),
array(
'TAGS' => $sTagName.",%" // строка целиком в начале
),
array(
'TAGS' => "% ".$sTagName // строка целиком в конце
),
array(
'TAGS' => $sTagName // единственная строка в тегах
)
)
Пример запроса SQL:
select ((case when LOCATE('Personal', TAGS)>0 then 1 else 0 end) + (case when LOCATE('2020', TAGS)>0 then 1 else 0 end)) as SORT,
TAGS, ID fr om b_iblock_element WHERE IBLOCK_ID=18 ORDER BY SORT DESC LIMIT 0, 30;
Представим, что нам надо отправлять сообщения в Битрикс24 на события из bitbucket, например Тимлиду ссылку на пулреквест для кодревью.
Bitbucket webhook Вебхуки bitbucket имеют события на пулреквесты, пуши и ишью. Полный перечень . Добавляется вебхука в настройках репозитория:
Укажите путь, куда будет отправлен запрос и выберите какие события вы хотите обрабатывать:
Обработка событий и отправка сообщения в чат Следующий скрипт, принимает запрос от bitbucket и отправляет ссылку на пулреквест Тимлиду на портал. Отправленное сообщение состоит из названия и ссылки на пулреквест.
Вот так просто. Логику поиска получателей или отправителей вы уже должны реализовать самостоятельно, в зависимости от ваших процессов и замысла. В нашем примере, для упрощения, ID пользователей прописаны явно.
Для обработки вебхуков bitbucket используется . Библиотека понимает большинство событий и комплектует объекты данными ответа в виде методов для получения ника автора, ссылки на пулреквест, комментарии коммитов и так далее.
Стандартное автоопределение клавиатуры почти всегда справляется, но некоторые русские слова всё-таки перекидывает на английскую раскладку (например: "шкаф" превращается в "irfa", а "кувшин" в "rediby", очень неприятно, если это ищут). Ну и специфические потребности никто не отменял.
Как ни странно, но отвечающий за эту радость класс CSearchLanguage поддерживает какую-никакую кастомизацию. Копируем всё из папки /bitrix/modules/search/tools/ru/ в папку /bitrix/php_interface/ru/search/ (и аналогично с en версией). Папка local не поддерживается.
По этому пути ищется кастомный класс для этой петрушки и теперь он есть, но требует небольшой доработки. Добавляем в ru версию в файл language.php функцию
function PreGuessLanguage($text, $lang=false)
{
$stop_list = array(
//сюда вписываем любые слова, которым не требуется автоопреление. Ключи важны, значения - любые, но мне так удобнее
"шкаф" => "irfa",
"шкафы" => "irfas",
);
//Indicates that there is no own guess
if(isset($stop_list[$text]))
return true;
else
return false;
//In subclasses you should return array("from" => lang, "to" => lang) to translate
//or return true when no translation nedded
//or parent::GuessLanguage for futher processing
}
Теперь слово "шкаф" не заменяется на "irfa". Класс.
А в en версию аналогичный, но чуть другой:
function PreGuessLanguage($text, $lang=false)
{
$stop_list = array(
"irfa" => "шкаф",
"irfas" => "шкафы",
);
//Indicates that there is no own guess
if(isset($stop_list[$text]))
return array("from" => "en", "to" => "ru");
else
return false;
//In subclasses you should return array("from" => lang, "to" => lang) to translate
//or return true when no translation nedded
//or parent::GuessLanguage for futher processing
}
Теперь и "irfa" вполне себе меняется на "шкаф".
Собственно вот и всё. Можно вписывать любые другие слова и наслаждаться жизнью.
(А ещё можно вынести словарь в отдельный файл и подтягивать значения из него, но ради пары слов я бы таким не занимался.)