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