В дополнение к статье о создании собственного типа пользовательских полей хочу рассказать как делать аналогичные свойства для информационных блоков, т.к. эти свойства относятся к другому модулю, а именно «информационные блоки» (iblock). Из коробки инфоблоки битрикс предоставляют следующий набор типов свойств:

  • Строка
  • Число
  • Список
  • Файл
  • Привязка к элементам
  • Привязка к разделам
  • HTML\Текст
  • Видео
  • Дата
  • Дата\Время
  • Деньги
  • Привязка к Яндекс.Карте
  • Привязка к Google Maps
  • Привязка к пользователю
  • Привязка к разделам с автозаполнением
  • Привязка к теме форума
  • Привязка к товарам (SKU)
  • Привязка к файлу (на сервере)
  • Привязка к элементам в виде списка
  • Привязка к элементам по XML_ID
  • Привязка к элементам с автозаполнением
  • Справочник
  • Счётчик

Достаточно внушительный список, однако иногда заказчику нужны какие-то очень специфические решения, которые не удаётся реализовать в полном объёме. Тут битрикс предоставляет возможность расширить доступный перечень свойств.

Рассмотрим пример создания множественного свойства для реализации расписания врачей.

Подготовка и загрузка класса

Структура и способ загрузки класса будет аналогичным с первой статьёй. Так же используем папку /local/ и такую структуру:

Структура класса

Файл init.php


<?php

//Константы
require dirname(__FILE__) . '/constants.php';

//Автозагрузка классов
require dirname(__FILE__) . '/autoload.php';

//Обработка событий
require dirname(__FILE__) . '/event_handler.php';


/**
 * обёртка для print_r() и var_dump()
 * @param $val - значение
 * @param string $name - заголовок
 * @param bool $mode - использовать var_dump() или print_r()
 * @param bool $die - использовать die() после вывода
 */
function print_p($val, $name = 'Содержимое переменной', $mode = false, $die = false){
    global $USER;
    if($USER->IsAdmin()){
        echo '<pre>'.(!empty($name) ? $name.': ' : ''); if($mode) { var_dump($val); } else { print_r($val); } echo '</pre>';
        if($die) die;
    }
}

Тут дополнительная функция print_p() служит для удобства вывода содержимого переменных и отладки.

Файл constants.php


<?php

//Папка с пользовательскими классами
define('APP_CLASS_FOLDER', '/local/php_interface/lib/');

Тут храним константы с путями к ключевым папкам (пока одна).

Файл autoload.php


<?php

use Bitrix\Main\Loader;

//Автозагрузка наших классов
Loader::registerAutoLoadClasses(null, [
    'lib\usertype\CUserTypeTimesheet' => APP_CLASS_FOLDER . 'usertype/CUserTypeTimesheet.php',
]);

Тут подгружаем один единственный класс. У меня он будет реализован в файле CUserTypeTimesheet.php.

Стандартные классы модуля iblock

Подсмотреть реализацию близкого к вашей задаче свойства, можно подсмотреть в модуле «Информационные блоки». Для этого перейдём в папку /bitrix/modules/iblock/classes/general/, здесь вы найдёте перечень классов в отдельных файлов с префиксом prop_, например:

  • prop_date.php
  • prop_datetime.php
  • prop_html.php

Для реализации собственного класса, вам нужно реализовать в собственном классе как минимум 2 метода:

  • GetUserTypeDescription() — метод для описания свойства
  • GetPropertyFieldHtml() — метод для вывода html формы свойства

Если вы делаете составное свойство как в моём примере, вам так же потребуется 2 метода контролирующие запись и извлечение значения свойства из базы данных.

  • ConvertToDB() — обработка значения перед записью в БД
  • ConvertFromDB() — обработка значения после извлечения из БД, но до вывода в GetPropertyFieldHtml()

Создаём класс для реализации собственного свойства инфоблока

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


<?php

namespace lib\usertype;

use Bitrix\Main\Loader,
    Bitrix\Main\Localization\Loc,
    Bitrix\Iblock;

/**
 * Реализация свойство «Расписание врача»
 * Class CUserTypeTimesheet
 * @package lib\usertype
 */
class CUserTypeTimesheet
{
    /**
     * Метод возвращает массив описания собственного типа свойств
     * @return array
     */
    public function GetUserTypeDescription()
    {
        return array(
            'USER_TYPE_ID' => 'user_timesheet', //Уникальный идентификатор типа свойств
            'USER_TYPE' => 'TIMESHEET',
            'CLASS_NAME' => __CLASS__,
            'DESCRIPTION' => 'Расписание специалиста',
            'PROPERTY_TYPE' => Iblock\PropertyTable::TYPE_STRING,
            'ConvertToDB' => [__CLASS__, 'ConvertToDB'],
            'ConvertFromDB' => [__CLASS__, 'ConvertFromDB'],
            'GetPropertyFieldHtml' => [__CLASS__, 'GetPropertyFieldHtml'],
        );
    }

    /**
     * Конвертация данных перед сохранением в БД
     * @param $arProperty
     * @param $value
     * @return mixed
     */
    public static function ConvertToDB($arProperty, $value)
    {
        if ($value['VALUE']['TIME_FROM'] != '' && $value['VALUE']['TIME_TO']!='')
        {
            try {
                $value['VALUE'] = base64_encode(serialize($value['VALUE']));
            } catch(Bitrix\Main\ObjectException $exception) {
                echo $exception->getMessage();
            }
        } else {
            $value['VALUE'] = '';
        }

        return $value;
    }

