Виртуальные свойства

При разработке сайта, и, в особенности, интернет-магазина, бывает необходимо выдавать пользователю свойство объекта, основываясь на каком-то изменяющемся параметре, или высчитываемое по определенной формуле. Например, при наличии у товара свойств "Высота", "Ширина" и "Длина" - выдавать в карточке товара также и свойство "Объём". Или показывать срок доставки товара в зависимости от времени суток и дня недели.

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

 

Итак, для примера возьмём реализацию функционала, который находится в стандартной поставке шаблона "demodizzy" с версии 2.8.5.1. В карточках товаров раздела "ДВД диски" есть свойство "Диаметр" а также виртуальное свойство "Площадь", высчитывющееся из диаметра по математической формуле. Разберемся, как это работает.

Для начала, нужно добавить соответствующий рестрикшен в систему. Для этого нужно сделать две вещи:

  • 1. Необходимо создать непосредственно рестрикшен (код). Как это сделать, описано здесь. В итоге мы должны получить в директории ~/classes/system/subsystems/models/data/restrictions файл, например, circleSquare.php с таким содержимым:
    <?php
     class circleSquareRestriction extends baseRestriction implements iNormalizeOutRestriction {
    
      public function validate($value, $objectId = false) {
       return true;
      }
      // используем функцию normalizeOut, для обработки значения поля после загрузки из БД
      public function normalizeOut($value, $objectId = false) {
    
      $objects = umiObjectsCollection::getInstance();
       $object = $objects->getObject($objectId);
    
       $square = null;
       // получаем значение поля diametr_sm для обрабатываемого объекта
       if ($object instanceof umiObject && $object->getValue('diametr_sm')) {
        $square = 3.1415 * pow(($object->getValue('diametr_sm')/2), 2);
       }
    
      return $square;
      
      }
     };
    ?>
     
  • 2. Вторым шагом будет добавление этого рестрикшена для нужного типа полей, при помощи метода add(). Код этого скрипта будет примерно таким:
    <?php
    
     include("./standalone.php");
     
     $title = "Площадь круга"; //название рестрикшена в админ-панели
     $prefix = "circleSquare"; //префикс класса рестрикшена
     
     $dataType = "int"; //строковый идентификатор типа поля
     $multiple = false; //множественность типа поля
     
     $fieldsCollection = umiFieldTypesCollection::getInstance(); //коллекция типов полей
     $fieldType = $fieldsCollection->getFieldTypeByDataType($dataType, $multiple); //тип поля
     $fieldTypeId = $fieldType->getId(); //числовой идентификатор типа поля
     
     baseRestriction::add($prefix, $title, $fieldTypeId); //добавить рестрикшен с именем $title префиксом $prefix для поля типа "число"
     
    ?>
     
    Скрипт следует поместить в отдельный php-файл в корне сайта и запустить его один раз - этого будет достаточно для добавления рестрикшена в систему.

Теперь, когда рестрикшен добавлен в систему, мы можем использовать его в админ-панели. Для этого в модуле Шаблоны данных добавляем соответствующее поле в нужный тип данных (в нашем примере это тип "dvd диски") и выбираем в выпадающем списке параметра "Формат значения" наш рестрикшен "Площадь круга".

Всё готово. Осталось указать в шаблоне место для отображения добавленного поля.