Поля товаров в любом месте
Как получить и вывести значения дополнительных полей товара в корзине, модуле, кастомном layout или плагине, когда стандартного блока полей недостаточно.
Общий принцип
Готовые поля
$product->fields, $product->fieldsets
На странице товара и в списках RadicalMart уже готовит поля для вывода. В объекте поля есть название, алиас, настройки, сырое значение и готовый результат в $field->value. Если эти данные уже есть, выводите их напрямую.
Сырые значения
$product->fieldsRaw
Когда нужно вывести поле в другом месте, берите сырые значения из $product->fieldsRaw. Это массив по алиасам полей: ключ — алиас поля, значение — то, что сохранено у товара.
Точечный парсинг
FieldsHelper::parseProductFields()
Для одного или нескольких нужных полей соберите маленький массив ['alias' => value] и передайте его в helper. Не прогоняйте все поля товара без причины: каждый тип поля может запускать свой плагин и свои проверки.
Метод parseProductFields
Метод находится в Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper. Он не строит группы полей и не фильтрует поле по настройкам отображения категории; он берёт переданные алиасы, находит опубликованные поля и просит плагин типа поля подготовить значение для вывода.
-
Контекст определяет событие плагина поля. Ровно com_radicalmart.product вызывает onRadicalMartGetProductFieldValue. Любой другой контекст вызывает onRadicalMartGetProductsFieldValue. У плагинов полей могут быть собственные проверки контекста, поэтому выбирайте контекст под место вывода.
-
Массив сырых значений по алиасам полей. Ключи должны быть алиасами, не id. Пустой массив вернёт false.
-
Объект товара. Формально аргумент может быть пустым, но его лучше передавать: плагины полей могут использовать данные товара, категории, цены, наличия или свои дополнительные свойства.
-
Возвращается массив объектов полей по алиасам или false, если нечего обработать. У каждого объекта есть $field->rawvalue и $field->value. $field->value — готовое значение для вывода, если плагин поля смог его подготовить.
Где брать данные
Страница товара
com_radicalmart.product
Обычно доступны $this->product->fields и $this->product->fieldsets. Для повторного вывода конкретного поля можно взять $this->product->fieldsRaw и распарсить только нужный алиас.
Список товаров
com_radicalmart.products / category
В карточках списка объект товара уже может иметь $product->fields. Эти поля подготовлены для отображения в списке и используют событие списка товаров.
Корзина и мини-корзина
cart products
У товаров корзины можно использовать $product->fieldsRaw и событие onRadicalMartGetCartProduct или шаблон корзины. Для вывода в стандартной строке товара удобно добавлять HTML в $product->extra_display[].
Свой запрос
custom object
Если товар получен своим SQL-запросом и поле fields ещё является JSON-строкой, сначала преобразуйте его через new Registry($product->fields)->toArray(), затем передавайте нужные алиасы в helper.
Примеры
Корзина: вывести одно поле
template/layout
<?php
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
$fieldAlias = 'spisok';
foreach ($this->cart->products as $key => $product)
{
$raw = $product->fieldsRaw ?? [];
if (empty($raw[$fieldAlias]))
{
continue;
}
$fields = FieldsHelper::parseProductFields(
'com_radicalmart.product',
[$fieldAlias => $raw[$fieldAlias]],
$product
);
$field = $fields[$fieldAlias] ?? null;
if ($field && $field->value !== false && $field->value !== '')
{
echo '<div class="uk-text-small">';
echo '<span class="uk-text-meta">' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': </span>';
echo $field->value;
echo '</div>';
}
}
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
$fieldAlias = 'spisok';
foreach ($this->cart->products as $key => $product)
{
$raw = $product->fieldsRaw ?? [];
if (empty($raw[$fieldAlias]))
{
continue;
}
$fields = FieldsHelper::parseProductFields(
'com_radicalmart.product',
[$fieldAlias => $raw[$fieldAlias]],
$product
);
$field = $fields[$fieldAlias] ?? null;
if ($field && $field->value !== false && $field->value !== '')
{
echo '<div class="uk-text-small">';
echo '<span class="uk-text-meta">' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': </span>';
echo $field->value;
echo '</div>';
}
}
Несколько алиасов без парсинга всего товара
array_intersect_key
<?php
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
$aliases = ['spisok', 'color', 'size'];
$raw = $product->fieldsRaw ?? [];
$values = array_intersect_key($raw, array_flip($aliases));
$fields = FieldsHelper::parseProductFields('com_radicalmart.products', $values, $product);
if ($fields)
{
foreach ($fields as $field)
{
if ($field->value === false || $field->value === '')
{
continue;
}
echo '<div>' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': ' . $field->value . '</div>';
}
}
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
$aliases = ['spisok', 'color', 'size'];
$raw = $product->fieldsRaw ?? [];
$values = array_intersect_key($raw, array_flip($aliases));
$fields = FieldsHelper::parseProductFields('com_radicalmart.products', $values, $product);
if ($fields)
{
foreach ($fields as $field)
{
if ($field->value === false || $field->value === '')
{
continue;
}
echo '<div>' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': ' . $field->value . '</div>';
}
}
Если поля уже подготовлены
$product->fields
<?php if (!empty($product->fields)): ?>
<dl class="uk-description-list">
<?php foreach ($product->fields as $field): ?>
<?php if (empty($field->value)) continue; ?>
<dt><?php echo $this->escape($field->title); ?></dt>
<dd><?php echo $field->value; ?></dd>
<?php endforeach; ?>
</dl>
<?php endif; ?>
<dl class="uk-description-list">
<?php foreach ($product->fields as $field): ?>
<?php if (empty($field->value)) continue; ?>
<dt><?php echo $this->escape($field->title); ?></dt>
<dd><?php echo $field->value; ?></dd>
<?php endforeach; ?>
</dl>
<?php endif; ?>
Если объект пришёл из своего запроса
Registry fallback
<?php
use Joomla\Registry\Registry;
$raw = [];
if (!empty($product->fieldsRaw) && is_array($product->fieldsRaw))
{
$raw = $product->fieldsRaw;
}
elseif (!empty($product->fields) && is_string($product->fields))
{
$raw = (new Registry($product->fields))->toArray();
}
use Joomla\Registry\Registry;
$raw = [];
if (!empty($product->fieldsRaw) && is_array($product->fieldsRaw))
{
$raw = $product->fieldsRaw;
}
elseif (!empty($product->fields) && is_string($product->fields))
{
$raw = (new Registry($product->fields))->toArray();
}
Плагин для корзины
Стандартные шаблоны корзины, мини-корзины и страницы заказа выводят массив $product->extra_display, если в нём есть элементы с ключом html. Поэтому плагин может добавить туда готовый HTML и не трогать шаблоны.
PHP-класс плагина
onRadicalMartGetCartProduct
<?php
namespace Joomla\Plugin\System\ExampleCartFields\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
use Joomla\Event\SubscriberInterface;
final class ExampleCartFields extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'onRadicalMartGetCartProduct' => 'onRadicalMartGetCartProduct',
];
}
public function onRadicalMartGetCartProduct(string $context, string &$key, object &$product): void
{
$alias = 'spisok';
$raw = $product->fieldsRaw ?? [];
if (empty($raw[$alias]))
{
return;
}
$fields = FieldsHelper::parseProductFields('com_radicalmart.product', [$alias => $raw[$alias]], $product);
$field = $fields[$alias] ?? null;
if (!$field || $field->value === false || $field->value === '')
{
return;
}
$product->extra_display[] = [
'html' => '<span>' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': ' . $field->value . '</span>',
];
}
}
namespace Joomla\Plugin\System\ExampleCartFields\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\RadicalMart\Administrator\Helper\FieldsHelper;
use Joomla\Event\SubscriberInterface;
final class ExampleCartFields extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'onRadicalMartGetCartProduct' => 'onRadicalMartGetCartProduct',
];
}
public function onRadicalMartGetCartProduct(string $context, string &$key, object &$product): void
{
$alias = 'spisok';
$raw = $product->fieldsRaw ?? [];
if (empty($raw[$alias]))
{
return;
}
$fields = FieldsHelper::parseProductFields('com_radicalmart.product', [$alias => $raw[$alias]], $product);
$field = $fields[$alias] ?? null;
if (!$field || $field->value === false || $field->value === '')
{
return;
}
$product->extra_display[] = [
'html' => '<span>' . htmlspecialchars($field->title, ENT_QUOTES, 'UTF-8') . ': ' . $field->value . '</span>',
];
}
}
Правила и частые ошибки
Не парсить всё подряд
производительность
Если нужен один алиас, передайте один алиас. Парсинг всех полей запускает обработчики типов полей и может дать лишнюю работу на каждой строке корзины или списка.
Не путать raw и value
данные / вывод
$field->rawvalue — сохранённое значение. $field->value — результат плагина поля, подготовленный для отображения. В HTML обычно нужен именно $field->value.
Проверять false
безопасность вывода
Helper может вернуть false, а конкретное поле может иметь $field->value === false или пустую строку. Такие значения не выводят.
Экранировать своё
HTML
Название поля и свои строки экранируйте. Значение $field->value уже может быть HTML, подготовленным плагином поля; не смешивайте его с неэкранированным пользовательским текстом.
Контекст влияет
события полей
Для com_radicalmart.product используется событие одиночного товара. Для остальных контекстов — событие списков. Некоторые плагины полей могут вести себя по-разному.
Алиасы, не id
values keys
parseProductFields() ищет поля по алиасам из ключей массива. Если передать id в ключе массива, нужное поле не будет найдено как ожидается.
ТЗ для генерации
Этот текст можно дать ИИ, чтобы он сделал плагин для вывода нужного поля товара в корзине без доступа к ядру RadicalMart. Замените алиас spisok на свой.
Готовый промпт
пример для ИИ
Создай Joomla 5 плагин для RadicalMart 3.
Задача: вывести одно поле товара с алиасом spisok в строках корзины и мини-корзины без правки файлов RadicalMart.
Справка для сверки:
- документация по обработке полей товаров: https://radicalmart.ru/baza-znanij/razrabotchikam/radicalmart-obrabotka-polej-tovarov-v-lyubom-meste
- документация по событиям RadicalMart: https://radicalmart.ru/baza-znanij/razrabotchikam/radicalmart-plugins-events
- документация по полям товаров: использовать FieldsHelper::parseProductFields($context, $values, $product)
- контекст com_radicalmart.product вызывает onRadicalMartGetProductFieldValue, остальные контексты вызывают onRadicalMartGetProductsFieldValue
Требования:
- подписаться на onRadicalMartGetCartProduct;
- брать сырые значения из $product->fieldsRaw;
- передавать в parseProductFields только нужный алиас, не все поля товара;
- передавать объект $product третьим аргументом;
- проверить false, пустые значения и отсутствие алиаса;
- добавить готовый HTML в $product->extra_display[];
- не менять шаблоны и файлы RadicalMart;
- вернуть структуру файлов плагина, PHP-класс, manifest XML и пояснить, где заменить alias поля.
Задача: вывести одно поле товара с алиасом spisok в строках корзины и мини-корзины без правки файлов RadicalMart.
Справка для сверки:
- документация по обработке полей товаров: https://radicalmart.ru/baza-znanij/razrabotchikam/radicalmart-obrabotka-polej-tovarov-v-lyubom-meste
- документация по событиям RadicalMart: https://radicalmart.ru/baza-znanij/razrabotchikam/radicalmart-plugins-events
- документация по полям товаров: использовать FieldsHelper::parseProductFields($context, $values, $product)
- контекст com_radicalmart.product вызывает onRadicalMartGetProductFieldValue, остальные контексты вызывают onRadicalMartGetProductsFieldValue
Требования:
- подписаться на onRadicalMartGetCartProduct;
- брать сырые значения из $product->fieldsRaw;
- передавать в parseProductFields только нужный алиас, не все поля товара;
- передавать объект $product третьим аргументом;
- проверить false, пустые значения и отсутствие алиаса;
- добавить готовый HTML в $product->extra_display[];
- не менять шаблоны и файлы RadicalMart;
- вернуть структуру файлов плагина, PHP-класс, manifest XML и пояснить, где заменить alias поля.