primo commit
This commit is contained in:
713
administrator/components/com_fields/src/Helper/FieldsHelper.php
Normal file
713
administrator/components/com_fields/src/Helper/FieldsHelper.php
Normal file
@ -0,0 +1,713 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_fields
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Fields\Administrator\Helper;
|
||||
|
||||
use Joomla\CMS\Event\CustomFields\AfterPrepareFieldEvent;
|
||||
use Joomla\CMS\Event\CustomFields\BeforePrepareFieldEvent;
|
||||
use Joomla\CMS\Event\CustomFields\GetTypesEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareDomEvent;
|
||||
use Joomla\CMS\Event\CustomFields\PrepareFieldEvent;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Fields\FieldsServiceInterface;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Form\FormHelper;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\Component\Fields\Administrator\Model\FieldModel;
|
||||
use Joomla\Component\Fields\Administrator\Model\FieldsModel;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* FieldsHelper
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
class FieldsHelper
|
||||
{
|
||||
/**
|
||||
* @var FieldsModel
|
||||
*/
|
||||
private static $fieldsCache = null;
|
||||
|
||||
/**
|
||||
* @var FieldModel
|
||||
*/
|
||||
private static $fieldCache = null;
|
||||
|
||||
/**
|
||||
* Extracts the component and section from the context string which has to
|
||||
* be in the format component.context.
|
||||
*
|
||||
* @param string $contextString contextString
|
||||
* @param object $item optional item object
|
||||
*
|
||||
* @return array|null
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function extract($contextString, $item = null)
|
||||
{
|
||||
if ($contextString === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = explode('.', $contextString, 2);
|
||||
|
||||
if (\count($parts) < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newSection = '';
|
||||
|
||||
$component = Factory::getApplication()->bootComponent($parts[0]);
|
||||
|
||||
if ($component instanceof FieldsServiceInterface) {
|
||||
$newSection = $component->validateSection($parts[1], $item);
|
||||
}
|
||||
|
||||
if ($newSection) {
|
||||
$parts[1] = $newSection;
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields for the given context.
|
||||
* If the item is an object the returned fields do have an additional field
|
||||
* "value" which represents the value for the given item. If the item has an
|
||||
* assigned_cat_ids field, then additionally fields which belong to that
|
||||
* category will be returned.
|
||||
* Should the value being prepared to be shown in an HTML context then
|
||||
* prepareValue must be set to true. No further escaping needs to be done.
|
||||
* The values of the fields can be overridden by an associative array where the keys
|
||||
* have to be a name and its corresponding value.
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param object|array|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 $valuesToOverride The values to override
|
||||
* @param bool $includeSubformFields Should I include fields marked as Only Use In Subform?
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFields(
|
||||
$context,
|
||||
$item = null,
|
||||
$prepareValue = false,
|
||||
?array $valuesToOverride = null,
|
||||
bool $includeSubformFields = false
|
||||
) {
|
||||
if (self::$fieldsCache === null) {
|
||||
// Load the model
|
||||
self::$fieldsCache = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Fields', 'Administrator', ['ignore_request' => true]);
|
||||
|
||||
self::$fieldsCache->setState('filter.state', 1);
|
||||
self::$fieldsCache->setState('list.limit', 0);
|
||||
}
|
||||
|
||||
if ($includeSubformFields) {
|
||||
self::$fieldsCache->setState('filter.only_use_in_subform', '');
|
||||
} else {
|
||||
self::$fieldsCache->setState('filter.only_use_in_subform', 0);
|
||||
}
|
||||
|
||||
if (\is_array($item)) {
|
||||
$item = (object) $item;
|
||||
}
|
||||
|
||||
if (Multilanguage::isEnabled() && isset($item->language) && $item->language != '*') {
|
||||
self::$fieldsCache->setState('filter.language', ['*', $item->language]);
|
||||
}
|
||||
|
||||
self::$fieldsCache->setState('filter.context', $context);
|
||||
self::$fieldsCache->setState('filter.assigned_cat_ids', []);
|
||||
|
||||
/*
|
||||
* If item has assigned_cat_ids parameter display only fields which
|
||||
* belong to the category
|
||||
*/
|
||||
if ($item && (isset($item->catid) || isset($item->fieldscatid))) {
|
||||
$assignedCatIds = $item->catid ?? $item->fieldscatid;
|
||||
|
||||
if (!\is_array($assignedCatIds)) {
|
||||
$assignedCatIds = explode(',', $assignedCatIds);
|
||||
}
|
||||
|
||||
// Fields without any category assigned should show as well
|
||||
$assignedCatIds[] = 0;
|
||||
|
||||
self::$fieldsCache->setState('filter.assigned_cat_ids', $assignedCatIds);
|
||||
}
|
||||
|
||||
$fields = self::$fieldsCache->getItems();
|
||||
|
||||
if ($fields === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($item && isset($item->id)) {
|
||||
if (self::$fieldCache === null) {
|
||||
self::$fieldCache = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Field', 'Administrator', ['ignore_request' => true]);
|
||||
}
|
||||
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
PluginHelper::importPlugin('fields', null, true, $dispatcher);
|
||||
|
||||
$fieldIds = array_map(
|
||||
function ($f) {
|
||||
return $f->id;
|
||||
},
|
||||
$fields
|
||||
);
|
||||
|
||||
$fieldValues = self::$fieldCache->getFieldValues($fieldIds, $item->id);
|
||||
|
||||
$new = [];
|
||||
|
||||
foreach ($fields as $key => $original) {
|
||||
/*
|
||||
* Doing a clone, otherwise fields for different items will
|
||||
* always reference to the same object
|
||||
*/
|
||||
$field = clone $original;
|
||||
|
||||
if ($valuesToOverride && \array_key_exists($field->name, $valuesToOverride)) {
|
||||
$field->value = $valuesToOverride[$field->name];
|
||||
} elseif ($valuesToOverride && \array_key_exists($field->id, $valuesToOverride)) {
|
||||
$field->value = $valuesToOverride[$field->id];
|
||||
} elseif (\array_key_exists($field->id, $fieldValues)) {
|
||||
$field->value = $fieldValues[$field->id];
|
||||
}
|
||||
|
||||
if (!isset($field->value) || $field->value === '') {
|
||||
$field->value = $field->default_value;
|
||||
}
|
||||
|
||||
$field->rawvalue = $field->value;
|
||||
|
||||
// If boolean prepare, if int, it is the event type: 1 - After Title, 2 - Before Display Content, 3 - After Display Content, 0 - Do not prepare
|
||||
if ($prepareValue && (\is_bool($prepareValue) || $prepareValue === (int) $field->params->get('display', '2'))) {
|
||||
/*
|
||||
* On before field prepare
|
||||
* Event allow plugins to modify the output of the field before it is prepared
|
||||
*/
|
||||
$dispatcher->dispatch('onCustomFieldsBeforePrepareField', new BeforePrepareFieldEvent('onCustomFieldsBeforePrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
]));
|
||||
|
||||
// Gathering the value for the field
|
||||
$value = $dispatcher->dispatch('onCustomFieldsPrepareField', new PrepareFieldEvent('onCustomFieldsPrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
]))->getArgument('result', []);
|
||||
|
||||
if (\is_array($value)) {
|
||||
$value = array_filter($value, function ($v) {
|
||||
return $v !== '' && $v !== null;
|
||||
});
|
||||
$value = $value ? implode(' ', $value) : '';
|
||||
}
|
||||
|
||||
/*
|
||||
* On after field render
|
||||
* Event allows plugins to modify the output of the prepared field
|
||||
*/
|
||||
$eventAfter = new AfterPrepareFieldEvent('onCustomFieldsAfterPrepareField', [
|
||||
'context' => $context,
|
||||
'item' => $item,
|
||||
'subject' => $field,
|
||||
'value' => &$value, // @todo: Remove reference in Joomla 6, see AfterPrepareFieldEvent::__constructor()
|
||||
]);
|
||||
$dispatcher->dispatch('onCustomFieldsAfterPrepareField', $eventAfter);
|
||||
$value = $eventAfter->getValue();
|
||||
|
||||
// Assign the value
|
||||
$field->value = $value;
|
||||
}
|
||||
|
||||
$new[$key] = $field;
|
||||
}
|
||||
|
||||
$fields = $new;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the layout file and data on the context and does a fall back to
|
||||
* Fields afterwards.
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param string $layoutFile layoutFile
|
||||
* @param array $displayData displayData
|
||||
*
|
||||
* @return NULL|string
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function render($context, $layoutFile, $displayData)
|
||||
{
|
||||
$value = '';
|
||||
|
||||
/*
|
||||
* Because the layout refreshes the paths before the render function is
|
||||
* called, so there is no way to load the layout overrides in the order
|
||||
* template -> context -> fields.
|
||||
* If there is no override in the context then we need to call the
|
||||
* layout from Fields.
|
||||
*/
|
||||
if ($parts = self::extract($context)) {
|
||||
// Trying to render the layout on the component from the context
|
||||
$value = LayoutHelper::render($layoutFile, $displayData, null, ['component' => $parts[0], 'client' => 0]);
|
||||
}
|
||||
|
||||
if ($value == '') {
|
||||
// Trying to render the layout on Fields itself
|
||||
$value = LayoutHelper::render($layoutFile, $displayData, null, ['component' => 'com_fields','client' => 0]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* PrepareForm
|
||||
*
|
||||
* @param string $context The context of the content passed to the helper
|
||||
* @param Form $form form
|
||||
* @param object $data data.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function prepareForm($context, Form $form, $data)
|
||||
{
|
||||
// Extracting the component and section
|
||||
$parts = self::extract($context);
|
||||
|
||||
if (! $parts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$context = $parts[0] . '.' . $parts[1];
|
||||
|
||||
// When no fields available return here
|
||||
$fields = self::getFields($parts[0] . '.' . $parts[1]);
|
||||
|
||||
if (! $fields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$component = $parts[0];
|
||||
$section = $parts[1];
|
||||
|
||||
$assignedCatids = $data->catid ?? $data->fieldscatid ?? $form->getValue('catid');
|
||||
|
||||
// Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category
|
||||
$assignedCatids = \is_array($assignedCatids)
|
||||
? (int) reset($assignedCatids)
|
||||
: (int) $assignedCatids;
|
||||
|
||||
if (!$assignedCatids && $formField = $form->getField('catid')) {
|
||||
$assignedCatids = $formField->getAttribute('default', null);
|
||||
|
||||
if (!$assignedCatids) {
|
||||
// Choose the first category available
|
||||
$catOptions = $formField->options;
|
||||
|
||||
if ($catOptions && !empty($catOptions[0]->value)) {
|
||||
$assignedCatids = (int) $catOptions[0]->value;
|
||||
}
|
||||
}
|
||||
|
||||
$data->fieldscatid = $assignedCatids;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a catid field we need to reload the page when the catid
|
||||
* is changed
|
||||
*/
|
||||
if ($form->getField('catid') && $parts[0] != 'com_fields') {
|
||||
/*
|
||||
* Setting some parameters for the category field
|
||||
*/
|
||||
$form->setFieldAttribute('catid', 'refresh-enabled', true);
|
||||
$form->setFieldAttribute('catid', 'refresh-cat-id', $assignedCatids);
|
||||
$form->setFieldAttribute('catid', 'refresh-section', $section);
|
||||
}
|
||||
|
||||
// Getting the fields
|
||||
$fields = self::getFields($parts[0] . '.' . $parts[1], $data);
|
||||
|
||||
if (!$fields) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$fieldTypes = self::getFieldTypes();
|
||||
|
||||
// Creating the dom
|
||||
$xml = new \DOMDocument('1.0', 'UTF-8');
|
||||
$fieldsNode = $xml->appendChild(new \DOMElement('form'))->appendChild(new \DOMElement('fields'));
|
||||
$fieldsNode->setAttribute('name', 'com_fields');
|
||||
|
||||
// Organizing the fields according to their group
|
||||
$fieldsPerGroup = [0 => []];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (!\array_key_exists($field->type, $fieldTypes)) {
|
||||
// Field type is not available
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!\array_key_exists($field->group_id, $fieldsPerGroup)) {
|
||||
$fieldsPerGroup[$field->group_id] = [];
|
||||
}
|
||||
|
||||
if ($path = $fieldTypes[$field->type]['path']) {
|
||||
// Add the lookup path for the field
|
||||
FormHelper::addFieldPath($path);
|
||||
}
|
||||
|
||||
if ($path = $fieldTypes[$field->type]['rules']) {
|
||||
// Add the lookup path for the rule
|
||||
FormHelper::addRulePath($path);
|
||||
}
|
||||
|
||||
$fieldsPerGroup[$field->group_id][] = $field;
|
||||
}
|
||||
|
||||
$model = Factory::getApplication()->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Groups', 'Administrator', ['ignore_request' => true]);
|
||||
$model->setState('filter.context', $context);
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
|
||||
/**
|
||||
* $model->getItems() would only return existing groups, but we also
|
||||
* have the 'default' group with id 0 which is not in the database,
|
||||
* so we create it virtually here.
|
||||
*/
|
||||
$defaultGroup = new \stdClass();
|
||||
$defaultGroup->id = 0;
|
||||
$defaultGroup->title = '';
|
||||
$defaultGroup->description = '';
|
||||
$iterateGroups = array_merge([$defaultGroup], $model->getItems());
|
||||
|
||||
// Looping through the groups
|
||||
foreach ($iterateGroups as $group) {
|
||||
if (empty($fieldsPerGroup[$group->id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Defining the field set
|
||||
/** @var \DOMElement $fieldset */
|
||||
$fieldset = $fieldsNode->appendChild(new \DOMElement('fieldset'));
|
||||
$fieldset->setAttribute('name', 'fields-' . $group->id);
|
||||
$fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields');
|
||||
$fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules');
|
||||
|
||||
$label = $group->title;
|
||||
$description = $group->description;
|
||||
|
||||
if (!$label) {
|
||||
$key = strtoupper($component . '_FIELDS_' . $section . '_LABEL');
|
||||
|
||||
if (!Factory::getLanguage()->hasKey($key)) {
|
||||
$key = 'JGLOBAL_FIELDS';
|
||||
}
|
||||
|
||||
$label = $key;
|
||||
}
|
||||
|
||||
if (!$description) {
|
||||
$key = strtoupper($component . '_FIELDS_' . $section . '_DESC');
|
||||
|
||||
if (Factory::getLanguage()->hasKey($key)) {
|
||||
$description = $key;
|
||||
}
|
||||
}
|
||||
|
||||
$fieldset->setAttribute('label', $label);
|
||||
$fieldset->setAttribute('description', strip_tags($description));
|
||||
|
||||
// Looping through the fields for that context
|
||||
foreach ($fieldsPerGroup[$group->id] as $field) {
|
||||
try {
|
||||
$dispatcher->dispatch('onCustomFieldsPrepareDom', new PrepareDomEvent('onCustomFieldsPrepareDom', [
|
||||
'subject' => $field,
|
||||
'fieldset' => $fieldset,
|
||||
'form' => $form,
|
||||
]));
|
||||
|
||||
/*
|
||||
* If the field belongs to an assigned_cat_id but the assigned_cat_ids in the data
|
||||
* is not known, set the required flag to false on any circumstance.
|
||||
*/
|
||||
if (!$assignedCatids && !empty($field->assigned_cat_ids) && $form->getField($field->name)) {
|
||||
$form->setFieldAttribute($field->name, 'required', 'false');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// When the field set is empty, then remove it
|
||||
if (!$fieldset->hasChildNodes()) {
|
||||
$fieldsNode->removeChild($fieldset);
|
||||
}
|
||||
}
|
||||
|
||||
// Loading the XML fields string into the form
|
||||
$form->load($xml->saveXML());
|
||||
|
||||
// Looping through the fields again to set the value
|
||||
if (!isset($data->id) || !$data->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($fields as $field) {
|
||||
// Get the value already loaded by static::getFields()
|
||||
$value = $field->rawvalue;
|
||||
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!\is_array($value) && $value !== '') {
|
||||
// Function getField doesn't cache the fields, so we try to do it only when necessary
|
||||
$formField = $form->getField($field->name, 'com_fields');
|
||||
|
||||
if ($formField && $formField->forceMultiple) {
|
||||
$value = (array) $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the value on the field
|
||||
$form->setValue($field->name, 'com_fields', $value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean if the actual logged in user can edit the given field value.
|
||||
*
|
||||
* @param \stdClass $field The field
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function canEditFieldValue($field)
|
||||
{
|
||||
$parts = self::extract($field->context);
|
||||
|
||||
return Factory::getUser()->authorise('core.edit.value', $parts[0] . '.field.' . (int) $field->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean based on field (and field group) display / show_on settings
|
||||
*
|
||||
* @param \stdClass $field The field
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.8.7
|
||||
*/
|
||||
public static function displayFieldOnForm($field)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Detect if the field should be shown at all
|
||||
if ($field->params->get('show_on') == 1 && $app->isClient('administrator')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($field->params->get('show_on') == 2 && $app->isClient('site')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!self::canEditFieldValue($field)) {
|
||||
$fieldDisplayReadOnly = $field->params->get('display_readonly', '2');
|
||||
|
||||
if ($fieldDisplayReadOnly == '2') {
|
||||
// Inherit from field group display read-only setting
|
||||
$groupModel = $app->bootComponent('com_fields')
|
||||
->getMVCFactory()->createModel('Group', 'Administrator', ['ignore_request' => true]);
|
||||
$groupDisplayReadOnly = $groupModel->getItem($field->group_id)->params->get('display_readonly', '1');
|
||||
$fieldDisplayReadOnly = $groupDisplayReadOnly;
|
||||
}
|
||||
|
||||
if ($fieldDisplayReadOnly == '0') {
|
||||
// Do not display field on form when field is read-only
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Display field on form
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets assigned categories ids for a field
|
||||
*
|
||||
* @param \stdClass[] $fieldId The field ID
|
||||
*
|
||||
* @return array Array with the assigned category ids
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function getAssignedCategoriesIds($fieldId)
|
||||
{
|
||||
$fieldId = (int) $fieldId;
|
||||
|
||||
if (!$fieldId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('a.category_id'))
|
||||
->from($db->quoteName('#__fields_categories', 'a'))
|
||||
->where('a.field_id = ' . $fieldId);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets assigned categories titles for a field
|
||||
*
|
||||
* @param \stdClass[] $fieldId The field ID
|
||||
*
|
||||
* @return array Array with the assigned categories
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getAssignedCategoriesTitles($fieldId)
|
||||
{
|
||||
$fieldId = (int) $fieldId;
|
||||
|
||||
if (!$fieldId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('c.title'))
|
||||
->from($db->quoteName('#__fields_categories', 'a'))
|
||||
->join('INNER', $db->quoteName('#__categories', 'c') . ' ON a.category_id = c.id')
|
||||
->where($db->quoteName('field_id') . ' = :fieldid')
|
||||
->bind(':fieldid', $fieldId, ParameterType::INTEGER);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fields system plugin extension id.
|
||||
*
|
||||
* @return integer The fields system plugin extension id.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFieldsPluginId()
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('extension_id'))
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
|
||||
->where($db->quoteName('element') . ' = ' . $db->quote('fields'));
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$result = (int) $db->loadResult();
|
||||
} catch (\RuntimeException $e) {
|
||||
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
|
||||
$result = 0;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the fields plugins and returns an array of field types from the plugins.
|
||||
*
|
||||
* The returned array contains arrays with the following keys:
|
||||
* - label: The label of the field
|
||||
* - type: The type of the field
|
||||
* - path: The path of the folder where the field can be found
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function getFieldTypes()
|
||||
{
|
||||
/** @var DispatcherInterface $dispatcher */
|
||||
$dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
|
||||
PluginHelper::importPlugin('fields', null, true, $dispatcher);
|
||||
$eventData = $dispatcher->dispatch('onCustomFieldsGetTypes', new GetTypesEvent('onCustomFieldsGetTypes'))->getArgument('result', []);
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($eventData as $fields) {
|
||||
foreach ($fields as $fieldDescription) {
|
||||
if (!\array_key_exists('path', $fieldDescription)) {
|
||||
$fieldDescription['path'] = null;
|
||||
}
|
||||
|
||||
if (!\array_key_exists('rules', $fieldDescription)) {
|
||||
$fieldDescription['rules'] = null;
|
||||
}
|
||||
|
||||
$data[$fieldDescription['type']] = $fieldDescription;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the internal cache for the custom fields.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
public static function clearFieldsCache()
|
||||
{
|
||||
self::$fieldCache = null;
|
||||
self::$fieldsCache = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user