uawdijnntqw1x1x1
IP : 216.73.217.59
Hostname : webm003.cluster107.gra.hosting.ovh.net
Kernel : Linux webm003.cluster107.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
OS : Linux
PATH:
/
home
/
opticamezl
/
www
/
newok
/
tmp
/
..
/
cli
/
..
/
plugins
/
..
/
tmp
/
..
/
api
/
..
/
.
/
cli
/
..
/
templates
/
..
/
subform.tar
/
/
services/provider.php000064400000002444151721514730010744 0ustar00<?php /** * @package Joomla.Plugin * @subpackage Fields.subform * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Fields\Subform\Extension\Subform; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Subform( $dispatcher, (array) PluginHelper::getPlugin('fields', 'subform') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; src/Extension/Subform.php000064400000034437151721514730011456 0ustar00<?php /** * @package Joomla.Plugin * @subpackage Fields.subform * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Fields\Subform\Extension; use DOMDocument; use DOMElement; use DOMXPath; use Joomla\CMS\Form\Form; use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; use Joomla\Component\Fields\Administrator\Plugin\FieldsPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Fields Subform Plugin * * @since 3.7.0 */ final class Subform extends FieldsPlugin { /** * Two-dimensional array to hold to do a fast in-memory caching of rendered * subfield values. * * @var array * * @since 4.0.0 */ protected $renderCache = []; /** * Array to do a fast in-memory caching of all custom field items. * * @var array * * @since 4.0.0 */ protected static $customFieldsCache = null; /** * Handles the onContentPrepareForm event. Adds form definitions to relevant forms. * * @param Form $form The form to manipulate * @param array|object $data The data of the form * * @return void * * @since 4.0.0 */ public function onContentPrepareForm(Form $form, $data) { // Get the path to our own form definition (basically ./params/subform.xml) $path = $this->getFormPath($form, $data); if ($path === null) { return; } // Ensure it is an object $formData = (object) $data; // Now load our own form definition into a DOMDocument, because we want to manipulate it $xml = new \DOMDocument(); $xml->load($path); // Prepare a DOMXPath object $xmlxpath = new \DOMXPath($xml); /** * Get all fields of type "subfields" in our own XML * * @var $valuefields \DOMNodeList */ $valuefields = $xmlxpath->evaluate('//field[@type="subfields"]'); // If we haven't found it, something is wrong if (!$valuefields || $valuefields->length != 1) { return; } // Now iterate over those fields and manipulate them, set its parameter `context` to our context foreach ($valuefields as $valuefield) { $valuefield->setAttribute('context', $formData->context); } // When this is not a new instance (editing an existing instance) if (isset($formData->id) && $formData->id > 0) { // Don't allow the 'repeat' attribute to be edited foreach ($xmlxpath->evaluate('//field[@name="repeat"]') as $field) { $field->setAttribute('readonly', '1'); } } // And now load our manipulated form definition into the JForm $form->load($xml->saveXML(), true, '/form/*'); } /** * Manipulates the $field->value before the field is being passed to * onCustomFieldsPrepareField. * * @param string $context The context * @param object $item The item * @param \stdClass $field The field * * @return void * * @since 4.0.0 */ public function onCustomFieldsBeforePrepareField($context, $item, $field) { if (!$this->isTypeSupported($field->type)) { return; } if (is_array($field->value)) { return; } $decoded_value = json_decode($field->value, true); if (!$decoded_value || !is_array($decoded_value)) { return; } $field->value = $decoded_value; } /** * Renders this fields value by rendering all sub fields and joining all those rendered sub fields together. * * @param string $context The context * @param object $item The item * @param \stdClass $field The field * * @return string * * @since 4.0.0 */ public function onCustomFieldsPrepareField($context, $item, $field) { // Check if the field should be processed by us if (!$this->isTypeSupported($field->type)) { return; } // If we don't have any subfields (or values for them), nothing to do. if (!is_array($field->value) || count($field->value) < 1) { return; } // Get the field params $field_params = $this->getParamsFromField($field); /** * Placeholder to hold all rows (if this field is repeatable). * Each array entry is another array representing a row, containing all of the sub fields that * are valid for this row and their raw and rendered values. */ $subform_rows = []; // Create an array with entries being subfields forms, and if not repeatable, containing only one element. $rows = $field->value; if ($field_params->get('repeat', '1') == '0') { $rows = [$field->value]; } // Iterate over each row of the data foreach ($rows as $row) { // Holds all sub fields of this row, incl. their raw and rendered value $row_subfields = []; // For each row, iterate over all the subfields foreach ($this->getSubfieldsFromField($field) as $subfield) { // Fill value (and rawvalue) if we have data for this subfield in the current row, otherwise set them to empty $subfield->rawvalue = $subfield->value = $row[$subfield->name] ?? ''; // Do we want to render the value of this field, and is the value non-empty? if ($subfield->value !== '' && $subfield->render_values == '1') { /** * Construct the cache-key for our renderCache. It is important that the cache key * is as unique as possible to avoid false duplicates (e.g. type and rawvalue is not * enough for the cache key, because type 'list' and value '1' can have different * rendered values, depending on the list items), but it also must be as general as possible * to not cause too many unneeded rendering processes (e.g. the type 'text' will always be * rendered the same when it has the same rawvalue). */ $renderCache_key = serialize( [ $subfield->type, $subfield->id, $subfield->rawvalue, ] ); // Let's see if we have a fast in-memory result for this if (isset($this->renderCache[$renderCache_key])) { $subfield->value = $this->renderCache[$renderCache_key]; } else { // Render this virtual subfield $subfield->value = $this->getApplication()->triggerEvent( 'onCustomFieldsPrepareField', [$context, $item, $subfield] ); $this->renderCache[$renderCache_key] = $subfield->value; } } // Flatten the value if it is an array (list, checkboxes, etc.) [independent of render_values] if (is_array($subfield->value)) { $subfield->value = implode(' ', $subfield->value); } // Store the subfield (incl. its raw and rendered value) into this rows sub fields $row_subfields[$subfield->fieldname] = $subfield; } // Store all the sub fields of this row $subform_rows[] = $row_subfields; } // Store all the rows and their corresponding sub fields in $field->subform_rows $field->subform_rows = $subform_rows; // Call our parent to combine all those together for the final $field->value return parent::onCustomFieldsPrepareField($context, $item, $field); } /** * Returns a DOMElement which is the child of $parent and represents * the form XML definition for this field. * * @param \stdClass $field The field * @param \DOMElement $parent The original parent element * @param Form $form The form * * @return \DOMElement * * @since 4.0.0 */ public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form) { // Call the onCustomFieldsPrepareDom method on FieldsPlugin $parent_field = parent::onCustomFieldsPrepareDom($field, $parent, $form); if (!$parent_field) { return $parent_field; } // Override the fieldname attribute of the subform - this is being used to index the rows $parent_field->setAttribute('fieldname', 'row'); // If the user configured this subform instance as required if ($field->required) { // Then we need to have at least one row $parent_field->setAttribute('min', '1'); } // Get the configured parameters for this field $field_params = $this->getParamsFromField($field); // If this fields should be repeatable, set some attributes on the subform element if ($field_params->get('repeat', '1') == '1') { $parent_field->setAttribute('multiple', 'true'); $parent_field->setAttribute('layout', 'joomla.form.field.subform.repeatable-table'); } // Create a child 'form' DOMElement under the field[type=subform] element. $parent_fieldset = $parent_field->appendChild(new \DOMElement('form')); $parent_fieldset->setAttribute('hidden', 'true'); $parent_fieldset->setAttribute('name', ($field->name . '_modal')); if ($field_params->get('max_rows')) { $parent_field->setAttribute('max', $field_params->get('max_rows')); } // If this field should be repeatable, set some attributes on the modal if ($field_params->get('repeat', '1') == '1') { $parent_fieldset->setAttribute('repeat', 'true'); } // Get the configured sub fields for this field $subfields = $this->getSubfieldsFromField($field); // If we have 5 or more of them, use the `repeatable` layout instead of the `repeatable-table` if (count($subfields) >= 5) { $parent_field->setAttribute('layout', 'joomla.form.field.subform.repeatable'); } // Iterate over the sub fields to call prepareDom on each of those sub-fields foreach ($subfields as $subfield) { // Let the relevant plugins do their work and insert the correct // DOMElement's into our $parent_fieldset. $this->getApplication()->triggerEvent( 'onCustomFieldsPrepareDom', [$subfield, $parent_fieldset, $form] ); } // If the edit layout is set we override any automation $editLayout = $field->params->get('form_layout'); if ($editLayout) { $parent_field->setAttribute('layout', $editLayout); } return $parent_field; } /** * Returns an array of all options configured for this field. * * @param \stdClass $field The field * * @return \stdClass[] * * @since 4.0.0 */ protected function getOptionsFromField(\stdClass $field) { $result = []; // Fetch the options from the plugin $params = $this->getParamsFromField($field); foreach ($params->get('options', []) as $option) { $result[] = (object) $option; } return $result; } /** * Returns the configured params for a given field. * * @param \stdClass $field The field * * @return \Joomla\Registry\Registry * * @since 4.0.0 */ protected function getParamsFromField(\stdClass $field) { $params = (clone $this->params); if (isset($field->fieldparams) && is_object($field->fieldparams)) { $params->merge($field->fieldparams); } return $params; } /** * Returns an array of all subfields for a given field. This will always return a bare clone * of a sub field, so manipulating it is safe. * * @param \stdClass $field The field * * @return \stdClass[] * * @since 4.0.0 */ protected function getSubfieldsFromField(\stdClass $field) { if (static::$customFieldsCache === null) { // Prepare our cache static::$customFieldsCache = []; // Get all custom field instances $customFields = FieldsHelper::getFields('', null, false, null, true); foreach ($customFields as $customField) { // Store each custom field instance in our cache with its id as key static::$customFieldsCache[$customField->id] = $customField; } } $result = []; // Iterate over all configured options for this field foreach ($this->getOptionsFromField($field) as $option) { // Check whether the wanted sub field really is an existing custom field if (!isset(static::$customFieldsCache[$option->customfield])) { continue; } // Get a clone of the sub field, so we and the caller can do some manipulation with it. $cur_field = (clone static::$customFieldsCache[$option->customfield]); // Manipulate it and add our custom configuration to it $cur_field->render_values = $option->render_values; /** * Set the name of the sub field to its id so that the values in the database are being saved * based on the id of the sub fields, not on their name. Actually we do not need the name of * the sub fields to render them, but just to make sure we have the name when we need it, we * store it as `fieldname`. */ $cur_field->fieldname = $cur_field->name; $cur_field->name = 'field' . $cur_field->id; // And add it to our result $result[] = $cur_field; } return $result; } } tmpl/subform.php000064400000003043151721514730007714 0ustar00<?php /** * @package Joomla.Plugin * @subpackage Fields.Subform * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; defined('_JEXEC') or die; if (!$context || empty($field->subform_rows)) { return; } $result = ''; // Iterate over each row that we have foreach ($field->subform_rows as $subform_row) { // Placeholder array to generate this rows output $row_output = []; // Iterate over each sub field inside of that row foreach ($subform_row as $subfield) { $class = trim($subfield->params->get('render_class', '')); $layout = trim($subfield->params->get('layout', 'render')); $content = trim( FieldsHelper::render( $context, 'field.' . $layout, // normally just 'field.render' ['field' => $subfield] ) ); // Skip empty output if ($content === '') { continue; } // Generate the output for this sub field and row $row_output[] = '<span class="field-entry' . ($class ? (' ' . $class) : '') . '">' . $content . '</span>'; } // Skip empty rows if (count($row_output) == 0) { continue; } $result .= '<li>' . implode(', ', $row_output) . '</li>'; } ?> <?php if (trim($result) != '') : ?> <ul class="fields-container"> <?php echo $result; ?> </ul> <?php endif; ?> subform.xml000064400000001614151721514730006753 0ustar00<?xml version="1.0" encoding="UTF-8"?> <extension type="plugin" group="fields" method="upgrade"> <name>plg_fields_subform</name> <author>Joomla! Project</author> <creationDate>2017-06</creationDate> <copyright>(C) 2019 Open Source Matters, Inc.</copyright> <license>GNU General Public License version 2 or later; see LICENSE.txt</license> <authorEmail>admin@joomla.org</authorEmail> <authorUrl>www.joomla.org</authorUrl> <version>4.0.0</version> <description>PLG_FIELDS_SUBFORM_XML_DESCRIPTION</description> <namespace path="src">Joomla\Plugin\Fields\Subform</namespace> <files> <folder>params</folder> <folder plugin="subform">services</folder> <folder>src</folder> <folder>tmpl</folder> </files> <languages> <language tag="en-GB">language/en-GB/plg_fields_subform.ini</language> <language tag="en-GB">language/en-GB/plg_fields_subform.sys.ini</language> </languages> </extension> params/subform.xml000064400000003717151721514730010244 0ustar00<?xml version="1.0" encoding="UTF-8"?> <form> <field name="default_value" type="hidden" default="" /> <fields name="fieldparams"> <fieldset name="fieldparams"> <field name="repeat" type="radio" label="PLG_FIELDS_SUBFORM_PARAMS_REPEAT_LABEL" layout="joomla.form.field.radio.switcher" default="1" > <option value="0">JNO</option> <option value="1">JYES</option> </field> <field name="max_rows" type="number" label="PLG_FIELDS_SUBFORM_PARAMS_MAX_ROWS_LABEL" default="" filter="integer" showon="repeat:1" /> <field name="options" type="subform" label="PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_LABEL" icon="list" layout="joomla.form.field.subform.repeatable-table" min="1" multiple="true" > <form hidden="true" name="options_modal" repeat="true"> <field context="" name="customfield" type="subfields" label="PLG_FIELDS_SUBFORM_PARAMS_CUSTOMFIELD_LABEL" default="" required="true" /> <field name="render_values" type="radio" label="PLG_FIELDS_SUBFORM_PARAMS_RENDER_VALUES_LABEL" layout="joomla.form.field.radio.switcher" default="1" > <option value="0">JNO</option> <option value="1">JYES</option> </field> </form> </field> </fieldset> </fields> <fields name="params"> <fieldset name="basic"> <fieldset name="formoptions"> <field name="form_layout" type="list" label="COM_FIELDS_FIELD_FORM_LAYOUT_LABEL" default="" class="form-select" showon="repeat:1" > <option value="">JDEFAULT</option> <option value="joomla.form.field.subform.repeatable-table">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_TABLE_LABEL</option> <option value="joomla.form.field.subform.repeatable">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_FORM_LABEL</option> </field> </fieldset> </fieldset> </fields> </form>
/home/opticamezl/www/newok/tmp/../cli/../plugins/../tmp/../api/.././cli/../templates/../subform.tar