Отдельная страница кастомных настроек Битрикс
Последние записи
Публикую один из вариантов решения по созданию отдельных страниц в Битрикс для хранения тех или иных настроек.
Мне для работы обычно требуется такой список поддерживаемых типов полей: Text, Checkbox, Textarea, Datetime range, Time range, Select
, Вы можете дописать свои и реализовать свой вывод по аналогии.
Time range реализовал на базе Ion.RangeSlider
. Для моих задач такого решения достаточно
Выглядит страница примерно так:
Основной файл settings.php
выглядит так:
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php');
use \Bitrix\Main\Config\Option;
$APPLICATION->SetAdditionalCSS('/local/admin/css/ion.rangeSlider.css');
$APPLICATION->SetAdditionalCSS('/local/admin/css/ion.rangeSlider.skinFlat.css');
$APPLICATION->SetAdditionalCSS('/local/admin/css/settings.css');
$APPLICATION->AddHeadScript('https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js');
$APPLICATION->AddHeadScript('/local/admin/js/ion.rangeSlider.js');
$APPLICATION->AddHeadScript('/local/admin/js/settings.js');
$tabs[] = ['DIV' => 'customSettings', 'TAB' => 'Страница настроек', 'TITLE' => 'Страница настроек'];
$tabControl = new \CAdminTabControl('customSettingsTabControl', $tabs, true, true);
$request = \Bitrix\Main\Context::getCurrent()->getRequest();
if (check_bitrix_sessid() && $request->isPost() && strlen($request['save'])) {
$options = $request['options'];
if ($options) {
foreach ($options as $key => $option) {
if ($option) {
Option::set('customSettings', $key, serialize($option));
} else {
Option::set('customSettings', $key);
}
}
unset($key, $option, $options);
} else {
Option::delete('customSettings');
}
}
$APPLICATION->SetTitle('Страница настроек');
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_after.php');
$settings = [
[
'NAME' => 'Автоответчик Вконтакте',
'CLASS' => 'vk--auto',
'ITEMS' => [
[
'TYPE' => 'checkbox',
'CODE' => 'vk--auto-messenger',
'NAME' => 'Включить автоответчик',
'HINT' => 'Включает функцию отправки сообщений пользователям ВК в выходные дни'
],
[
'TYPE' => 'checkbox',
'CODE' => 'vk--days-pn',
'NAME' => 'Пн',
'HINT' => 'Включите, чтобы автоответчик срабатывал в понедельник',
],
[
'TYPE' => 'timerange',
'CODE' => 'vk--time-send-week',
'NAME' => 'Время отправки в будние дни',
'HINT' => 'Правило будет действовать с Пн-00:00 по Пт-24:00'
],
[
'TYPE' => 'timerange',
'CODE' => 'vk--time-send-weekend',
'NAME' => 'Время отправки в выходные дни',
'HINT' => 'Правило будет действовать с Сб-00:00 по Вс-24:00'
],
[
'TYPE' => 'datetime',
'CODE' => 'vk--datetime',
'NAME' => 'Datetime',
'HINT' => ''
],
[
'TYPE' => 'text',
'CODE' => 'vk--text',
'NAME' => 'Text',
'HINT' => ''
],
[
'TYPE' => 'select',
'CODE' => 'vk--wait',
'NAME' => 'Сколько минут не реагировать на сообщение',
'VALUES' => [
[
'NAME' => '5 минут',
'VALUE' => '5 минут',
],
[
'NAME' => '5 часов',
'VALUE' => '5 часов',
],
[
'NAME' => '24 часа',
'VALUE' => '24 часа',
],
[
'NAME' => 'до прихода сотрудников',
'VALUE' => 'до прихода сотрудников',
],
],
'MULTIPLE' => 'N',
'HINT' => ''
],
[
'TYPE' => 'textarea',
'CODE' => 'vk--message',
'NAME' => 'Шаблон сообщения',
'HINT' => 'Пользователю будет отправлено это сообщение'
],
]
],
];
?>
<script>
var times = ['15:00', '15:05', '15:10', '15:15', '15:20', '15:25', '15:30', '15:35', '15:40', '15:45', '15:50', '15:55', '16:00', '16:05', '16:10', '16:15', '16:20', '16:25', '16:30', '16:35', '16:40', '16:45', '16:50', '16:55', '17:00', '17:05', '17:10', '17:15', '17:20', '17:25', '17:30', '17:35', '17:40', '17:45', '17:50', '17:55', '18:00', '18:05', '18:10', '18:15', '18:20', '18:25', '18:30', '18:35', '18:40', '18:45', '18:50', '18:55', '19:00', '19:05', '19:10', '19:15', '19:20', '19:25', '19:30', '19:35', '19:40', '19:45', '19:50', '19:55', '20:00', '20:05', '20:10', '20:15', '20:20', '20:25', '20:30', '20:35', '20:40', '20:45', '20:50', '20:55', '21:00', '21:05', '21:10', '21:15', '21:20', '21:25', '21:30', '21:35', '21:40', '21:45', '21:50', '21:55', '22:00', '22:05', '22:10', '22:15', '22:20', '22:25', '22:30', '22:35', '22:40', '22:45', '22:50', '22:55', '23:00', '23:05', '23:10', '23:15', '23:20', '23:25', '23:30', '23:35', '23:40', '23:45', '23:50', '23:55', '00:00', '00:05', '00:10', '00:15', '00:20', '00:25', '00:30', '00:35', '00:40', '00:45', '00:50', '00:55', '01:00', '01:05', '01:10', '01:15', '01:20', '01:25', '01:30', '01:35', '01:40', '01:45', '01:50', '01:55', '02:00', '02:05', '02:10', '02:15', '02:20', '02:25', '02:30', '02:35', '02:40', '02:45', '02:50', '02:55', '03:00', '03:05', '03:10', '03:15', '03:20', '03:25', '03:30', '03:35', '03:40', '03:45', '03:50', '03:55', '04:00', '04:05', '04:10', '04:15', '04:20', '04:25', '04:30', '04:35', '04:40', '04:45', '04:50', '04:55', '05:00', '05:05', '05:10', '05:15', '05:20', '05:25', '05:30', '05:35', '05:40', '05:45', '05:50', '05:55', '06:00', '06:05', '06:10', '06:15', '06:20', '06:25', '06:30', '06:35', '06:40', '06:45', '06:50', '06:55', '07:00', '07:05', '07:10', '07:15', '07:20', '07:25', '07:30', '07:35', '07:40', '07:45', '07:50', '07:55', '08:00', '08:05', '08:10', '08:15', '08:20', '08:25', '08:30', '08:35', '08:40', '08:45', '08:50', '08:55', '09:00', '09:05', '09:10', '09:15', '09:20', '09:25', '09:30', '09:35', '09:40', '09:45', '09:50', '09:55', '10:00', '10:05', '10:10', '10:15', '10:20', '10:25', '10:30', '10:35', '10:40', '10:45', '10:50', '10:55', '11:00', '11:05', '11:10', '11:15', '11:20', '11:25', '11:30', '11:35', '11:40', '11:45', '11:50', '11:55', '12:00', '12:05', '12:10', '12:15', '12:20', '12:25', '12:30', '12:35', '12:40', '12:45', '12:50', '12:55', '13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55', '14:00', '14:05', '14:10', '14:15', '14:20', '14:25', '14:30', '14:35', '14:40', '14:45', '14:50', '14:55'];
</script>
<form name='settings_form' method='POST' action='<?= POST_FORM_ACTION_URI; ?>'>
<?php
$tabControl->Begin();
$tabControl->BeginNextTab();
foreach ($settings as $sGroup) {
$opened = $_COOKIE[$sGroup['CLASS']];
?>
<tr class="heading opt--section <?=$sGroup['CLASS']; ?>">
<td colspan="2">
<div class="opt--title">
<?=$sGroup['NAME']; ?>:<span data-name="<?=$sGroup['CLASS']; ?>"><?if($opened == 1){?>Скрыть<?}else{?>Показать<?}?></span>
</div>
</td>
</tr>
<tbody class="for-<?=$sGroup['CLASS']; ?> body--section<?if($opened == 1){?> opened<?}?>">
<?php
foreach ($sGroup['ITEMS'] as $option) {
?>
<tr class="row">
<td class="adm-detail-content-cell-l" style="width:50%;">
<?php
if ($option['HINT']) {
ShowJSHint($option['HINT']);
}
?>
<label for="field_<?=$option['CODE']; ?>">
<?=$option['NAME']; ?>:
</label>
</td>
<?php
$value = unserialize(Option::get('customSettings', $option['CODE']));
if ($option['TYPE'] === 'checkbox') {
?>
<td class="adm-detail-content-cell-r">
<input type="hidden" name="options[<?=$option['CODE']; ?>]" value="0">
<input id="field_<?=$option['CODE']; ?>" type="<?=$option['TYPE']; ?>" name="options[<?=$option['CODE']; ?>]" <?= ((int)$value === 1) ? 'checked' : ''; ?> value="1">
</td>
<?php
}
if ($option['TYPE'] === 'text') {
?>
<td class="adm-detail-content-cell-r">
<input id="field_<?=$option['CODE']; ?>" type="<?=$option['TYPE']; ?>" name="options[<?=$option['CODE']; ?>]" size="30" value="<?= (mb_strlen($value) > 0) ? $value : ''; ?>">
</td>
<?php
}
if ($option['TYPE'] === 'textarea') {
?>
<td class="adm-detail-content-cell-r">
<textarea id="field_<?=$option['CODE']; ?>" name="options[<?=$option['CODE']; ?>]" cols="75" rows="10"><?=$value; ?></textarea>
</td>
<?php
}
if ($option['TYPE'] === 'select') {
?>
<td class="adm-detail-content-cell-r">
<select name="options[<?=$option['CODE']; ?>][]"
<?php if ($option['MULTIPLE'] === 'Y') {
echo ' multiple';
if (count($option['VALUES']) > 10) {
echo ' size="10"';
}
} ?>>
<?php
foreach ($option['VALUES'] as $item) {
?>
<option value="<?= $item['VALUE'] ?>" <?php if (in_array($item['VALUE'], $value)) { echo ' selected'; } ?>>
<?php
if ($item['DEPTH_LEVEL']) {
echo str_repeat(' . ', $item['DEPTH_LEVEL']);
}
echo $item['NAME'];
?>
</option>
<?php
}
unset($item);
?>
</select>
</td>
<?php
}
if ($option['TYPE'] === 'datetime') {
?>
<td class="adm-detail-content-cell-r">
<?//Date Range?>
<?
$from = $value['from'] ? $value['from'] : date("d.m.Y H:i:s");
$to = $value['to'] ? $value['to'] : date("d.m.Y H:i:s");
?>
<?=CalendarPeriod("options[".$option['CODE']."][from]", $from, "options[".$option['CODE']."][to]", $to, "form1", "Y")?>
<?/* //Single Calendar?>
<input type="text" class="typeinput" name="TIME" size="12">
<?=Calendar("TIME", "curform")?>
<?*/?>
<?//Single Calendar?>
<?//=CalendarDate("birthdate", "25.11.1975", "form1", "15", "class=\"my_input\"")?>
</td>
<?php
}
if ($option['TYPE'] === 'timerange') {
?>
<td class="adm-detail-content-cell-r">
<input id="<?=$option['CODE']; ?>" type="text" />
<input type="text" name="options[<?=$option['CODE']; ?>]" class="<?=$option['CODE']; ?>" value='<?=json_encode(json_decode($value))?>' style="display: none" />
<?
$value = json_decode($value);
$from = $value[1] ? $value[1] : 0;
$to = $value[3] ? $value[3] : 288;
?>
<script>
(function($) {
$(document).ready(function() {
$("#<?=$option['CODE']; ?>").ionRangeSlider({
type: 'double',
prettify: false,
hasGrid: false,
gridMargin: 0,
hideMinMax: true,
values: times,
from: '<?=$from?>',
to: '<?=$to?>',
onFinish: function (data) {
$(".<?=$option['CODE']; ?>").val(JSON.stringify([data.from_value, data.from.toString(), data.to_value, data.to.toString()]));
}
});
});
})(jQuery);
</script>
</td>
<?php
}
?>
</tr>
<?php
}
?></tbody><?
}
unset($option);
$tabControl->Buttons(['btnApply' => false]);
echo bitrix_sessid_post();
$tabControl->End();
?>
</form>
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php');
?>
Дополнительные файлы прикладывать смысла не вижу. Вы сможете скачать всю страницу вместе с дополнительными файлами. Распаковать нужно в /local/
. После распаковки путь к странице будет такой: /local/admin/settings.php
Получаем настройки следующим образом:
unserialize(\Bitrix\Main\Config\Option::get('customSettings', 'vk--auto-messenger'))
Значения опций сериализируются и при использовании emoji
в текстовых полях значение опции нарушается. За решение данной проблемы огромное спасибо BarryMode
, которые предложил данную функцию
Использовать если что так:
Option::set('customSettings', $key, serialize(emoji_entitizer($option)));
Комментарии