    /**
     * Конвертируем данные при извлечении из БД
     * @param $arProperty
     * @param $value
     * @param string $format
     * @return mixed
     */
    public static function ConvertFromDB($arProperty, $value, $format = '')
    {
        if ($value['VALUE'] != '')
        {
            try {
                $value['VALUE'] = base64_decode($value['VALUE']);
            } catch(Bitrix\Main\ObjectException $exception) {
                echo $exception->getMessage();
            }
        }

        return $value;
    }

    /**
     * Представление формы редактирования значения
     * @param $arUserField
     * @param $arHtmlControl
     */
    public static function GetPropertyFieldHtml($arProperty, $value, $arHtmlControl)
    {
        $weekDays = [
            'mon' => 'Понедельник',
            'tue' => 'Вторник',
            'wed' => 'Среда',
            'thu' => 'Четверг',
            'fri' => 'Пятница',
            'sat' => 'Суббота',
            'sun' => 'Воскресенье',
        ];

        $itemId = 'row_' . substr(md5($arHtmlControl['VALUE']), 0, 10); //ID для js
        $fieldName =  htmlspecialcharsbx($arHtmlControl['VALUE']);
        //htmlspecialcharsback нужен для того, чтобы избавиться от многобайтовых символов из-за которых не работает unserialize()
        $arValue = unserialize(htmlspecialcharsback($value['VALUE']), [stdClass::class]);

        $select = '<select class="week_day" name="'. $fieldName .'[WEEK_DAY]">';
        foreach ($weekDays as $key => $day){
            if($arValue['WEEK_DAY'] == $key){
                $select .= '<option value="'. $key .'" selected="selected">'. $day .'</option>';
            } else {
                $select .= '<option value="'. $key .'">'. $day .'</option>';
            }

        }
        $select .= '</select>';

        $html = '<div class="property_row" id="'. $itemId .'">';

        $html .= '<div class="reception_time">';
        $html .= $select;
        $timeFrom = ($arValue['TIME_FROM']) ? $arValue['TIME_FROM'] : '';
        $timeTo = ($arValue['TIME_TO']) ? $arValue['TIME_TO'] : '';

        $html .='&nbsp;время приёма: с&nbsp;<input type="time" name="'. $fieldName .'[TIME_FROM]" value="'. $timeFrom . '">';
        $html .='&nbsp;по&nbsp;<input type="time" name="'. $fieldName .'[TIME_TO]" value="'. $timeTo .'">';
        if($timeFrom!='' && $timeTo!=''){
            $html .= '&nbsp;&nbsp;<input type="button" style="height: auto;" value="x" title="Удалить" onclick="document.getElementById(\''. $itemId .'\').parentNode.parentNode.remove()" />';
        }
        $html .= '</div>';

        $html .= '</div><br/>';

        return $html;
    }
}

Подключаемый класс реализует вот такое свойство:

Свойство «Расписание врачей»

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

Обратите внимание что  для хранения составных данных я использую сериализацию массива + функцию base64_encode(), это позволяет избежать ряд ошибок при хранении данных в БД.

Данное свойство позволит вам реализовать страницу со списком врачей или других специалистов компании с удобным редактированием времени приёма.



Вам также могут понравиться

Современные способы заработка на сайтах

Современные способы заработка на сайтах

Не для кого не секрет, что в современном мире вы можете зарабатывать определённые деньги на своём сайте ничего не продавая. Говоря «ничего не продавая», я имею ввиду классическую схему, когда вы продаёте свои услуги, перепродаёте товар (предварительно закупая или используя схемы прямой поставки «дроп-шиппинга») или что-то производите. В статье рассмотрим методы, которые не требуют от вас подобных действий. И так, рассмотрим основные методы в порядке возрастания их сложности и времени которое требуется от владельца сайта.

Пользовательский тип свойств инфоблока в 1С Битрикс

Пользовательский тип свойств инфоблока в 1С Битрикс

В дополнение к статье о создании собственного типа пользовательских полей хочу рассказать как делать аналогичные свойства для информационных блоков, т.к. эти свойства относятся к другому модулю, а именно «информационные блоки» (iblock).

Условные операторы в PHP

Условные операторы в PHP

Добрались до логики выполнения программы. И так условные операторы (по другому операторы ветвления) позволяют нам организовать определённое поведение программы в зависимости от входных параметров (данных вводимых пользователем, результатом работы вспомогательных функций). Вся логика в языках программирования основана на Алгебре Буля. 

Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке

Самые читаемые

Тонкая настройка SEO для результатов фильтрации каталога битрикс

Тонкая настройка SEO для результатов фильтрации каталога битрикс

Одним из преимуществ интернет-магазинов на 1С Битрикс на мой взгляд является наличие не так давно до...

Основы SEO оптимизации сайта

Основы SEO оптимизации сайта

Эта статья не истина в последней инстанции, а лишь набор правил которые я применяю при создании/испр...

Собственный тип пользовательских полей в 1С Битрикс

Собственный тип пользовательских полей в 1С Битрикс

Для решения некоторых задач порой не хватает стандартного набора пользовательских полей поставляемых...