File manager - Edit - /home/ferretapmx/public_html/subform.zip
Back
PK ���\�wX.�: �: src/Extension/Subform.phpnu �[��� <?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 Joomla\CMS\Event\CustomFields\BeforePrepareFieldEvent; use Joomla\CMS\Form\Form; use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; use Joomla\Component\Fields\Administrator\Plugin\FieldsPlugin; use Joomla\Event\SubscriberInterface; // 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 implements SubscriberInterface { /** * 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; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 5.3.0 */ public static function getSubscribedEvents(): array { return array_merge(parent::getSubscribedEvents(), [ 'onCustomFieldsBeforePrepareField' => 'beforePrepareField', ]); } /** * 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 BeforePrepareFieldEvent $event The event instance. * * @return void * * @since 4.0.0 */ public function beforePrepareField(BeforePrepareFieldEvent $event): void { $field = $event->getField(); 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; } } PK ���\�Sʉ� � src/Extension/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK ���\�Sʉ� � src/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK ���\R�@�# # tmpl/subform.phpnu �[��� <?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; ?> PK ���\�Sʉ� � tmpl/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK ���\�r� � subform.xmlnu �[��� <?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> PK ���\C�r� � services/provider.phpnu �[��� <?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\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) { $plugin = new Subform( (array) PluginHelper::getPlugin('fields', 'subform') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK ���\�Sʉ� � services/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK ���\f� � params/subform.xmlnu �[��� <?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="JLIB_FORM_FIELD_PARAM_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> PK ���\�Sʉ� � params/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK ���\�Sʉ� � .htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK b �\�� � repeatable.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var Form $tmpl The Empty form for template * @var array $forms Array of JForm instances for render the rows * @var bool $multiple The multiple state for the form field * @var int $min Count of minimum repeating in multiple mode * @var int $max Count of maximum repeating in multiple mode * @var string $name Name of the input field. * @var string $fieldname The field name * @var string $fieldId The field ID * @var string $control The forms control * @var string $label The field label * @var string $description The field description * @var string $class Classes for the container * @var array $buttons Array of the buttons that will be rendered * @var bool $groupByFieldset Whether group the subform fields by it`s fieldset */ if ($multiple) { // Add script Factory::getApplication() ->getDocument() ->getWebAssetManager() ->useScript('webcomponent.field-subform'); } $class = $class ? ' ' . $class : ''; $sublayout = empty($groupByFieldset) ? 'section' : 'section-byfieldsets'; ?> <div class="subform-repeatable-wrapper subform-layout"> <joomla-field-subform class="subform-repeatable<?php echo $class; ?>" name="<?php echo $name; ?>" button-add=".group-add" button-remove=".group-remove" button-move="<?php echo empty($buttons['move']) ? '' : '.group-move' ?>" repeatable-element=".subform-repeatable-group" minimum="<?php echo $min; ?>" maximum="<?php echo $max; ?>"> <?php if (!empty($buttons['add'])) : ?> <div class="btn-toolbar"> <div class="btn-group"> <button type="button" class="group-add btn btn-sm button btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"> <span class="icon-plus icon-white" aria-hidden="true"></span> </button> </div> </div> <?php endif; ?> <?php foreach ($forms as $k => $form) : echo $this->sublayout($sublayout, ['form' => $form, 'basegroup' => $fieldname, 'group' => $fieldname . $k, 'buttons' => $buttons]); endforeach; ?> <?php if ($multiple) : ?> <template class="subform-repeatable-template-section hidden"><?php echo trim($this->sublayout($sublayout, ['form' => $tmpl, 'basegroup' => $fieldname, 'group' => $fieldname . 'X', 'buttons' => $buttons])); ?></template> <?php endif; ?> </joomla-field-subform> </div> PK b �\]��U U repeatable-table.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var Form $tmpl The Empty form for template * @var array $forms Array of JForm instances for render the rows * @var bool $multiple The multiple state for the form field * @var int $min Count of minimum repeating in multiple mode * @var int $max Count of maximum repeating in multiple mode * @var string $name Name of the input field. * @var string $fieldname The field name * @var string $fieldId The field ID * @var string $control The forms control * @var string $label The field label * @var string $description The field description * @var string $class Classes for the container * @var array $buttons Array of the buttons that will be rendered * @var bool $groupByFieldset Whether group the subform fields by it`s fieldset */ if ($multiple) { // Add script Factory::getApplication() ->getDocument() ->getWebAssetManager() ->useScript('webcomponent.field-subform'); } $class = $class ? ' ' . $class : ''; // Build heading $table_head = ''; if (!empty($groupByFieldset)) { foreach ($tmpl->getFieldsets() as $k => $fieldset) { $table_head .= '<th scope="col">' . Text::_($fieldset->label); if ($fieldset->description) { $table_head .= '<span class="icon-info-circle" aria-hidden="true" tabindex="0"></span><div role="tooltip" id="tip-th-' . $fieldId . '-' . $k . '">' . Text::_($fieldset->description) . '</div>'; } $table_head .= '</th>'; } $sublayout = 'section-byfieldsets'; } else { $fields = $tmpl->getGroup(''); $th_width = 92 / count($fields); foreach ($fields as $field) { $table_head .= '<th scope="col" style="width:' . $th_width . '%">' . strip_tags($field->label); if ($field->description) { $table_head .= '<span class="icon-info-circle" aria-hidden="true" tabindex="0"></span><div role="tooltip" id="tip-' . $field->id . '">' . Text::_($field->description) . '</div>'; } $table_head .= '</th>'; } $sublayout = 'section'; // Label will not be shown for sections layout, so reset the margin left Factory::getApplication() ->getDocument() ->addStyleDeclaration('.subform-table-sublayout-section .controls { margin-left: 0px }'); } ?> <div class="subform-repeatable-wrapper subform-table-layout subform-table-sublayout-<?php echo $sublayout; ?>"> <joomla-field-subform class="subform-repeatable<?php echo $class; ?>" name="<?php echo $name; ?>" button-add=".group-add" button-remove=".group-remove" button-move="<?php echo empty($buttons['move']) ? '' : '.group-move' ?>" repeatable-element=".subform-repeatable-group" rows-container="tbody.subform-repeatable-container" minimum="<?php echo $min; ?>" maximum="<?php echo $max; ?>"> <div class="table-responsive"> <table class="table" id="subfieldList_<?php echo $fieldId; ?>"> <caption class="visually-hidden"> <?php echo Text::_('JGLOBAL_REPEATABLE_FIELDS_TABLE_CAPTION'); ?> </caption> <thead> <tr> <?php echo $table_head; ?> <?php if (!empty($buttons)) : ?> <td style="width:8%;"> <?php if (!empty($buttons['add'])) : ?> <div class="btn-group"> <button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"> <span class="icon-plus" aria-hidden="true"></span> </button> </div> <?php endif; ?> </td> <?php endif; ?> </tr> </thead> <tbody class="subform-repeatable-container"> <?php foreach ($forms as $k => $form) : echo $this->sublayout($sublayout, ['form' => $form, 'basegroup' => $fieldname, 'group' => $fieldname . $k, 'buttons' => $buttons]); endforeach; ?> </tbody> </table> </div> <?php if ($multiple) : ?> <template class="subform-repeatable-template-section hidden"> <?php echo trim($this->sublayout($sublayout, ['form' => $tmpl, 'basegroup' => $fieldname, 'group' => $fieldname . 'X', 'buttons' => $buttons])); ?> </template> <?php endif; ?> </joomla-field-subform> </div> PK b �\y���1 1 repeatable-table/section.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Form\Form; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var Form $form The form instance for render the section * @var string $basegroup The base group name * @var string $group Current group name * @var array $buttons Array of the buttons that will be rendered */ ?> <tr class="subform-repeatable-group" data-base-name="<?php echo $basegroup; ?>" data-group="<?php echo $group; ?>"> <?php foreach ($form->getGroup('') as $field) : ?> <td data-column="<?php echo strip_tags($field->label); ?>"> <?php echo $field->renderField(['hiddenLabel' => true, 'hiddenDescription' => true]); ?> </td> <?php endforeach; ?> <?php if (!empty($buttons)) : ?> <td> <div class="btn-group"> <?php if (!empty($buttons['add'])) : ?> <button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"> <span class="icon-plus" aria-hidden="true"></span> </button> <?php endif; ?> <?php if (!empty($buttons['remove'])) : ?> <button type="button" class="group-remove btn btn-sm btn-danger" aria-label="<?php echo Text::_('JGLOBAL_FIELD_REMOVE'); ?>"> <span class="icon-minus" aria-hidden="true"></span> </button> <?php endif; ?> <?php if (!empty($buttons['move'])) : ?> <button type="button" class="group-move btn btn-sm btn-primary" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE'); ?>"> <span class="icon-arrows-alt" aria-hidden="true"></span> </button> <?php endif; ?> </div> </td> <?php endif; ?> </tr> PK b �\u�O�� � ( repeatable-table/section-byfieldsets.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Form\Form; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var Form $form The form instance for render the section * @var string $basegroup The base group name * @var string $group Current group name * @var array $buttons Array of the buttons that will be rendered */ ?> <tr class="subform-repeatable-group" data-base-name="<?php echo $basegroup; ?>" data-group="<?php echo $group; ?>"> <?php foreach ($form->getFieldsets() as $fieldset) : ?> <td class="<?php if (!empty($fieldset->class)) { echo $fieldset->class; } ?>"> <?php foreach ($form->getFieldset($fieldset->name) as $field) : ?> <?php echo $field->renderField(); ?> <?php endforeach; ?> </td> <?php endforeach; ?> <?php if (!empty($buttons)) : ?> <td> <div class="btn-group"> <?php if (!empty($buttons['add'])) : ?> <button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"> <span class="icon-plus" aria-hidden="true"></span> </button> <?php endif; ?> <?php if (!empty($buttons['remove'])) : ?> <button type="button" class="group-remove btn btn-sm btn-danger" aria-label="<?php echo Text::_('JGLOBAL_FIELD_REMOVE'); ?>"> <span class="icon-minus" aria-hidden="true"></span> </button> <?php endif; ?> <?php if (!empty($buttons['move'])) : ?> <button type="button" class="group-move btn btn-sm btn-primary" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE'); ?>"> <span class="icon-arrows-alt" aria-hidden="true"></span> </button> <?php endif; ?> </div> </td> <?php endif; ?> </tr> PK b �\�Sʉ� � repeatable-table/.htaccessnu �7��m <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>PK b �\��r r default.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Form\Form; extract($displayData); /** * Layout variables * ----------------- * @var Form $tmpl The Empty form for template * @var array $forms Array of JForm instances for render the rows * @var bool $multiple The multiple state for the form field * @var int $min Count of minimum repeating in multiple mode * @var int $max Count of maximum repeating in multiple mode * @var string $name Name of the input field. * @var string $fieldname The field name * @var string $fieldId The field ID * @var string $control The forms control * @var string $label The field label * @var string $description The field description * @var array $buttons Array of the buttons that will be rendered * @var bool $groupByFieldset Whether group the subform fields by it`s fieldset */ $form = $forms[0]; ?> <div class="subform-wrapper"> <?php foreach ($form->getGroup('') as $field) : ?> <?php echo $field->renderField(); ?> <?php endforeach; ?> </div> PK b �\L�E� � repeatable/section.phpnu �[��� <?php /** * @package Joomla.Site * @subpackage Layout * * @copyright (C) 2016 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\Form\Form; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var Form $form The form instance for render the section * @var string $basegroup The base group name * @var string $group Current group name * @var array $buttons Array of the buttons that will be rendered */ ?> <div class="subform-repeatable-group" data-base-name="<?php echo $basegroup; ?>" data-group="<?php echo $group; ?>"> <?php if (!empty($buttons)) : ?> <div class="btn-toolbar text-end"> <div class="btn-group"> <?php if (!empty($buttons['add'])) : ?><button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"><span class="icon-plus icon-white" aria-hidden="true"></span> </button><?php endif; ?> <?php if (!empty($buttons['remove'])) : ?><button type="button" class="group-remove btn btn-sm btn-danger" aria-label="<?php echo Text::_('JGLOBAL_FIELD_REMOVE'); ?>"><span class="icon-minus icon-white" aria-hidden="true"></span> </button><?php endif; ?> <?php if (!empty($buttons['move'])) : ?> <button type="button" class="group-move btn btn-sm btn-primary" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE'); ?>"><span class="icon-arrows-alt icon-white" aria-hidden="true"></span> </button> <button type="button" class="group-move-up btn btn-sm" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE_UP'); ?>"><span class="icon-chevron-up" aria-hidden="true"></span> </button> <button type="button" class="group-move-down btn btn-sm" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE_DOWN'); ?>"><span class="icon-chevron-down" aria-hidden="true"></span> </button> <?php endif; ?> </div> </div> <?php endif; ?> <?php foreach ($form->getGroup('') as $field) : ?> <?php echo $field->renderField(); ?> <?php endforeach; ?> </div> PK b �\���� � "