Отдельная страница кастомных настроек Битрикс
Rus
Eng
Отдельная страница кастомных настроек Битрикс
Решаю сложные технические задачи для Bitrix и 1С: от аудита чужого кода до разработки сайтов и настройки сложных интеграций с гарантией результата
Рекомендую

Хостинг для сайта

Если выбираете хостинг под проект — советую Timeweb. Современная инфраструктура, широкий выбор тарифов от стартовых до VPS под нагрузку, отзывчивая техподдержка, которая отвечает по существу, а не отписками. Я сам держу на нём часть своих проектов и рекомендую клиентам.

Перейти Партнёрская ссылка. Для вас цена не меняется.

Публикую один из вариантов решения по созданию отдельных страниц в Битрикс для хранения тех или иных настроек.

Мне для работы обычно требуется такой список поддерживаемых типов полей: 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)));
Александр Тихий
Автор статьи

Александр Тихий

Fullstack-разработчик · 1С-Битрикс

Разрабатываю и развиваю интернет-магазины и корпоративные порталы на 1С-Битрикс. Интеграции с 1С, highload-нагрузки, безопасность по 152-ФЗ.


Ответить
Отменить

Комментарии

Максим
Максим
|Ответить
Добрый день. Подскажите пожалуйста, а если мне необходимо вставить поле для изображения, как я могу это сделать ?
Александр
Александр
|Ответить
Достаточно просто: echo \Bitrix\Main\UI\FileInput::createInstance(array( "name" => 'options['.$option['CODE'].']', "description" => false, "upload" => true, "allowUpload" => "A", "medialib" => true, "fileDialog" => true, "cloud" => true, "delete" => true, "maxCount" => 1 ))->show($value);

Оставьте комментарий

На сайте используется система премодерирования комментариев, поэтому ваше сообщение будет опубликовано лишь после одобрения модератором

Вы отвечаете на комментарий пользователя

Отправить

ОБРАТНАЯ СВЯЗЬ

Напишите мне

Напишите мне, чтобы обсудить задачу. Работаю удаленно, официально (самозанятый), стоимость часа — 1800 ₽, в день могу уделять проекту 3–4 часа. Отвечаю быстро, консультация бесплатная.

Во время отправки произошла ошибка, пожалуйста попробуйте еще раз через некоторое время
Сообщение отправлено успешно

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

Россия, г. Москва

Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта