Перейти к основному содержимому

Вычисляемые значения

Общее

Тип данных вычисляемое значение (calculated value) позволяет вычислять значение поля на основе значений других полей объекта. Значение всегда вычисляется «на лету» при вызове соответствующего геттера — кеширование не применяется.

Единственные данные, которые сохраняются в базе, — это значения в таблицах запросов (query tables) объекта, необходимые для возможности фильтрации/поиска (например, фильтрация в сетке) по вычисляемым полям.

Значения в таблице запросов обновляются только при сохранении объекта. Поэтому будьте внимательны: значения в таблице запросов могут быть неактуальны в зависимости от параметров вычисления.

В редакторе объекта доступно три варианта отображения:

  • Input: одна строка, отображается как поле только для чтения.
  • TextArea: многострочное поле, отображается как область текста только для чтения.
  • HTML: многострочный HTML-контент, отображается как поле для отображения.

Вычисление

Для задания логики вычисления доступны два варианта:

Выражение (Expression)

Проще всего задать вычисление с помощью выражения. Язык выражений базируется на компоненте symfony expression language. Синтаксис и возможности см. в документации Symfony по expression language.

Доступные переменные
  • object — сам объект DataObject.
  • data — контекстная информация (см. раздел «Информация о контексте вычисления» ниже).
Простые примеры
# Вывести ID объекта 
object.getId()

# Вывести имя и фамилию объекта, разделённые пробелом
object.getFirstname() ~ ' ' ~ object.getLastname()

# Проверить, пусто ли поле
object.getText() != '' ? 'yes' : 'no'

# Получить имя текущего поля
data.getFieldname()


Класс вычислитель

Второй вариант — предоставить PHP‑класс вычислитель. Это удобно для более сложных вычислений и повторного использования логики.

Класс вычислитель должен быть стандартным сервисом Symfony (или простой PHP‑класс) и реализовывать интерфейс CalculatorClassInterface.

Настройка в определении класса

Класс вычислитель можно указать двумя способами:

  • Symfony‑сервис (рекомендуемый): указать имя сервиса с префиксом @ (например, @service_name), cервис должен быть публичным.
  • Обычный PHP‑класс: указать полное пространство имён класса, Pimcore создаст экземпляр через new.

Конфигурация вычисляемого значения

Реализация класса вычислителя

Предположим, у нас есть очень простой класс объекта с двумя числовыми полями xValue и yValue, и вычисляемым полем sum, помещённым внутри localizedfields.

The PHP calculator class needs to implement the CalculatorClassInterface interface.

Класс вычислителя должен реализовать интерфейс CalculatorClassInterface и реализовать метод compute, который вычисляет значение для поля sum. В метод в качестве аргументов передаются объект Pimcore и контекст с информацией о том, какое поле вычисляется и где оно расположено (подробнее — в разделе «Информация о контексте вычисления»).

namespace App;  

use Pimcore\Logger;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\ClassDefinition\CalculatorClassInterface;
use Pimcore\Model\DataObject\Data\CalculatedValue;

class Calculator implements CalculatorClassInterface
{
public function compute(Concrete $object, CalculatedValue $context): string
{
if ($context->getFieldname() == "sum") {
$language = $context->getPosition();
return $object->getXValue($language) + $object->getYValue($language);
} else {
Logger::error("unknown field");
return '';
}
}
}

В этом примере вычислитель суммирует значения x и y для соответствующей языковой вкладки.

Кроме метода compute, необходимо реализовать метод getCalculatedValueForEditMode. Он используется для отображения значения в режиме редактирования объекта:

public function getCalculatedValueForEditMode(Concrete $object, CalculatedValue $context): string  
{
$language = $context->getPosition();
$result = $object->getXValue($language) . " + " . $object->getYValue($language) . " = " . $this->compute($object, $context);
return $result;
}

Результат

Визуальный результат был бы следующим:

Поле вычисляемого значения

Информация о контексте вычисления

Содержимое объекта контекста зависит от того, где находится поле calculated-value в модели данных.

Объект (высший уровень)

НазваниеОписание
ownerType"object"
fieldNameимя вычисляемого поля (например, sum)

Localizedfields

НазваниеОписание
positionязык ("en", "de", ...)
ownerType"localizedfield"
ownerNameимя контейнера локализованных полей ("localizedfields")

Objectbricks

НазваниеОписание
ownerType"objectbrick"
ownerNameимя поля objectbrick в объекте
fieldNameимя атрибута внутри objectbrick
indexимя brick (ключ) — указывает, к какому brick относится поле
keyDefinitionопределение поля calculated-value
positionязык ("en", "de", ...), если вычисляемое поле локализовано

Fieldcollections

НазваниеОписание
ownerType"fieldcollection"
ownerNameимя атрибута fieldcollection
fieldNameимя атрибута внутри fieldcollection
indexиндекс элемента в коллекции
keyDefinitionопределение вычисляемого поля

Classification Store

НазваниеОписание
ownerType"classificationstore"
ownerNameимя атрибута classification store
fieldNameимя атрибута внутри classification store
positionязык
groupIdid группы
keyIdid ключа
keyDefinitionопределение поля в classification store

Работа с PHP API

Геттеры для класса объекта генерируются как обычно. Пример получения значений:

$object = DataObject::getByPath("/demoobject");  
$valueDe = $object->getSum("de"); // => 38
$valueEn = $object->getSum("en"); // => 11


Вы можете предложить улучшение документации или задать вопрос в комментариях.
Если вам нужна полноценная консультация — вы можете заказать её на нашем сайте.