Работа с дополнительными полями (вместо API)

Для Joomla 5 способ:

use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
$app = \Joomla\CMS\Factory::getApplication();
$model = $app->bootComponent('com_fields')->getMVCFactory()->createModel('Field', 'Administrator', ['ignore_request' => true]);
try{
    $model->setFieldValue($field_id, $item_id, $value);
}catch(\Exception $e){
    
}

Для Joomla 4 способ такой:

use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
...
$fields = FieldsHelper::getFields('com_content.article', $article, true);

	 * @param   string      $context              The context of the content passed to the helper
	 * @param   null        $item                 The item being edited in the form
	 * @param   int|bool    $prepareValue         (if int is display event): 1 - AfterTitle, 2 - BeforeDisplay, 3 - AfterDisplay, 0 - OFF
	 * @param   array|null  $valuesToOverride     The values to override
	 * @param   bool        $includeSubformFields Should I include fields marked as Only Use In Subform?
	 *
	 * @return  array

Нормального АПИ не нашел. Поэтому работа через модель поля (взято из их же плагина).

// Возможно, сперва придется подключить в верхней части скрипта:
defined('_JEXEC') or die;
use Joomla\Registry\Registry;
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');

// Получение доп. полей объекта по контексту (без этого может не работать вызов модуля)
$fields = FieldsHelper::getFields('com_users.user', $user->id);

// Создаем объект модели поля
$model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true));

// Запись значения поля
$model->setFieldValue($field->id, $item->id, $value);

// Чтение значения поля
$value = $model->getFieldValue($field->id, $item->id);

// Очистка значений всех доп. полей для объекта заданного контекстом (напри., "com_users.user") и его ИДом. Может пригодиться при удалении объекта:
$model->cleanupValues($context, $item->id);

// Остальные методы модели можно посмотреть в самой модели:
/administrator/components/com_fields/models/field.php

 

 

После очередного обновления способ, описанный выше, дал сбой и новые значения доп. полей не захотели сохраняться в базе. А потому - менее кошерный, но более надежный способ работы с доп. полями (а точнее - их значениями):

    static function getFieldValue($fieldId, $itemId, $default = null){
        $db = JFactory::getDbo();
        $fieldIdQ = $db->quote($fieldId);
        $itemIdQ = $db->quote($itemId);
        $db->setQuery("SELECT `value` FROM `#__fields_values` WHERE `field_id` = {$fieldIdQ} AND `item_id` = {$itemIdQ}");
        $res = $db->loadAssoc();
        $value = empty($res) ? $default : $res['value'];
        return $value;
    }
    
    static function setFieldValue($fieldId, $itemId, $value = null){
        $db = JFactory::getDbo();
        $fieldIdQ = $db->quote($fieldId);
        $itemIdQ = $db->quote($itemId);
        $valueQ = $db->quote($value);
        
        if(is_null($value)){
            $db->setQuery("DELETE FROM `#__fields_values` WHERE `field_id` = {$fieldIdQ} AND `item_id` = {$itemIdQ};");
            $db->execute();
        }else{
            $old = self::getFieldValue($fieldId, $itemId);
            if(is_null($old)){
                $db->setQuery("INSERT INTO `#__fields_values` (`field_id`, `item_id`, `value`) VALUES ({$fieldIdQ}, {$itemIdQ}, {$valueQ});");
                $db->execute();
            }else{
                $db->setQuery("UPDATE `#__fields_values` SET `value` = {$valueQ} WHERE `field_id` = {$fieldIdQ} AND `item_id` = {$itemIdQ};");
                $db->execute();
            }
        }
        
        return $db->getAffectedRows();
    }