Перейти к содержимому

Форма добавления элемента инфоблока - свойства, права, модерация

Посетитель заводит объявление, заявку или запись каталога прямо с сайта, не заходя в административную часть. Разбираем штатную форму добавления элемента: набор свойств, модерацию, права и письмо ответственному.

Решение

Форма на странице

Ставим штатную форму добавления:

$APPLICATION->IncludeComponent('bitrix:iblock.element.add.form', '', [
'IBLOCK_TYPE' => 'services',
'IBLOCK_ID' => 12,
'GROUPS' => ['2'], // каким группам показывать форму
'STATUS_NEW' => 'N', // новая запись заводится неактивной
'ELEMENT_ASSOC' => 'CREATED_BY', // чем запись привязана к автору
'USE_CAPTCHA' => 'Y',
'LIST_URL' => '/cabinet/ads/',
]);

Компонент сам рисует поля, сам проверяет обязательные и сам пишет элемент. Своего обработчика формы писать не нужно, но и номер созданной записи компонент наружу не отдаёт.

Какие свойства выводить

Перечисляем поля и свойства формы:

'PROPERTY_CODES' => [
'NAME', 'PREVIEW_TEXT', 'PREVIEW_PICTURE', 'IBLOCK_SECTION',
'PHONE', 'CITY', 'PRICE', // дальше идут коды свойств инфоблока
],
'PROPERTY_CODES_REQUIRED' => ['NAME', 'PHONE'],
'CUSTOM_TITLE_NAME' => 'Заголовок объявления',
'RESIZE_IMAGES' => 'Y', // уменьшение картинок по настройкам инфоблока

В одном списке лежат и поля самого элемента, и коды его свойств. Свойство, не попавшее в PROPERTY_CODES, форма не покажет, и посетитель никак его не заполнит.

Куда попадает запись

Собираем очередь на проверку:

$rows = CIBlockElement::GetList(
['DATE_CREATE' => 'DESC'],
['IBLOCK_ID' => 12, 'ACTIVE' => 'N'], // не прошедшие проверку
false, false,
['ID', 'NAME', 'CREATED_BY', 'DATE_CREATE']
);

Параметр STATUS_NEW со значением N снимает активность у каждой поступившей записи. Публикация сводится к включению активности, отказ - к удалению элемента, а посетитель до проверки видит только свою запись.

Кто добавляет и кто видит чужое

Проверяем право посетителя на запись:

\Bitrix\Main\Loader::includeModule('iblock');
// при расширенных правах передаётся код операции, а не буква уровня доступа
if (!CIBlockElementRights::UserHasRightTo(12, 0, 'section_element_bind')) {
ShowError('Добавление объявлений сейчас закрыто');
return;
}

Параметр GROUPS прячет форму от чужих групп, но правами не управляет. Право записи в инфоблок выдают отдельно, иначе форма нарисуется, а сохранение молча не пройдёт. Устаревший CIBlock::GetPermission при расширенных правах врёт.

Письмо модератору

Шлём письмо после сохранения:

/local/php_interface/init.php
AddEventHandler('iblock', 'OnAfterIBlockElementAdd', 'notifyModerator');
function notifyModerator(&$arFields) // массив приходит по ссылке
{
if ((int)$arFields['IBLOCK_ID'] !== 12 || empty($arFields['ID'])) {
return;
}
CEvent::Send('NEW_AD_ON_MODERATION', ['s1'], [
'ELEMENT_ID' => $arFields['ID'],
'NAME' => $arFields['NAME'],
]);
}

Метод CEvent::Send кладёт письмо в очередь b_event, а рассылает её пролог следующей страницы. Тип почтового события и шаблон письма заводят заранее в настройках модуля почты, иначе отправлять будет нечего.

Правка своей записи

Дописываем служебное свойство после сохранения:

// внутри того же обработчика OnAfterIBlockElementAdd
CIBlockElement::SetPropertyValuesEx($arFields['ID'], 12, [
'SOURCE' => 'site',
'MODERATOR' => 143, // списочное свойство пишется ID варианта, не текстом
]);

Метод трогает только переданные свойства и не обнуляет остальные. У полного набора есть SetPropertyValues, но без списка кодов он затирает пропущенные значения, поэтому дописывать одно свойство им нельзя.

Открываем форму на правку своего элемента:

// ссылка из личного списка: /cabinet/ads/?edit=Y&CODE=#ELEMENT_CODE#
'STATUS' => 'ANY', // какие свои записи разрешено править
'ELEMENT_ASSOC' => 'CREATED_BY', // свои - это созданные этим человеком
'MAX_USER_ENTRIES' => 5, // сколько записей заводит один автор

Без edit=Y в адресе компонент всегда рисует пустую форму добавления. Список своих записей со ссылками на правку даёт соседний компонент bitrix:iblock.element.add.list.

Типичные проблемы

Форма на странице есть, а элемент не создаётся.

Параметр GROUPS показал форму нужной группе, но право записи в инфоблок ей не выдано. Права смотрят классом CIBlockElementRights, а не по галочкам в параметрах компонента.

После сохранения не найти номер новой записи.

Компонент не возвращает ID созданного элемента ни в шаблон, ни в вызывающий код. Номер ловят обработчиком OnAfterIBlockElementAdd либо копией компонента в своём пространстве имён.

Капча включена, а картинки в форме нет.

Шаблон компонента переопределён, и блок капчи из него вырезан вместе с полем ввода. Проверка на стороне сервера при этом работает, поэтому форма молча отклоняет каждую отправку.

Множественное свойство-файл рисует сразу пять полей.

Число полей загрузки задаёт сам компонент, в настройках инфоблока такого параметра нет. Лишние поля убирают правкой копии шаблона в своём пространстве имён.

Картинка сохранилась в исходном размере.

Уменьшение из настроек инфоблока срабатывает при загрузке через административную часть. Публичная форма трогает картинку только при параметре RESIZE_IMAGES со значением Y.

Частые вопросы

Как получить ID созданного элемента инфоблока?

Компонент его не отдаёт. Номер ловят обработчиком OnAfterIBlockElementAdd: после сохранения в $arFields лежит ID новой записи. Второй путь - копия компонента в своём пространстве имён, где ID забирают прямо в component.php.

Как вызвать компонент в режиме редактирования?

Режим включают параметры адреса вида ?edit=Y&CODE=#ELEMENT_CODE#. Без них компонент всегда рисует пустую форму добавления. Какие записи разрешено править, задают параметры ELEMENT_ASSOC и STATUS.

Почему посетитель не видит свою же запись?

Элемент не привязан к автору. Привязку задаёт ELEMENT_ASSOC: значение CREATED_BY связывает запись с создавшим её пользователем. У гостя автора нет, поэтому его запись не попадёт ни в один личный список.

Чем это отличается от веб-формы?

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

Можно ли обойтись без модерации?

Можно: при STATUS_NEW со значением ANY запись публикуется сразу. На открытых для гостей формах так почти не делают, потому что первым эту возможность находит спам, а удалять его приходится вручную.

Смежное

Первоисточник