Отдельная страница кастомных настроек Битрикс
Rus
Eng
Отдельная страница кастомных настроек Битрикс

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

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

Комментарии

Максим
Максим
|Ответить
Добрый день. Подскажите пожалуйста, а если мне необходимо вставить поле для изображения, как я могу это сделать ?
Александр
Александр
|Ответить
Достаточно просто: 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);

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

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

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

Отправить

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

Напишите мне

Вы разрабатываете новый сервис, вносите доработки в существующий и хотите лучше чем у конкурентов? Вы обратились по адресу. Предлагаю вам комплексную разработку сайтов студийного уровня. У меня вы можете заказать дизайн, верстку, програмированние, разработку нетрадиционного функционала, реализацию связи между CMS, CRM и Data Analitics, а так же все остальное касаемое сайтов, кроме продвижения.

Обращайтесь, я всегда проконсультирую по всем вопросам и помогу подобрать наиболее эффективное решение для Вашего бизнеса. Я занимаюсь созданием сайтов в Новосибирске и в других регионах России, также работаю со странами СНГ. Вы останетесь довольны нашим сотрудничеством

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

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

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

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

Написать мне
Отправить
Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта
Отправка успешна!
Thank you for your feedback. I will answer you within the next working hours
Отправка не удалась
Во время отправки запроса произошла ошибка. Пожалуйста, подождите и попробуйте снова через некоторое время или свяжитесь со мной