File manager - Edit - /home/opticamezl/www/newok/Form.zip
Back
PK ��\,��� FormFactoryInterface.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface defining a factory which can create Form objects * * @since 4.0.0 */ interface FormFactoryInterface { /** * Method to get an instance of a form. * * @param string $name The name of the form. * @param array $options An array of form options. * * @return Form * * @since 4.0.0 */ public function createForm(string $name, array $options = []): Form; } PK ��\4 ��B B Filter/TelFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for phone numbers * * @since 4.0.0 */ class TelFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $value = trim($value); // Does it match the NANP pattern? if (preg_match('/^(?:\+?1[-. ]?)?\(?([2-9][0-8][0-9])\)?[-. ]?([2-9][0-9]{2})[-. ]?([0-9]{4})$/', $value) == 1) { $number = (string) preg_replace('/[^\d]/', '', $value); if (substr($number, 0, 1) === '1') { $number = substr($number, 1); } if (substr($number, 0, 2) === '+1') { $number = substr($number, 2); } $result = '1.' . $number; } elseif (preg_match('/^\+(?:[0-9] ?){6,14}[0-9]$/', $value) == 1) { // If not, does it match ITU-T? $countrycode = substr($value, 0, strpos($value, ' ')); $countrycode = (string) preg_replace('/[^\d]/', '', $countrycode); $number = strstr($value, ' '); $number = (string) preg_replace('/[^\d]/', '', $number); $result = $countrycode . '.' . $number; } elseif (preg_match('/^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/', $value) == 1) { // If not, does it match EPP? if (strstr($value, 'x')) { $xpos = strpos($value, 'x'); $value = substr($value, 0, $xpos); } $result = str_replace('+', '', $value); } elseif (preg_match('/[0-9]{1,3}\.[0-9]{4,14}$/', $value) == 1) { // Maybe it is already ccc.nnnnnnn? $result = $value; } else { // If not, can we make it a string of digits? $value = (string) preg_replace('/[^\d]/', '', $value); if ($value != null && \strlen($value) <= 15) { $length = \strlen($value); // If it is fewer than 13 digits assume it is a local number if ($length <= 12) { $result = '.' . $value; } else { // If it has 13 or more digits let's make a country code. $cclen = $length - 12; $result = substr($value, 0, $cclen) . '.' . substr($value, $cclen); } } else { // If not let's not save anything. $result = ''; } } return $result; } } PK ��\��� G G Filter/UrlFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\CMS\String\PunycodeHelper; use Joomla\CMS\Uri\Uri; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for URLs * * @since 4.0.0 */ class UrlFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { if (empty($value)) { return false; } // This cleans some of the more dangerous characters but leaves special characters that are valid. $value = InputFilter::getInstance()->clean($value, 'html'); $value = trim($value); // <>" are never valid in a uri see https://www.ietf.org/rfc/rfc1738.txt $value = str_replace(['<', '>', '"'], '', $value); // Check for a protocol $protocol = parse_url($value, PHP_URL_SCHEME); // If there is no protocol and the relative option is not specified, // we assume that it is an external URL and prepend http:// if ( ((string) $element['type'] === 'url' && !$protocol && !$element['relative']) || ((string) $element['type'] !== 'url' && !$protocol) ) { $protocol = 'http'; // If it looks like an internal link, then add the root. if (substr($value, 0, 9) === 'index.php') { $value = Uri::root() . $value; } else { // Otherwise we treat it as an external link. // Put the url back together. $value = $protocol . '://' . $value; } } elseif (!$protocol && $element['relative']) { // If relative URLS are allowed we assume that URLs without protocols are internal. $host = Uri::getInstance('SERVER')->getHost(); // If it starts with the host string, just prepend the protocol. if (substr($value, 0) === $host) { $value = 'http://' . $value; } elseif (substr($value, 0, 1) !== '/') { // Otherwise if it doesn't start with "/" prepend the prefix of the current site. $value = Uri::root(true) . '/' . $value; } } $value = PunycodeHelper::urlToPunycode($value); return $value; } } PK ��\��r� Filter/RawFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for raw values * * @since 4.0.0 */ class RawFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { return $value; } } PK ��\4�R�� � Filter/RulesFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for rules * * @since 4.0.0 */ class RulesFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $return = []; foreach ((array) $value as $action => $ids) { // Build the rules array. $return[$action] = []; foreach ($ids as $id => $p) { if ($p !== '') { $return[$action][$id] = ($p == '1' || $p === 'true'); } } } return $return; } } PK ��\&R &c c Filter/SafehtmlFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for safe HTML * * @since 4.0.0 */ class SafehtmlFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { return InputFilter::getInstance( [], [], InputFilter::ONLY_BLOCK_DEFINED_TAGS, InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES )->clean($value, 'html'); } } PK ��\ٲ0�y y Filter/UnsetFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class to unset * * @since 4.0.0 */ class UnsetFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { return null; } } PK ��\D�M M Filter/IntarrayFilter.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Filter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFilterInterface; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Filter class for integer arrays * * @since 4.0.0 */ class IntarrayFilter implements FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { if (strtoupper((string) $element['filter']) === 'INT_ARRAY') { @trigger_error('`INT_ARRAY` form filter is deprecated and will be removed in 5.0. Use `Intarray` instead', E_USER_DEPRECATED); } if (\is_object($value)) { $value = get_object_vars($value); } $value = \is_array($value) ? $value : [$value]; $value = ArrayHelper::toInteger($value); return $value; } } PK ��\������ �� FormField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form; use Joomla\CMS\Factory; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Form\Field\SubformField; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\FileLayout; use Joomla\CMS\Log\Log; use Joomla\Database\DatabaseAwareInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseInterface; use Joomla\Database\Exception\DatabaseNotFoundException; use Joomla\Registry\Registry; use Joomla\String\Normalise; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Abstract Form Field class for the Joomla Platform. * * @since 1.7.0 */ abstract class FormField implements DatabaseAwareInterface { use DatabaseAwareTrait; /** * The description text for the form field. Usually used in tooltips. * * @var string * @since 1.7.0 */ protected $description; /** * The hint text for the form field used to display hint inside the field. * * @var string * @since 3.2 */ protected $hint; /** * The autocomplete state for the form field. If 'off' element will not be automatically * completed by browser. * * @var mixed * @since 3.2 */ protected $autocomplete = 'on'; /** * The spellcheck state for the form field. * * @var boolean * @since 3.2 */ protected $spellcheck = true; /** * The autofocus request for the form field. If true element will be automatically * focused on document load. * * @var boolean * @since 3.2 */ protected $autofocus = false; /** * The SimpleXMLElement object of the `<field>` XML element that describes the form field. * * @var \SimpleXMLElement * @since 1.7.0 */ protected $element; /** * The Form object of the form attached to the form field. * * @var Form * @since 1.7.0 */ protected $form; /** * The form control prefix for field names from the Form object attached to the form field. * * @var string * @since 1.7.0 */ protected $formControl; /** * The hidden state for the form field. * * @var boolean * @since 1.7.0 */ protected $hidden = false; /** * Should the label be hidden when rendering the form field? This may be useful if you have the * label rendering in a legend in your form field itself for radio buttons in a fieldset etc. * If you use this flag you should ensure you display the label in your form (for a11y etc.) * * @var boolean * @since 4.0.0 */ protected $hiddenLabel = false; /** * Should the description be hidden when rendering the form field? This may be useful if you have the * description rendering in your form field itself for e.g. note fields. * * @var boolean * @since 4.0.0 */ protected $hiddenDescription = false; /** * True to translate the field label string. * * @var boolean * @since 1.7.0 */ protected $translateLabel = true; /** * True to translate the field description string. * * @var boolean * @since 1.7.0 */ protected $translateDescription = true; /** * True to translate the field hint string. * * @var boolean * @since 3.2 */ protected $translateHint = true; /** * The document id for the form field. * * @var string * @since 1.7.0 */ protected $id; /** * The input for the form field. * * @var string * @since 1.7.0 */ protected $input; /** * The label for the form field. * * @var string * @since 1.7.0 */ protected $label; /** * The multiple state for the form field. If true then multiple values are allowed for the * field. Most often used for list field types. * * @var boolean * @since 1.7.0 */ protected $multiple = false; /** * Allows extensions to create repeat elements * * @var mixed * @since 3.2 */ public $repeat = false; /** * The pattern (Reg Ex) of value of the form field. * * @var string * @since 1.7.0 */ protected $pattern; /** * The validation text of invalid value of the form field. * * @var string * @since 4.0.0 */ protected $validationtext; /** * The name of the form field. * * @var string * @since 1.7.0 */ protected $name; /** * The name of the field. * * @var string * @since 1.7.0 */ protected $fieldname; /** * The group of the field. * * @var string * @since 1.7.0 */ protected $group; /** * The required state for the form field. If true then there must be a value for the field to * be considered valid. * * @var boolean * @since 1.7.0 */ protected $required = false; /** * The disabled state for the form field. If true then the field will be disabled and user can't * interact with the field. * * @var boolean * @since 3.2 */ protected $disabled = false; /** * The readonly state for the form field. If true then the field will be readonly. * * @var boolean * @since 3.2 */ protected $readonly = false; /** * The form field type. * * @var string * @since 1.7.0 */ protected $type; /** * The validation method for the form field. This value will determine which method is used * to validate the value for a field. * * @var string * @since 1.7.0 */ protected $validate; /** * The value of the form field. * * @var mixed * @since 1.7.0 */ protected $value; /** * The default value of the form field. * * @var mixed * @since 1.7.0 */ protected $default; /** * The size of the form field. * * @var integer * @since 3.2 */ protected $size; /** * The class of the form field * * @var mixed * @since 3.2 */ protected $class; /** * The label's CSS class of the form field * * @var mixed * @since 1.7.0 */ protected $labelclass; /** * The javascript onchange of the form field. * * @var string * @since 3.2 */ protected $onchange; /** * The javascript onclick of the form field. * * @var string * @since 3.2 */ protected $onclick; /** * The conditions to show/hide the field. * * @var string * @since 3.7.0 */ protected $showon; /** * The parent class of the field * * @var string * @since 4.0.0 */ protected $parentclass; /** * The count value for generated name field * * @var integer * @since 1.7.0 */ protected static $count = 0; /** * The string used for generated fields names * * @var string * @since 1.7.0 */ protected static $generated_fieldname = '__field'; /** * Name of the layout being used to render the field * * @var string * @since 3.5 */ protected $layout; /** * Layout to render the form field * * @var string */ protected $renderLayout = 'joomla.form.renderfield'; /** * Layout to render the label * * @var string */ protected $renderLabelLayout = 'joomla.form.renderlabel'; /** * The data-attribute name and values of the form field. * For example, data-action-type="click" data-action-type="change" * * @var array * * @since 4.0.0 */ protected $dataAttributes = []; /** * Method to instantiate the form field object. * * @param Form $form The form to attach to the form field object. * * @since 1.7.0 */ public function __construct($form = null) { // If there is a form passed into the constructor set the form and form control properties. if ($form instanceof Form) { $this->form = $form; $this->formControl = $form->getFormControl(); } // Detect the field type if not set if (!isset($this->type)) { $parts = Normalise::fromCamelCase(\get_called_class(), true); if ($parts[0] === 'J') { $this->type = StringHelper::ucfirst($parts[\count($parts) - 1], '_'); } else { $this->type = StringHelper::ucfirst($parts[0], '_') . StringHelper::ucfirst($parts[\count($parts) - 1], '_'); } } } /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 1.7.0 */ public function __get($name) { switch ($name) { case 'description': case 'hint': case 'formControl': case 'hidden': case 'id': case 'multiple': case 'name': case 'required': case 'type': case 'validate': case 'value': case 'class': case 'layout': case 'labelclass': case 'size': case 'onchange': case 'onclick': case 'fieldname': case 'group': case 'disabled': case 'readonly': case 'autofocus': case 'autocomplete': case 'spellcheck': case 'validationtext': case 'showon': case 'parentclass': return $this->$name; case 'input': // If the input hasn't yet been generated, generate it. if (empty($this->input)) { $this->input = $this->getInput(); } return $this->input; case 'label': // If the label hasn't yet been generated, generate it. if (empty($this->label)) { $this->label = $this->getLabel(); } return $this->label; case 'title': return $this->getTitle(); default: // Check for data attribute if (strpos($name, 'data-') === 0 && array_key_exists($name, $this->dataAttributes)) { return $this->dataAttributes[$name]; } } } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'class': // Removes spaces from left & right and extra spaces from middle $value = preg_replace('/\s+/', ' ', trim((string) $value)); // No break case 'description': case 'hint': case 'value': case 'labelclass': case 'layout': case 'onchange': case 'onclick': case 'validate': case 'pattern': case 'validationtext': case 'group': case 'showon': case 'parentclass': case 'default': case 'autocomplete': $this->$name = (string) $value; break; case 'id': $this->id = $this->getId((string) $value, $this->fieldname); break; case 'fieldname': $this->fieldname = $this->getFieldName((string) $value); break; case 'name': $this->fieldname = $this->getFieldName((string) $value); $this->name = $this->getName($this->fieldname); break; case 'multiple': // Allow for field classes to force the multiple values option. $value = (string) $value; $value = $value === '' && isset($this->forceMultiple) ? (string) $this->forceMultiple : $value; // No break case 'required': case 'disabled': case 'readonly': case 'autofocus': case 'hidden': $value = (string) $value; $this->$name = ($value === 'true' || $value === $name || $value === '1'); break; case 'spellcheck': case 'translateLabel': case 'translateDescription': case 'translateHint': $value = (string) $value; $this->$name = !($value === 'false' || $value === 'off' || $value === '0'); break; case 'translate_label': $value = (string) $value; $this->translateLabel = $this->translateLabel && !($value === 'false' || $value === 'off' || $value === '0'); break; case 'translate_description': $value = (string) $value; $this->translateDescription = $this->translateDescription && !($value === 'false' || $value === 'off' || $value === '0'); break; case 'size': $this->$name = (int) $value; break; default: // Detect data attribute(s) if (strpos($name, 'data-') === 0) { $this->dataAttributes[$name] = $value; } else { if (property_exists(__CLASS__, $name)) { Log::add("Cannot access protected / private property $name of " . __CLASS__); } else { $this->$name = $value; } } } } /** * Method to attach a Form object to the field. * * @param Form $form The Form object to attach to the form field. * * @return FormField The form field object so that the method can be used in a chain. * * @since 1.7.0 */ public function setForm(Form $form) { $this->form = $form; $this->formControl = $form->getFormControl(); return $this; } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @since 1.7.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { // Make sure there is a valid FormField XML element. if ((string) $element->getName() !== 'field') { return false; } // Reset the input and label values. $this->input = null; $this->label = null; // Set the XML element object. $this->element = $element; // Set the group of the field. $this->group = $group; $attributes = [ 'multiple', 'name', 'id', 'hint', 'class', 'description', 'labelclass', 'onchange', 'onclick', 'validate', 'pattern', 'validationtext', 'default', 'required', 'disabled', 'readonly', 'autofocus', 'hidden', 'autocomplete', 'spellcheck', 'translateHint', 'translateLabel', 'translate_label', 'translateDescription', 'translate_description', 'size', 'showon', ]; $this->default = isset($element['value']) ? (string) $element['value'] : $this->default; // Set the field default value. if ($element['multiple'] && \is_string($value) && \is_array(json_decode($value, true))) { $this->value = (array) json_decode($value); } else { $this->value = $value; } // Lets detect miscellaneous data attribute. For eg, data-* foreach ($this->element->attributes() as $key => $value) { if (strpos($key, 'data-') === 0) { // Data attribute key value pair $this->dataAttributes[$key] = $value; } } foreach ($attributes as $attributeName) { $this->__set($attributeName, $element[$attributeName]); } // Allow for repeatable elements $repeat = (string) $element['repeat']; $this->repeat = ($repeat === 'true' || $repeat === 'multiple' || (!empty($this->form->repeat) && $this->form->repeat == 1)); // Set the visibility. $this->hidden = ($this->hidden || strtolower((string) $this->element['type']) === 'hidden'); $this->layout = !empty($this->element['layout']) ? (string) $this->element['layout'] : $this->layout; $this->parentclass = isset($this->element['parentclass']) ? (string) $this->element['parentclass'] : $this->parentclass; // Add required to class list if field is required. if ($this->required) { $this->class = trim($this->class . ' required'); } return true; } /** * Simple method to set the value * * @param mixed $value Value to set * * @return void * * @since 3.2 */ public function setValue($value) { $this->value = $value; } /** * Method to get the id used for the field input tag. * * @param string $fieldId The field element id. * @param string $fieldName The field element name. * * @return string The id to be used for the field input tag. * * @since 1.7.0 */ protected function getId($fieldId, $fieldName) { $id = ''; // If there is a form control set for the attached form add it first. if ($this->formControl) { $id .= $this->formControl; } // If the field is in a group add the group control to the field id. if ($this->group) { // If we already have an id segment add the group control as another level. if ($id) { $id .= '_' . str_replace('.', '_', $this->group); } else { $id .= str_replace('.', '_', $this->group); } } // If we already have an id segment add the field id/name as another level. if ($id) { $id .= '_' . ($fieldId ?: $fieldName); } else { $id .= ($fieldId ?: $fieldName); } // Clean up any invalid characters. $id = preg_replace('#\W#', '_', $id); // If this is a repeatable element, add the repeat count to the ID if ($this->repeat) { $repeatCounter = empty($this->form->repeatCounter) ? 0 : $this->form->repeatCounter; $id .= '-' . $repeatCounter; if (strtolower($this->type) === 'radio') { $id .= '-'; } } return $id; } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 1.7.0 */ protected function getInput() { if (empty($this->layout)) { throw new \UnexpectedValueException(sprintf('%s has no layout assigned.', $this->name)); } return $this->getRenderer($this->layout)->render($this->getLayoutData()); } /** * Method to get the field title. * * @return string The field title. * * @since 1.7.0 */ protected function getTitle() { $title = ''; if ($this->hidden) { return $title; } // Get the label text from the XML element, defaulting to the element name. $title = $this->element['label'] ? (string) $this->element['label'] : (string) $this->element['name']; $title = $this->translateLabel ? Text::_($title) : $title; return $title; } /** * Method to get the field label markup. * * @return string The field label markup. * * @since 1.7.0 */ protected function getLabel() { if ($this->hidden) { return ''; } $data = $this->getLayoutData(); // Forcing the Alias field to display the tip below $position = ((string) $this->element['name']) === 'alias' ? ' data-bs-placement="bottom" ' : ''; // Here mainly for B/C with old layouts. This can be done in the layouts directly $extraData = [ 'text' => $data['label'], 'for' => $this->id, 'classes' => explode(' ', $data['labelclass']), 'position' => $position, ]; return $this->getRenderer($this->renderLabelLayout)->render(array_merge($data, $extraData)); } /** * Method to get the name used for the field input tag. * * @param string $fieldName The field element name. * * @return string The name to be used for the field input tag. * * @since 1.7.0 */ protected function getName($fieldName) { // To support repeated element, extensions can set this in plugin->onRenderSettings $name = ''; // If there is a form control set for the attached form add it first. if ($this->formControl) { $name .= $this->formControl; } // If the field is in a group add the group control to the field name. if ($this->group) { // If we already have a name segment add the group control as another level. $groups = explode('.', $this->group); if ($name) { foreach ($groups as $group) { $name .= '[' . $group . ']'; } } else { $name .= array_shift($groups); foreach ($groups as $group) { $name .= '[' . $group . ']'; } } } // If we already have a name segment add the field name as another level. if ($name) { $name .= '[' . $fieldName . ']'; } else { $name .= $fieldName; } // If the field should support multiple values add the final array segment. if ($this->multiple) { switch (strtolower((string) $this->element['type'])) { case 'text': case 'textarea': case 'email': case 'password': case 'radio': case 'calendar': case 'editor': case 'hidden': break; default: $name .= '[]'; } } return $name; } /** * Method to get the field name used. * * @param string $fieldName The field element name. * * @return string The field name * * @since 1.7.0 */ protected function getFieldName($fieldName) { if ($fieldName) { return $fieldName; } else { self::$count = self::$count + 1; return self::$generated_fieldname . self::$count; } } /** * Method to get an attribute of the field * * @param string $name Name of the attribute to get * @param mixed $default Optional value to return if attribute not found * * @return mixed Value of the attribute / default * * @since 3.2 */ public function getAttribute($name, $default = null) { if ($this->element instanceof \SimpleXMLElement) { $attributes = $this->element->attributes(); // Ensure that the attribute exists if ($attributes->$name !== null) { return (string) $attributes->$name; } } return $default; } /** * Method to get data attributes. For example, data-user-type * * @return array list of data attribute(s) * * @since 4.0.0 */ public function getDataAttributes() { return $this->dataAttributes; } /** * Method to render data attributes to html. * * @return string A HTML Tag Attribute string of data attribute(s) * * @since 4.0.0 */ public function renderDataAttributes() { $dataAttribute = ''; $dataAttributes = $this->getDataAttributes(); if (!empty($dataAttributes)) { foreach ($dataAttributes as $key => $attrValue) { $dataAttribute .= ' ' . $key . '="' . htmlspecialchars($attrValue, ENT_COMPAT, 'UTF-8') . '"'; } } return $dataAttribute; } /** * Render a layout of this field * * @param string $layoutId Layout identifier * @param array $data Optional data for the layout * * @return string * * @since 3.5 */ public function render($layoutId, $data = []) { $data = array_merge($this->getLayoutData(), $data); return $this->getRenderer($layoutId)->render($data); } /** * Method to get a control group with label and input. * * @param array $options Options to be passed into the rendering of the field * * @return string A string containing the html for the control group * * @since 3.2 */ public function renderField($options = []) { if ($this->hidden) { return $this->getInput(); } if (!isset($options['class'])) { $options['class'] = ''; } $options['rel'] = ''; if (empty($options['hiddenLabel'])) { if ($this->getAttribute('hiddenLabel')) { $options['hiddenLabel'] = $this->getAttribute('hiddenLabel') == 'true'; } else { $options['hiddenLabel'] = $this->hiddenLabel; } } if (empty($options['hiddenDescription'])) { if ($this->getAttribute('hiddenDescription')) { $options['hiddenDescription'] = $this->getAttribute('hiddenDescription') == 'true'; } else { $options['hiddenDescription'] = $this->hiddenDescription; } } $options['inlineHelp'] = isset($this->form, $this->form->getXml()->config->inlinehelp['button']) ? ((string) $this->form->getXml()->config->inlinehelp['button'] == 'show' ?: false) : false; // Check if the field has showon in nested option $hasOptionShowOn = false; if (!empty((array) $this->element->xpath('option'))) { foreach ($this->element->xpath('option') as $option) { if ((string) $option['showon']) { $hasOptionShowOn = true; break; } } } if ($this->showon || $hasOptionShowOn) { $options['rel'] = ' data-showon=\'' . json_encode(FormHelper::parseShowOnConditions($this->showon, $this->formControl, $this->group)) . '\''; $options['showonEnabled'] = true; } $data = [ 'input' => $this->getInput(), 'label' => $this->getLabel(), 'options' => $options, ]; $data = array_merge($this->getLayoutData(), $data); return $this->getRenderer($this->renderLayout)->render($data); } /** * Method to filter a field value. * * @param mixed $value The optional value to use as the default for the field. * @param string $group The optional dot-separated form group path on which to find the field. * @param ?Registry $input An optional Registry object with the entire data set to filter * against the entire form. * * @return mixed The filtered value. * * @since 4.0.0 * @throws \UnexpectedValueException */ public function filter($value, $group = null, Registry $input = null) { // Make sure there is a valid SimpleXMLElement. if (!($this->element instanceof \SimpleXMLElement)) { throw new \UnexpectedValueException(sprintf('%s::filter `element` is not an instance of SimpleXMLElement', \get_class($this))); } // Get the field filter type. $filter = (string) $this->element['filter']; if ($filter !== '') { $required = ((string) $this->element['required'] === 'true' || (string) $this->element['required'] === 'required'); if (($value === '' || $value === null) && !$required) { return ''; } // Check for a callback filter if (strpos($filter, '::') !== false && \is_callable(explode('::', $filter))) { return \call_user_func(explode('::', $filter), $value); } // Load the FormRule object for the field. FormRule objects take precedence over PHP functions $obj = FormHelper::loadFilterType($filter); // Run the filter rule. if ($obj) { return $obj->filter($this->element, $value, $group, $input, $this->form); } if (\function_exists($filter)) { return \call_user_func($filter, $value); } if ($this instanceof SubformField) { $subForm = $this->loadSubForm(); // Subform field may have a default value, that is a JSON string if ($value && is_string($value)) { $value = json_decode($value, true); // The string is invalid json if (!$value) { return null; } } if ($this->multiple) { $return = []; if ($value) { foreach ($value as $key => $val) { $return[$key] = $subForm->filter($val); } } } else { $return = $subForm->filter($value); } return $return; } } return InputFilter::getInstance()->clean($value, $filter); } /** * Method to validate a FormField object based on field data. * * @param mixed $value The optional value to use as the default for the field. * @param string $group The optional dot-separated form group path on which to find the field. * @param ?Registry $input An optional Registry object with the entire data set to validate * against the entire form. * * @return boolean|\Exception Boolean true if field value is valid, Exception on failure. * * @since 4.0.0 * @throws \InvalidArgumentException * @throws \UnexpectedValueException */ public function validate($value, $group = null, Registry $input = null) { // Make sure there is a valid SimpleXMLElement. if (!($this->element instanceof \SimpleXMLElement)) { throw new \UnexpectedValueException(sprintf('%s::validate `element` is not an instance of SimpleXMLElement', \get_class($this))); } $valid = true; // Check if the field is required. $required = ((string) $this->element['required'] === 'true' || (string) $this->element['required'] === 'required'); if ($this->element['label']) { $fieldLabel = $this->element['label']; // Try to translate label if not set to false $translate = (string) $this->element['translateLabel']; if (!($translate === 'false' || $translate === 'off' || $translate === '0')) { $fieldLabel = Text::_($fieldLabel); } } else { $fieldLabel = Text::_($this->element['name']); } // If the field is required and the value is empty return an error message. if ($required && (($value === '') || ($value === null))) { $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED', $fieldLabel); return new \RuntimeException($message); } // Get the field validation rule. if ($type = (string) $this->element['validate']) { // Load the FormRule object for the field. $rule = FormHelper::loadRuleType($type); // If the object could not be loaded return an error message. if ($rule === false) { throw new \UnexpectedValueException(sprintf('%s::validate() rule `%s` missing.', \get_class($this), $type)); } if ($rule instanceof DatabaseAwareInterface) { try { $rule->setDatabase($this->getDatabase()); } catch (DatabaseNotFoundException $e) { @trigger_error(sprintf('Database must be set, this will not be caught anymore in 5.0.'), E_USER_DEPRECATED); $rule->setDatabase(Factory::getContainer()->get(DatabaseInterface::class)); } } try { // Run the field validation rule test. $valid = $rule->test($this->element, $value, $group, $input, $this->form); } catch (\Exception $e) { return $e; } } if ($valid !== false && $this instanceof SubformField) { // Load the subform validation rule. $rule = FormHelper::loadRuleType('Subform'); if ($rule instanceof DatabaseAwareInterface) { try { $rule->setDatabase($this->getDatabase()); } catch (DatabaseNotFoundException $e) { @trigger_error(sprintf('Database must be set, this will not be caught anymore in 5.0.'), E_USER_DEPRECATED); $rule->setDatabase(Factory::getContainer()->get(DatabaseInterface::class)); } } try { // Run the field validation rule test. $valid = $rule->test($this->element, $value, $group, $input, $this->form); } catch (\Exception $e) { return $e; } } // Check if the field is valid. if ($valid === false) { // Does the field have a defined error message? $message = (string) $this->element['message']; if ($message) { $message = Text::_($this->element['message']); } else { $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $fieldLabel); } return new \UnexpectedValueException($message); } return $valid; } /** * Method to post-process a field value. * * @param mixed $value The optional value to use as the default for the field. * @param string $group The optional dot-separated form group path on which to find the field. * @param ?Registry $input An optional Registry object with the entire data set to filter * against the entire form. * * @return mixed The processed value. * * @since 4.0.0 */ public function postProcess($value, $group = null, Registry $input = null) { return $value; } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.5 */ protected function getLayoutData() { $label = !empty($this->element['label']) ? (string) $this->element['label'] : null; $label = $label && $this->translateLabel ? Text::_($label) : $label; $description = !empty($this->description) ? $this->description : null; $description = !empty($description) && $this->translateDescription ? Text::_($description) : $description; $alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname); $options = [ 'autocomplete' => $this->autocomplete, 'autofocus' => $this->autofocus, 'class' => $this->class, 'description' => $description, 'disabled' => $this->disabled, 'field' => $this, 'group' => $this->group, 'hidden' => $this->hidden, 'hint' => $this->translateHint ? Text::alt($this->hint, $alt) : $this->hint, 'id' => $this->id, 'label' => $label, 'labelclass' => $this->labelclass, 'multiple' => $this->multiple, 'name' => $this->name, 'onchange' => $this->onchange, 'onclick' => $this->onclick, 'pattern' => $this->pattern, 'validationtext' => $this->validationtext, 'readonly' => $this->readonly, 'repeat' => $this->repeat, 'required' => (bool) $this->required, 'size' => $this->size, 'spellcheck' => $this->spellcheck, 'validate' => $this->validate, 'value' => $this->value, 'dataAttribute' => $this->renderDataAttributes(), 'dataAttributes' => $this->dataAttributes, 'parentclass' => $this->parentclass, ]; return $options; } /** * Allow to override renderer include paths in child fields * * @return array * * @since 3.5 */ protected function getLayoutPaths() { $renderer = new FileLayout('default'); return $renderer->getDefaultIncludePaths(); } /** * Get the renderer * * @param string $layoutId Id to load * * @return FileLayout * * @since 3.5 */ protected function getRenderer($layoutId = 'default') { $renderer = new FileLayout($layoutId); $renderer->setDebug($this->isDebugEnabled()); $layoutPaths = $this->getLayoutPaths(); if ($layoutPaths) { $renderer->setIncludePaths($layoutPaths); } return $renderer; } /** * Is debug enabled for this field * * @return boolean * * @since 3.5 */ protected function isDebugEnabled() { return $this->getAttribute('debug', 'false') === 'true'; } } PK ��\%�.� � # Rule/CssIdentifierSubstringRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 3.10.7 */ class CssIdentifierSubstringRule extends FormRule { /** * Method to test if a string is a valid CSS identifier substring * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.10.7 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value) && $value !== '0') { return true; } /** * The following regex rules are based on the Html::cleanCssIdentifier method from Drupal * https://github.com/drupal/drupal/blob/8.8.5/core/lib/Drupal/Component/Utility/Html.php#L116-L130 * * with the addition for Joomla that we allow the colon (U+003A) and the @ (U+0040). */ /** * Valid characters in a CSS identifier are: * - the hyphen (U+002D) * - a-z (U+0030 - U+0039) * - A-Z (U+0041 - U+005A) * - the underscore (U+005F) * - the colon (U+003A) * - the @ sign (U+0040) * - 0-9 (U+0061 - U+007A) * - ISO 10646 characters U+00A1 and higher */ // Make sure we allow multiple classes to be added $cssIdentifiers = explode(' ', $value); foreach ($cssIdentifiers as $identifier) { if (preg_match('/[^\\x{002D}\\x{0030}-\\x{0039}\\x{0040}-\\x{005A}\\x{005F}\\x{003A}\\x{0061}-\\x{007A}\\x{00A1}-\\x{FFFF}]/u', $identifier)) { return false; } } return true; } } PK ��\��_� � Rule/SubformRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Rule; use Joomla\CMS\Form\Field\SubformField; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form rule to validate subforms field-wise. * * @since 3.9.7 */ class SubformRule extends FormRule { /** * Method to test given values for a subform.. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.9.7 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Get the form field object. $field = $form->getField($element['name'], $group); if (!($field instanceof SubformField)) { throw new \UnexpectedValueException(sprintf('%s is no subform field.', $element['name'])); } if ($value === null) { return true; } $subForm = $field->loadSubForm(); // Multiple values: Validate every row. if ($field->multiple) { foreach ($value as $row) { if ($subForm->validate($row) === false) { // Pass the first error that occurred on the subform validation. $errors = $subForm->getErrors(); if (!empty($errors[0])) { return $errors[0]; } return false; } } } else { // Single value. if ($subForm->validate($value) === false) { // Pass the first error that occurred on the subform validation. $errors = $subForm->getErrors(); if (!empty($errors[0])) { return $errors[0]; } return false; } } return true; } } PK ��\�2B:g g Rule/PasswordRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 3.1.2 */ class PasswordRule extends FormRule { /** * Method to test if two values are not equal. To use this rule, the form * XML needs a validate attribute of equals and a field attribute * that is equal to the field to test against. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.1.2 * @throws \InvalidArgumentException * @throws \UnexpectedValueException */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $meter = isset($element['strengthmeter']) ? ' meter="0"' : '1'; $threshold = isset($element['threshold']) ? (int) $element['threshold'] : 66; $minimumLength = isset($element['minimum_length']) ? (int) $element['minimum_length'] : 12; $minimumIntegers = isset($element['minimum_integers']) ? (int) $element['minimum_integers'] : 0; $minimumSymbols = isset($element['minimum_symbols']) ? (int) $element['minimum_symbols'] : 0; $minimumUppercase = isset($element['minimum_uppercase']) ? (int) $element['minimum_uppercase'] : 0; $minimumLowercase = isset($element['minimum_lowercase']) ? (int) $element['minimum_lowercase'] : 0; // In the installer we don't have any access to the // database yet so use the hard coded default settings if ( !Factory::getApplication()->isClient('installation') && !Factory::getApplication()->isClient('cli_installation') ) { // If we have parameters from com_users, use those instead. // Some of these may be empty for legacy reasons. $params = ComponentHelper::getParams('com_users'); if (!empty($params)) { $minimumLengthp = $params->get('minimum_length', 12); $minimumIntegersp = $params->get('minimum_integers', 0); $minimumSymbolsp = $params->get('minimum_symbols', 0); $minimumUppercasep = $params->get('minimum_uppercase', 0); $minimumLowercasep = $params->get('minimum_lowercase', 0); $meterp = $params->get('meter'); $thresholdp = $params->get('threshold', 66); empty($minimumLengthp) ?: $minimumLength = (int) $minimumLengthp; empty($minimumIntegersp) ?: $minimumIntegers = (int) $minimumIntegersp; empty($minimumSymbolsp) ?: $minimumSymbols = (int) $minimumSymbolsp; empty($minimumUppercasep) ?: $minimumUppercase = (int) $minimumUppercasep; empty($minimumLowercasep) ?: $minimumLowercase = (int) $minimumLowercasep; empty($meterp) ?: $meter = $meterp; empty($thresholdp) ?: $threshold = $thresholdp; } } // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } $valueLength = \strlen($value); // We set a maximum length to prevent abuse since it is unfiltered. if ($valueLength > 4096) { Factory::getApplication()->enqueueMessage(Text::_('JFIELD_PASSWORD_TOO_LONG'), 'error'); } // We don't allow white space inside passwords $valueTrim = trim($value); // Set a variable to check if any errors are made in password $validPassword = true; if (\strlen($valueTrim) !== $valueLength) { Factory::getApplication()->enqueueMessage( Text::_('JFIELD_PASSWORD_SPACES_IN_PASSWORD'), 'error' ); $validPassword = false; } // Minimum number of integers required if (!empty($minimumIntegers)) { $nInts = preg_match_all('/[0-9]/', $value, $imatch); if ($nInts < $minimumIntegers) { Factory::getApplication()->enqueueMessage( Text::plural('JFIELD_PASSWORD_NOT_ENOUGH_INTEGERS_N', $minimumIntegers), 'error' ); $validPassword = false; } } // Minimum number of symbols required if (!empty($minimumSymbols)) { $nsymbols = preg_match_all('[\W]', $value, $smatch); if ($nsymbols < $minimumSymbols) { Factory::getApplication()->enqueueMessage( Text::plural('JFIELD_PASSWORD_NOT_ENOUGH_SYMBOLS_N', $minimumSymbols), 'error' ); $validPassword = false; } } // Minimum number of upper case ASCII characters required if (!empty($minimumUppercase)) { $nUppercase = preg_match_all('/[A-Z]/', $value, $umatch); if ($nUppercase < $minimumUppercase) { Factory::getApplication()->enqueueMessage( Text::plural('JFIELD_PASSWORD_NOT_ENOUGH_UPPERCASE_LETTERS_N', $minimumUppercase), 'error' ); $validPassword = false; } } // Minimum number of lower case ASCII characters required if (!empty($minimumLowercase)) { $nLowercase = preg_match_all('/[a-z]/', $value, $umatch); if ($nLowercase < $minimumLowercase) { Factory::getApplication()->enqueueMessage( Text::plural('JFIELD_PASSWORD_NOT_ENOUGH_LOWERCASE_LETTERS_N', $minimumLowercase), 'error' ); $validPassword = false; } } // Minimum length option if (!empty($minimumLength)) { if (\strlen((string) $value) < $minimumLength) { Factory::getApplication()->enqueueMessage( Text::plural('JFIELD_PASSWORD_TOO_SHORT_N', $minimumLength), 'error' ); $validPassword = false; } } // If valid has violated any rules above return false. if (!$validPassword) { return false; } return true; } } PK ��\�1a�E E Rule/CssIdentifierRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 4.0.0 */ class CssIdentifierRule extends FormRule { /** * Method to test if the file path is valid * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 4.0.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value) && $value !== '0') { return true; } // Make sure we allow multiple classes to be added $cssIdentifiers = explode(' ', $value); foreach ($cssIdentifiers as $i => $identifier) { /** * The following regex rules are based on the Html::cleanCssIdentifier method from Drupal * https://github.com/drupal/drupal/blob/8.8.5/core/lib/Drupal/Component/Utility/Html.php#L116-L130 * * with the addition for Joomla that we allow the colon (U+003A) and the @ (U+0040). */ /** * Valid characters in a CSS identifier are: * - the hyphen (U+002D) * - a-z (U+0030 - U+0039) * - A-Z (U+0041 - U+005A) * - the underscore (U+005F) * - the colon (U+003A) * - the @-sign (U+0040) * - 0-9 (U+0061 - U+007A) * - ISO 10646 characters U+00A1 and higher */ if (preg_match('/[^\\x{002D}\\x{0030}-\\x{0039}\\x{0040}-\\x{005A}\\x{005F}\\x{003A}\\x{0061}-\\x{007A}\\x{00A1}-\\x{FFFF}]/u', $identifier)) { return false; } /** * Full identifiers cannot start with a digit, two hyphens, or a hyphen followed by a digit. */ if (preg_match('/^[0-9]/', $identifier) || preg_match('/^(-[0-9])|^(--)/', $identifier)) { return false; } } return true; } } PK ��\8TV Rule/ColorRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class ColorRule extends FormRule { /** * Method to test for a valid color in hexadecimal. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $value = trim($value); // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } if ($value[0] != '#') { return false; } // Remove the leading # if present to validate the numeric part $value = ltrim($value, '#'); // The value must be 6 or 3 characters long if (!((\strlen($value) == 6 || \strlen($value) == 3) && ctype_xdigit($value))) { return false; } return true; } } PK ��\* �R Rule/UrlRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Uri\UriHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class UrlRule extends FormRule { /** * Method to test an external or internal url for all valid parts. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 * @link https://www.w3.org/Addressing/URL/url-spec.txt * @see \Joomla\String\StringHelper */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } // Check the value for XSS payloads if ((string) $element['disableXssCheck'] !== 'true' && InputFilter::checkAttribute(['href', $value])) { $element->addAttribute('message', Text::sprintf('JLIB_FORM_VALIDATE_FIELD_URL_INJECTION_DETECTED', $element['name'])); return false; } $urlParts = UriHelper::parse_url($value); // See https://www.w3.org/Addressing/URL/url-spec.txt // Use the full list or optionally specify a list of permitted schemes. if ($element['schemes'] == '') { $scheme = ['http', 'https', 'ftp', 'ftps', 'gopher', 'mailto', 'news', 'prospero', 'telnet', 'rlogin', 'sftp', 'tn3270', 'wais', 'mid', 'cid', 'nntp', 'tel', 'urn', 'ldap', 'file', 'fax', 'modem', 'git', ]; } else { $scheme = explode(',', $element['schemes']); } /* * Note that parse_url() does not always parse accurately without a scheme, * but at least the path should be set always. Note also that parse_url() * returns False for seriously malformed URLs instead of an associative array. * @link https://www.php.net/manual/en/function.parse-url.php */ if ($urlParts === false || !\array_key_exists('scheme', $urlParts)) { /* * The function parse_url() returned false (seriously malformed URL) or no scheme * was found and the relative option is not set: in both cases the field is not valid. */ if ($urlParts === false || !$element['relative']) { $element->addAttribute('message', Text::sprintf('JLIB_FORM_VALIDATE_FIELD_URL_SCHEMA_MISSING', $value, implode(', ', $scheme))); return false; } // The best we can do for the rest is make sure that the path exists and is valid UTF-8. if (!\array_key_exists('path', $urlParts) || !StringHelper::valid((string) $urlParts['path'])) { return false; } // The internal URL seems to be good. return true; } // Scheme found, check all parts found. $urlScheme = (string) $urlParts['scheme']; $urlScheme = strtolower($urlScheme); if (\in_array($urlScheme, $scheme) == false) { return false; } // For some schemes here must be two slashes. $scheme = ['http', 'https', 'ftp', 'ftps', 'gopher', 'wais', 'prospero', 'sftp', 'telnet', 'git']; if (\in_array($urlScheme, $scheme) && substr($value, \strlen($urlScheme), 3) !== '://') { return false; } // The best we can do for the rest is make sure that the strings are valid UTF-8 // and the port is an integer. if (\array_key_exists('host', $urlParts) && !StringHelper::valid((string) $urlParts['host'])) { return false; } if (\array_key_exists('port', $urlParts) && 0 === (int) $urlParts['port']) { return false; } if (\array_key_exists('path', $urlParts) && !StringHelper::valid((string) $urlParts['path'])) { return false; } return true; } } PK ��\�GS� � Rule/CalendarRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform * * @since 3.7.0 */ class CalendarRule extends FormRule { /** * Method to test the calendar value for a valid parts. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } if (strtolower($value) === 'now') { return true; } try { return Factory::getDate($value) instanceof Date; } catch (\Exception $e) { return false; } } } PK ��\6���� � Rule/UsernameRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Database\DatabaseAwareInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class UsernameRule extends FormRule implements DatabaseAwareInterface { use DatabaseAwareTrait; /** * Method to test the username for uniqueness. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Get the database object and a new query object. $db = $this->getDatabase(); $query = $db->getQuery(true); // Get the extra field check attribute. $userId = ($form instanceof Form) ? (int) $form->getValue('id') : 0; // Build the query. $query->select('COUNT(*)') ->from($db->quoteName('#__users')) ->where( [ $db->quoteName('username') . ' = :username', $db->quoteName('id') . ' <> :userId', ] ) ->bind(':username', $value) ->bind(':userId', $userId, ParameterType::INTEGER); // Set and query the database. $db->setQuery($query); $duplicate = (bool) $db->loadResult(); if ($duplicate) { return false; } return true; } } PK ��\�3�}x x Rule/TelRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform * * @since 1.7.0 */ class TelRule extends FormRule { /** * Method to test the url for a valid parts. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } /* * @link http://www.nanpa.com/ * @link http://tools.ietf.org/html/rfc4933 * @link http://www.itu.int/rec/T-REC-E.164/en * * Regex by Steve Levithan * @link http://blog.stevenlevithan.com/archives/validate-phone-number * @note that valid ITU-T and EPP must begin with +. */ $regexarray = [ 'NANP' => '/^(?:\+?1[-. ]?)?\(?([2-9][0-8][0-9])\)?[-. ]?([2-9][0-9]{2})[-. ]?([0-9]{4})$/', 'ITU-T' => '/^\+(?:[0-9] ?){6,14}[0-9]$/', 'EPP' => '/^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/', ]; if (isset($element['plan'])) { $plan = (string) $element['plan']; if ($plan === 'northamerica' || $plan === 'us') { $plan = 'NANP'; } elseif ($plan === 'International' || $plan === 'int' || $plan === 'missdn' || !$plan) { $plan = 'ITU-T'; } elseif ($plan === 'IETF') { $plan = 'EPP'; } $regex = $regexarray[$plan]; // Test the value against the regular expression. if (preg_match($regex, $value) == false) { return false; } } else { /* * If the rule is set but no plan is selected just check that there are between * 7 and 15 digits inclusive and no illegal characters (but common number separators * are allowed). */ $cleanvalue = preg_replace('/[+. \-(\)]/', '', $value); $regex = '/^[0-9]{7,15}?$/'; if (preg_match($regex, $cleanvalue) == true) { return true; } else { return false; } } return true; } } PK ��\�c�f� � Rule/OptionsRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * Requires the value entered be one of the options in a field of type="list" * * @since 1.7.0 */ class OptionsRule extends FormRule { /** * Method to test the value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Check if the field is required. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); // Check if the value is empty. $blank = empty($value) && $value !== '0' && $value !== 0 && $value !== 0.0; if (!$required && $blank) { return true; } // Make an array of all available option values. $options = []; // Create the field $field = null; if ($form) { $field = $form->getField((string) $element->attributes()->name, $group); } // When the field exists, the real options are fetched. // This is needed for fields which do have dynamic options like from a database. if ($field && \is_array($field->options)) { foreach ($field->options as $opt) { $options[] = $opt->value; } } else { foreach ($element->option as $opt) { $options[] = $opt->attributes()->value; } } // There may be multiple values in the form of an array (if the element is checkboxes, for example). if (\is_array($value)) { // If all values are in the $options array, $diff will be empty and the options valid. $diff = array_diff($value, $options); return empty($diff); } else { // In this case value must be a string return \in_array((string) $value, $options); } } } PK ��\��nc\ \ Rule/BooleanRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\FormRule; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class BooleanRule extends FormRule { /** * The regular expression to use in testing a form field value. * * @var string * @since 1.7.0 */ protected $regex = '^(?:[01]|true|false)$'; /** * The regular expression modifiers to use when testing a form field value. * * @var string * @since 1.7.0 */ protected $modifiers = 'i'; } PK ��\'MZ�2 2 Rule/ExistsRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Database\DatabaseAwareInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form rule class to determine if a value exists in a database table. * * @since 3.9.0 */ class ExistsRule extends FormRule implements DatabaseAwareInterface { use DatabaseAwareTrait; /** * Method to test the username for uniqueness. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.9.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $value = trim($value); $existsTable = (string) $element['exists_table']; $existsColumn = (string) $element['exists_column']; // We cannot validate without a table name if ($existsTable === '') { return true; } // Assume a default column name of `id` if ($existsColumn === '') { $existsColumn = 'id'; } $db = $this->getDatabase(); // Set and query the database. $exists = $db->setQuery( $db->getQuery(true) ->select('COUNT(*)') ->from($db->quoteName($existsTable)) ->where($db->quoteName($existsColumn) . ' = ' . $db->quote($value)) )->loadResult(); return (int) $exists > 0; } } PK ��\w�� Rule/FolderPathExistsRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Form\Form; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla CMS. * * @since 4.0.0 */ class FolderPathExistsRule extends FilePathRule { /** * Method to test if the folder path is valid and points to an existing folder below the Joomla root * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid and points to an existing folder below the Joomla root, false otherwise. * * @since 4.0.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { if (!parent::test($element, $value, $group, $input, $form)) { return false; } // If the field is empty and not required so the previous test hasn't failed, the field is valid. if ($value === '' || $value === null) { return true; } // Spaces only would result in Joomla root which is not allowed if (!trim($value)) { return false; } $pathCleaned = rtrim(Path::clean(JPATH_ROOT . '/' . $value), \DIRECTORY_SEPARATOR); $rootCleaned = rtrim(Path::clean(JPATH_ROOT), \DIRECTORY_SEPARATOR); // JPATH_ROOT is not allowed if ($pathCleaned === $rootCleaned) { return false; } return Folder::exists($pathCleaned); } } PK ��\�}� � Rule/CaptchaRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Captcha\Captcha; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Framework. * * @since 2.5 */ class CaptchaRule extends FormRule { /** * Method to test if the Captcha is correct. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 2.5 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $app = Factory::getApplication(); $default = $app->get('captcha'); if ($app->isClient('site')) { $default = $app->getParams()->get('captcha', $default); } $plugin = $element['plugin'] ? (string) $element['plugin'] : $default; $namespace = $element['namespace'] ?: $form->getName(); // Use 0 for none if ($plugin === 0 || $plugin === '0') { return true; } try { $captcha = Captcha::getInstance((string) $plugin, ['namespace' => (string) $namespace]); return $captcha->checkAnswer($value); } catch (\RuntimeException $e) { $app->enqueueMessage($e->getMessage(), 'error'); } return false; } } PK ��\cN<�� � Rule/NumberRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 3.5 */ class NumberRule extends FormRule { /** * Method to test the range for a number value using min and max attributes. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.5 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Check if the field is required. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); // If the value is empty and the field is not required return True. if (($value === '' || $value === null) && ! $required) { return true; } $float_value = (float) $value; if (isset($element['min'])) { $min = (float) $element['min']; if ($min > $float_value) { return false; } } if (isset($element['max'])) { $max = (float) $element['max']; if ($max < $float_value) { return false; } } return true; } } PK ��\�]G� � Rule/UserIdRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Database\DatabaseAwareInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 4.0.0 */ class UserIdRule extends FormRule implements DatabaseAwareInterface { use DatabaseAwareTrait; /** * Method to test the validity of a Joomla User. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param ?string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 4.0.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Check if the field is required. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); // If the value is empty, null or has the value 0 and the field is not required return true else return false if (($value === '' || $value === null || (string) $value === '0')) { return !$required; } // Get the database object and a new query object. $db = $this->getDatabase(); $query = $db->getQuery(true); // Build the query. $query->select('COUNT(*)') ->from($db->quoteName('#__users')) ->where($db->quoteName('id') . ' = :userId') ->bind(':userId', $value, ParameterType::INTEGER); // Set and query the database. return (bool) $db->setQuery($query)->loadResult(); } } PK ��\�"}� � Rule/FilePathRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 3.9.21 */ class FilePathRule extends FormRule { /** * Method to test if the file path is valid * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 3.9.21 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $value = trim($value); // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required'); if (!$required && empty($value)) { return true; } // Get the exclude setting from the xml $exclude = (array) explode('|', (string) $element['exclude']); // Exclude current folder '.' to be safe from full path disclosure $exclude[] = '.'; // Check the exclude setting $path = preg_split('/[\/\\\\]/', $value); if (in_array(strtolower($path[0]), $exclude) || empty($path[0])) { return false; } // Prepend the root path $value = JPATH_ROOT . '/' . $value; // Check if $value is a valid path, which includes not allowing to break out of the current path try { Path::check($value); } catch (\Exception $e) { // When there is an exception in the check path this is not valid return false; } // When there are no exception this rule should pass. // See: https://github.com/joomla/joomla-cms/issues/30500#issuecomment-683290162 return true; } } PK ��\N`�_ _ Rule/TimeRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Rule; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 4.0.0 */ class TimeRule extends FormRule { /** * Method to test the range for a number value using min and max attributes. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 4.0.0 * * @throws \Exception */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null): bool { // Check if the field is required. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); // If the value is empty and the field is not required return True. if (($value === '' || $value === null) && !$required) { return true; } $stringValue = (string) $value; // If the length of a field is smaller than 5 return error message if (strlen($stringValue) !== 5 && !isset($element['step'])) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If the third symbol isn't a ':' return error message if ($stringValue[2] !== ':') { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If the are other symbols except of numbers and ':' return error message if (!preg_match('#^[0-9:]+$#', $stringValue)) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If min and max is set if (isset($element['min']) && isset($element['max'])) { $min = $element['min'][0] . $element['min'][1]; $max = $element['max'][0] . $element['max'][1]; // If the input is smaller than the set min return error message if (intval($min) > intval($stringValue[0] . $stringValue[1])) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_MIN_TIME', $min), 'warning' ); return false; } // If the input is greater than the set max return error message if (intval($max) < intval($stringValue[0] . $stringValue[1])) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_MAX_TIME'), 'warning' ); return false; } // If the hour input is equal to the set max but the minutes input is greater than zero return error message if (intval($max) === intval($stringValue[0] . $stringValue[1])) { if (intval($element['min'][3] . $element['min'][4]) !== 0) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_MAX_TIME'), 'warning' ); return false; } } } // If the first symbol is greater than 2 return error message if (intval($stringValue[0]) > 2) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If the first symbol is greater than 2 and the second symbol is greater than 3 return error message if (intval($stringValue[0]) === 2 && intval($stringValue[1]) > 3) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If the fourth symbol is greater than 5 return error message if (intval($stringValue[3]) > 5) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT'), 'warning' ); return false; } // If the step is set return same error messages as above but taking into a count that there 8 and not 5 symbols if (isset($element['step'])) { if ( strlen($stringValue) !== 8 || intval($stringValue[5]) !== ':' || intval($stringValue[6]) > 5 ) { Factory::getApplication()->enqueueMessage( Text::_('JLIB_FORM_FIELD_INVALID_TIME_INPUT_SECONDS'), 'warning' ); return false; } } return true; } } PK ��\��㙩 � Rule/EmailRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\CMS\Language\Text; use Joomla\CMS\String\PunycodeHelper; use Joomla\Database\DatabaseAwareInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class EmailRule extends FormRule implements DatabaseAwareInterface { use DatabaseAwareTrait; /** * The regular expression to use in testing a form field value. * * @var string * @since 1.7.0 * @link https://www.w3.org/TR/html/sec-forms.html#email-state-typeemail */ protected $regex = "^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])" . "?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"; /** * Method to test the email address and optionally check for uniqueness. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed Boolean true if field value is valid. * * @since 1.7.0 * @throws \UnexpectedValueException */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required'); if (!$required && empty($value)) { return true; } // If the tld attribute is present, change the regular expression to require at least 2 characters for it. $tld = ((string) $element['tld'] === 'tld' || (string) $element['tld'] === 'required'); if ($tld) { $this->regex = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])" . '?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$'; } // Determine if the multiple attribute is present $multiple = ((string) $element['multiple'] === 'true' || (string) $element['multiple'] === 'multiple'); if (!$multiple) { // Handle idn email addresses by converting to punycode. $value = PunycodeHelper::emailToPunycode($value); // Test the value against the regular expression. if (!parent::test($element, $value, $group, $input, $form)) { throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_VALID_MAIL')); } } else { $values = explode(',', $value); foreach ($values as $value) { // Handle idn email addresses by converting to punycode. $value = PunycodeHelper::emailToPunycode($value); // Test the value against the regular expression. if (!parent::test($element, $value, $group, $input, $form)) { throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_VALID_MAIL')); } } } /** * validDomains value should consist of component name and the name of domain list field in component's configuration, separated by a dot. * This allows different components and contexts to use different lists. * If value is incomplete, com_users.domains is used as fallback. */ $validDomains = (string) $element['validDomains'] !== '' && (string) $element['validDomains'] !== 'false'; if ($validDomains && !$multiple) { $config = explode('.', $element['validDomains'], 2); if (\count($config) > 1) { $domains = ComponentHelper::getParams($config[0])->get($config[1]); } else { $domains = ComponentHelper::getParams('com_users')->get('domains'); } if ($domains) { $emailDomain = explode('@', $value); $emailDomain = $emailDomain[1]; $emailParts = array_reverse(explode('.', $emailDomain)); $emailCount = \count($emailParts); $allowed = true; foreach ($domains as $domain) { $domainParts = array_reverse(explode('.', $domain->name)); $status = 0; // Don't run if the email has less segments than the rule. if ($emailCount < \count($domainParts)) { continue; } foreach ($emailParts as $key => $emailPart) { if (!isset($domainParts[$key]) || $domainParts[$key] == $emailPart || $domainParts[$key] == '*') { $status++; } } // All segments match, check whether to allow the domain or not. if ($status === $emailCount) { if ($domain->rule == 0) { $allowed = false; } else { $allowed = true; } } } // If domain is not allowed, fail validation. Otherwise continue. if (!$allowed) { throw new \UnexpectedValueException(Text::sprintf('JGLOBAL_EMAIL_DOMAIN_NOT_ALLOWED', $emailDomain)); } } } // Check if we should test for uniqueness. This only can be used if multiple is not true $unique = ((string) $element['unique'] === 'true' || (string) $element['unique'] === 'unique'); if ($unique && !$multiple) { // Get the database object and a new query object. $db = $this->getDatabase(); $query = $db->getQuery(true); // Get the extra field check attribute. $userId = ($form instanceof Form) ? (int) $form->getValue('id') : 0; // Build the query. $query->select('COUNT(*)') ->from($db->quoteName('#__users')) ->where( [ $db->quoteName('email') . ' = :email', $db->quoteName('id') . ' <> :userId', ] ) ->bind(':email', $value) ->bind(':userId', $userId, ParameterType::INTEGER); // Set and query the database. $db->setQuery($query); $duplicate = (bool) $db->loadResult(); if ($duplicate) { throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_EMAIL_INUSE')); } } return true; } } PK ��\Y:�~ ~ Rule/EqualsRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class EqualsRule extends FormRule { /** * Method to test if two values are equal. To use this rule, the form * XML needs a validate attribute of equals and a field attribute * that is equal to the field to test against. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 * @throws \InvalidArgumentException * @throws \UnexpectedValueException */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $field = (string) $element['field']; // Check that a validation field is set. if (!$field) { throw new \UnexpectedValueException(sprintf('$field empty in %s::test', \get_class($this))); } if (\is_null($form)) { throw new \InvalidArgumentException(sprintf('The value for $form must not be null in %s', \get_class($this))); } if (\is_null($input)) { throw new \InvalidArgumentException(sprintf('The value for $input must not be null in %s', \get_class($this))); } $test = $input->get($field); if (isset($group) && $group !== '') { $test = $input->get($group . '.' . $field); } // Test the two values against each other. return $value == $test; } } PK ��\�)a Rule/RulesRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Access\Access; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class RulesRule extends FormRule { /** * Method to test the value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Get the possible field actions and the ones posted to validate them. $fieldActions = self::getFieldActions($element); $valueActions = self::getValueActions($value); // Make sure that all posted actions are in the list of possible actions for the field. foreach ($valueActions as $action) { if (!\in_array($action, $fieldActions)) { return false; } } return true; } /** * Method to get the list of permission action names from the form field value. * * @param mixed $value The form field value to validate. * * @return string[] A list of permission action names from the form field value. * * @since 1.7.0 */ protected function getValueActions($value) { $actions = []; // Iterate over the asset actions and add to the actions. foreach ((array) $value as $name => $rules) { $actions[] = $name; } return $actions; } /** * Method to get the list of possible permission action names for the form field. * * @param \SimpleXMLElement $element The \SimpleXMLElement object representing the `<field>` tag for the form field object. * * @return string[] A list of permission action names from the form field element definition. * * @since 1.7.0 */ protected function getFieldActions(\SimpleXMLElement $element) { $actions = []; // Initialise some field attributes. $section = $element['section'] ? (string) $element['section'] : ''; $component = $element['component'] ? (string) $element['component'] : ''; // Get the asset actions for the element. $elActions = Access::getActionsFromFile( JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', "/access/section[@name='" . $section . "']/" ); if ($elActions) { // Iterate over the asset actions and add to the actions. foreach ($elActions as $item) { $actions[] = $item->name; } } // Iterate over the children and add to the actions. foreach ($element->children() as $el) { if ($el->getName() === 'action') { $actions[] = (string) $el['name']; } } return $actions; } } PK ��\�G�� � Rule/NotequalsRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormRule; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 1.7.0 */ class NotequalsRule extends FormRule { /** * Method to test if two values are not equal. To use this rule, the form * XML needs a validate attribute of equals and a field attribute * that is equal to the field to test against. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.7.0 * @throws \InvalidArgumentException * @throws \UnexpectedValueException */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { $field = (string) $element['field']; // Check that a validation field is set. if (!$field) { throw new \UnexpectedValueException(sprintf('$field empty in %s::test', \get_class($this))); } if ($input === null) { throw new \InvalidArgumentException(sprintf('The value for $input must not be null in %s', \get_class($this))); } // Test the two values against each other. if ($value != $input->get($field)) { return true; } return false; } } PK ��\��� � Rule/ModuleLayoutRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Rule; use Joomla\CMS\Form\FormRule; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Rule class for the Joomla Platform. * * @since 3.9.26 */ class ModuleLayoutRule extends FormRule { /** * The regular expression to use in testing a module layout field value. * * A valid module layout field value consists of * - optionally a template name with only characters, numbers, hyphens and * underscores, which can also be just "_" for layouts provided by the * module, followed by a colon. * - the base name of the layout file, not starting with a dot and with * only characters, numbers, dots and hyphens but no underscores (see * method "getInput" of the "ModuleLayout" field). * * @var string * @since 3.9.26 */ protected $regex = '^([A-Za-z0-9_-]+:)?[A-Za-z0-9-][A-Za-z0-9\.-]*$'; } PK ��\~*;>A >A FormHelper.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form; use Joomla\CMS\Filesystem\Path; use Joomla\String\Normalise; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form's helper class. * Provides a storage for filesystem's paths where Form's entities reside and methods for creating those entities. * Also stores objects with entities' prototypes for further reusing. * * @since 1.7.0 */ class FormHelper { /** * Array with paths where entities(field, rule, form) can be found. * * Array's structure: * * paths: * {ENTITY_NAME}: * - /path/1 * - /path/2 * * @var array[] * @since 1.7.0 */ protected static $paths; /** * The class namespaces. * * @var array[] * @since 3.8.0 */ protected static $prefixes = ['field' => [], 'form' => [], 'rule' => [], 'filter' => []]; /** * Static array of Form's entity objects for re-use. * Prototypes for all fields and rules are here. * * Array's structure: * entities: * {ENTITY_NAME}: * {KEY}: {OBJECT} * * @var array[] * @since 1.7.0 */ protected static $entities = ['field' => [], 'form' => [], 'rule' => [], 'filter' => []]; /** * Method to load a form field object given a type. * * @param string $type The field type. * @param boolean $new Flag to toggle whether we should get a new instance of the object. * * @return FormField|boolean FormField object on success, false otherwise. * * @since 1.7.0 */ public static function loadFieldType($type, $new = true) { return self::loadType('field', $type, $new); } /** * Method to load a form rule object given a type. * * @param string $type The rule type. * @param boolean $new Flag to toggle whether we should get a new instance of the object. * * @return FormRule|boolean FormRule object on success, false otherwise. * * @since 1.7.0 */ public static function loadRuleType($type, $new = true) { return self::loadType('rule', $type, $new); } /** * Method to load a form filter object given a type. * * @param string $type The rule type. * @param boolean $new Flag to toggle whether we should get a new instance of the object. * * @return FormFilterInterface|boolean FormRule object on success, false otherwise. * * @since 4.0.0 */ public static function loadFilterType($type, $new = true) { return self::loadType('filter', $type, $new); } /** * Method to load a form entity object given a type. * Each type is loaded only once and then used as a prototype for other objects of same type. * Please, use this method only with those entities which support types (forms don't support them). * * @param string $entity The entity. * @param string $type The entity type. * @param boolean $new Flag to toggle whether we should get a new instance of the object. * * @return mixed Entity object on success, false otherwise. * * @since 1.7.0 */ protected static function loadType($entity, $type, $new = true) { // Reference to an array with current entity's type instances $types = &self::$entities[$entity]; $key = md5($type); // Return an entity object if it already exists and we don't need a new one. if (isset($types[$key]) && $new === false) { return $types[$key]; } $class = self::loadClass($entity, $type); if ($class === false) { return false; } // Instantiate a new type object. $types[$key] = new $class(); return $types[$key]; } /** * Attempt to import the FormField class file if it isn't already imported. * You can use this method outside of Form for loading a field for inheritance or composition. * * @param string $type Type of a field whose class should be loaded. * * @return string|boolean Class name on success or false otherwise. * * @since 1.7.0 */ public static function loadFieldClass($type) { return self::loadClass('field', $type); } /** * Attempt to import the FormRule class file if it isn't already imported. * You can use this method outside of Form for loading a rule for inheritance or composition. * * @param string $type Type of a rule whose class should be loaded. * * @return string|boolean Class name on success or false otherwise. * * @since 1.7.0 */ public static function loadRuleClass($type) { return self::loadClass('rule', $type); } /** * Attempt to import the FormFilter class file if it isn't already imported. * You can use this method outside of Form for loading a filter for inheritance or composition. * * @param string $type Type of a filter whose class should be loaded. * * @return string|boolean Class name on success or false otherwise. * * @since 4.0.0 */ public static function loadFilterClass($type) { return self::loadClass('filter', $type); } /** * Load a class for one of the form's entities of a particular type. * Currently, it makes sense to use this method for the "field" and "rule" entities * (but you can support more entities in your subclass). * * @param string $entity One of the form entities (field or rule). * @param string $type Type of an entity. * * @return string|boolean Class name on success or false otherwise. * * @since 1.7.0 */ protected static function loadClass($entity, $type) { // Check if there is a class in the registered namespaces foreach (self::addPrefix($entity) as $prefix) { // Treat underscores as namespace $name = Normalise::toSpaceSeparated($type); $name = str_ireplace(' ', '\\', ucwords($name)); $subPrefix = ''; if (strpos($name, '.')) { list($subPrefix, $name) = explode('.', $name); $subPrefix = ucfirst($subPrefix) . '\\'; } // Compile the classname $class = rtrim($prefix, '\\') . '\\' . $subPrefix . ucfirst($name) . ucfirst($entity); // Check if the class exists if (class_exists($class)) { return $class; } } $prefix = 'J'; if (strpos($type, '.')) { list($prefix, $type) = explode('.', $type); } $class = StringHelper::ucfirst($prefix, '_') . 'Form' . StringHelper::ucfirst($entity, '_') . StringHelper::ucfirst($type, '_'); if (class_exists($class)) { return $class; } // Get the field search path array. $paths = self::addPath($entity); // If the type is complex, add the base type to the paths. if ($pos = strpos($type, '_')) { // Add the complex type prefix to the paths. for ($i = 0, $n = \count($paths); $i < $n; $i++) { // Derive the new path. $path = $paths[$i] . '/' . strtolower(substr($type, 0, $pos)); // If the path does not exist, add it. if (!\in_array($path, $paths)) { $paths[] = $path; } } // Break off the end of the complex type. $type = substr($type, $pos + 1); } // Try to find the class file. $type = strtolower($type) . '.php'; foreach ($paths as $path) { $file = Path::find($path, $type); if (!$file) { continue; } require_once $file; if (class_exists($class)) { break; } } // Check for all if the class exists. return class_exists($class) ? $class : false; } /** * Method to add a path to the list of field include paths. * * @param string|string[] $new A path or array of paths to add. * * @return string[] The list of paths that have been added. * * @since 1.7.0 */ public static function addFieldPath($new = null) { return self::addPath('field', $new); } /** * Method to add a path to the list of form include paths. * * @param string|string[] $new A path or array of paths to add. * * @return string[] The list of paths that have been added. * * @since 1.7.0 */ public static function addFormPath($new = null) { return self::addPath('form', $new); } /** * Method to add a path to the list of rule include paths. * * @param string|string[] $new A path or array of paths to add. * * @return string[] The list of paths that have been added. * * @since 1.7.0 */ public static function addRulePath($new = null) { return self::addPath('rule', $new); } /** * Method to add a path to the list of filter include paths. * * @param string|string[] $new A path or array of paths to add. * * @return string[] The list of paths that have been added. * * @since 4.0.0 */ public static function addFilterPath($new = null) { return self::addPath('filter', $new); } /** * Method to add a path to the list of include paths for one of the form's entities. * Currently supported entities: field, rule and form. You are free to support your own in a subclass. * * @param string $entity Form's entity name for which paths will be added. * @param string|string[] $new A path or array of paths to add. * * @return string[] The list of paths that have been added. * * @since 1.7.0 */ protected static function addPath($entity, $new = null) { if (!isset(self::$paths[$entity])) { self::$paths[$entity] = []; } // Reference to an array with paths for current entity $paths = &self::$paths[$entity]; // Force the new path(s) to an array. settype($new, 'array'); // Add the new paths to the stack if not already there. foreach ($new as $path) { $path = \trim($path); if (!\in_array($path, $paths)) { \array_unshift($paths, $path); } } return $paths; } /** * Method to add a namespace prefix to the list of field lookups. * * @param string|string[] $new A namespaces or array of namespaces to add. * * @return string[] The list of namespaces that have been added. * * @since 3.8.0 */ public static function addFieldPrefix($new = null) { return self::addPrefix('field', $new); } /** * Method to add a namespace to the list of form lookups. * * @param string|string[] $new A namespace or array of namespaces to add. * * @return string[] The list of namespaces that have been added. * * @since 3.8.0 */ public static function addFormPrefix($new = null) { return self::addPrefix('form', $new); } /** * Method to add a namespace to the list of rule lookups. * * @param string|string[] $new A namespace or array of namespaces to add. * * @return string[] The list of namespaces that have been added. * * @since 3.8.0 */ public static function addRulePrefix($new = null) { return self::addPrefix('rule', $new); } /** * Method to add a namespace to the list of filter lookups. * * @param string|string[] $new A namespace or array of namespaces to add. * * @return string[] The list of namespaces that have been added. * * @since 4.0.0 */ public static function addFilterPrefix($new = null) { return self::addPrefix('filter', $new); } /** * Method to add a namespace to the list of namespaces for one of the form's entities. * Currently supported entities: field, rule and form. You are free to support your own in a subclass. * * @param string $entity Form's entity name for which paths will be added. * @param string|string[] $new A namespace or array of namespaces to add. * * @return string[] The list of namespaces that have been added. * * @since 3.8.0 */ protected static function addPrefix($entity, $new = null) { // Reference to an array with namespaces for current entity $prefixes = &self::$prefixes[$entity]; // Add the default entity's search namespace if not set. if (empty($prefixes)) { $prefixes[] = __NAMESPACE__ . '\\' . ucfirst($entity); } // Force the new namespace(s) to an array. settype($new, 'array'); // Add the new paths to the stack if not already there. foreach ($new as $prefix) { $prefix = trim($prefix); if (\in_array($prefix, $prefixes)) { continue; } array_unshift($prefixes, $prefix); } return $prefixes; } /** * Parse the show on conditions * * @param string $showOn Show on conditions. * @param string $formControl Form name. * @param string $group The dot-separated form group path. * * @return array[] Array with show on conditions. * * @since 3.7.0 */ public static function parseShowOnConditions($showOn, $formControl = null, $group = null) { // Process the showon data. if (!$showOn) { return []; } $formPath = $formControl ?: ''; if ($group) { $groups = explode('.', $group); // An empty formControl leads to invalid shown property // Use the 1st part of the group instead to avoid. if (empty($formPath) && isset($groups[0])) { $formPath = $groups[0]; array_shift($groups); } foreach ($groups as $group) { $formPath .= '[' . $group . ']'; } } $showOnData = []; $showOnParts = preg_split('#(\[AND\]|\[OR\])#', $showOn, -1, PREG_SPLIT_DELIM_CAPTURE); $op = ''; foreach ($showOnParts as $showOnPart) { if (($showOnPart === '[AND]') || $showOnPart === '[OR]') { $op = trim($showOnPart, '[]'); continue; } $compareEqual = strpos($showOnPart, '!:') === false; $showOnPartBlocks = explode(($compareEqual ? ':' : '!:'), $showOnPart, 2); $dotPos = strpos($showOnPartBlocks[0], '.'); if ($dotPos === false) { $field = $formPath ? $formPath . '[' . $showOnPartBlocks[0] . ']' : $showOnPartBlocks[0]; } else { if ($dotPos === 0) { $fieldName = substr($showOnPartBlocks[0], 1); $field = $formControl ? $formControl . '[' . $fieldName . ']' : $fieldName; } else { if ($formControl) { $field = $formControl . ('[' . str_replace('.', '][', $showOnPartBlocks[0]) . ']'); } else { $groupParts = explode('.', $showOnPartBlocks[0]); $field = array_shift($groupParts) . '[' . join('][', $groupParts) . ']'; } } } $showOnData[] = [ 'field' => $field, 'values' => explode(',', $showOnPartBlocks[1]), 'sign' => $compareEqual === true ? '=' : '!=', 'op' => $op, ]; if ($op !== '') { $op = ''; } } return $showOnData; } } PK ��\FA� � FormFilterInterface.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface for a filter class. * * @since 4.0.0 */ interface FormFilterInterface { /** * Method to filter a field value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return mixed The filtered value. * * @since 4.0.0 */ public function filter(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null); } PK ��\B[�f� � FormFactory.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form; use Joomla\Database\DatabaseAwareTrait; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Default factory for creating Form objects * * @since 4.0.0 */ class FormFactory implements FormFactoryInterface { use DatabaseAwareTrait; /** * Method to get an instance of a form. * * @param string $name The name of the form. * @param array $options An array of form options. * * @return Form * * @since 4.0.0 */ public function createForm(string $name, array $options = []): Form { $form = new Form($name, $options); $form->setDatabase($this->getDatabase()); return $form; } } PK ��\P�<� � FormRule.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt * * Remove phpcs exception with deprecated constant JCOMPAT_UNICODE_PROPERTIES * @phpcs:disable PSR1.Files.SideEffects */ namespace Joomla\CMS\Form; \defined('JPATH_PLATFORM') or die; use Joomla\Registry\Registry; // Detect if we have full UTF-8 and unicode PCRE support. if (!\defined('JCOMPAT_UNICODE_PROPERTIES')) { /** * Flag indicating UTF-8 and PCRE support is present * * @const boolean * @since 1.6 * * @deprecated 4.0 will be removed in 6.0 * Will be removed without replacement (Also remove phpcs exception) */ \define('JCOMPAT_UNICODE_PROPERTIES', (bool) @preg_match('/\pL/u', 'a')); } /** * Form Rule class for the Joomla Platform. * * @since 1.6 */ class FormRule { /** * The regular expression to use in testing a form field value. * * @var string * @since 1.6 */ protected $regex; /** * The regular expression modifiers to use when testing a form field value. * * @var string * @since 1.6 */ protected $modifiers = ''; /** * Method to test the value. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. * @param ?Form $form The form object for which the field is being tested. * * @return boolean True if the value is valid, false otherwise. * * @since 1.6 * @throws \UnexpectedValueException if rule is invalid. */ public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null) { // Check for a valid regex. if (empty($this->regex)) { throw new \UnexpectedValueException(sprintf('%s has invalid regex.', \get_class($this))); } // Detect if we have full UTF-8 and unicode PCRE support. static $unicodePropertiesSupport = null; if ($unicodePropertiesSupport === null) { $unicodePropertiesSupport = (bool) @\preg_match('/\pL/u', 'a'); } // Add unicode property support if available. if ($unicodePropertiesSupport) { $this->modifiers = (strpos($this->modifiers, 'u') !== false) ? $this->modifiers : $this->modifiers . 'u'; } // Test the value against the regular expression. if (preg_match(\chr(1) . $this->regex . \chr(1) . $this->modifiers, $value)) { return true; } return false; } } PK ��\?%�� FormFactoryAwareInterface.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface to be implemented by classes depending on a form factory. * * @since 4.0.0 */ interface FormFactoryAwareInterface { /** * Set the form factory to use. * * @param FormFactoryInterface $factory The form factory to use. * * @return FormFactoryAwareInterface This method is chainable. * * @since 4.0.0 */ public function setFormFactory(FormFactoryInterface $factory); } PK ��\H��T 5 5 Field/SubformField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormField; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * The Field to load the form inside current form * * @Example with all attributes: * <field name="field-name" type="subform" * formsource="path/to/form.xml" min="1" max="3" multiple="true" buttons="add,remove,move" * layout="joomla.form.field.subform.repeatable-table" groupByFieldset="false" component="com_example" client="site" * label="Field Label" description="Field Description" /> * * @since 3.6 */ class SubformField extends FormField { /** * The form field type. * @var string */ protected $type = 'Subform'; /** * Form source * @var string */ protected $formsource; /** * Minimum items in repeat mode * @var integer */ protected $min = 0; /** * Maximum items in repeat mode * @var integer */ protected $max = 1000; /** * Layout to render the form * @var string */ protected $layout = 'joomla.form.field.subform.default'; /** * Whether group subform fields by it`s fieldset * @var boolean */ protected $groupByFieldset = false; /** * Which buttons to show in multiple mode * @var boolean[] $buttons */ protected $buttons = ['add' => true, 'remove' => true, 'move' => true]; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.6 */ public function __get($name) { switch ($name) { case 'formsource': case 'min': case 'max': case 'layout': case 'groupByFieldset': case 'buttons': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.6 */ public function __set($name, $value) { switch ($name) { case 'formsource': $this->formsource = (string) $value; // Add root path if we have a path to XML file if (strrpos($this->formsource, '.xml') === \strlen($this->formsource) - 4) { $this->formsource = Path::clean(JPATH_ROOT . '/' . $this->formsource); } break; case 'min': $this->min = (int) $value; break; case 'max': if ($value) { $this->max = max(1, (int) $value); } break; case 'groupByFieldset': if ($value !== null) { $value = (string) $value; $this->groupByFieldset = !($value === 'false' || $value === 'off' || $value === '0'); } break; case 'layout': $this->layout = (string) $value; // Make sure the layout is not empty. if (!$this->layout) { // Set default value depend from "multiple" mode $this->layout = !$this->multiple ? 'joomla.form.field.subform.default' : 'joomla.form.field.subform.repeatable'; } break; case 'buttons': if (!$this->multiple) { $this->buttons = []; break; } if ($value && !\is_array($value)) { $value = explode(',', (string) $value); $value = array_fill_keys(array_filter($value), true); } if ($value) { $value = array_merge(['add' => false, 'remove' => false, 'move' => false], $value); $this->buttons = $value; } break; case 'value': // We allow a json encoded string or an array if (is_string($value)) { $value = json_decode($value, true); } $this->value = $value !== null ? (array) $value : null; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. * * @return boolean True on success. * * @since 3.6 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { if (!parent::setup($element, $value, $group)) { return false; } foreach (['formsource', 'min', 'max', 'layout', 'groupByFieldset', 'buttons'] as $attributeName) { $this->__set($attributeName, $element[$attributeName]); } if ((string) $element['fieldname']) { $this->__set('fieldname', $element['fieldname']); } if ($this->value && \is_string($this->value)) { // Guess here is the JSON string from 'default' attribute $this->value = json_decode($this->value, true); } if (!$this->formsource && $element->form) { // Set the formsource parameter from the content of the node $this->formsource = $element->form->saveXML(); } return true; } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 3.6 */ protected function getInput() { // Prepare data for renderer $data = $this->getLayoutData(); $tmpl = null; $control = $this->name; try { $tmpl = $this->loadSubForm(); $forms = $this->loadSubFormData($tmpl); } catch (\Exception $e) { return $e->getMessage(); } $data['tmpl'] = $tmpl; $data['forms'] = $forms; $data['min'] = $this->min; $data['max'] = $this->max; $data['control'] = $control; $data['buttons'] = $this->buttons; $data['fieldname'] = $this->fieldname; $data['fieldId'] = $this->id; $data['groupByFieldset'] = $this->groupByFieldset; /** * For each rendering process of a subform element, we want to have a * separate unique subform id present to could distinguish the eventhandlers * regarding adding/moving/removing rows from nested subforms from their parents. */ static $unique_subform_id = 0; $data['unique_subform_id'] = ('sr-' . ($unique_subform_id++)); // Prepare renderer $renderer = $this->getRenderer($this->layout); // Allow to define some Layout options as attribute of the element if ($this->element['component']) { $renderer->setComponent((string) $this->element['component']); } if ($this->element['client']) { $renderer->setClient((string) $this->element['client']); } // Render $html = $renderer->render($data); // Add hidden input on front of the subform inputs, in multiple mode // for allow to submit an empty value if ($this->multiple) { $html = '<input name="' . $this->name . '" type="hidden" value="">' . $html; } return $html; } /** * Method to get the name used for the field input tag. * * @param string $fieldName The field element name. * * @return string The name to be used for the field input tag. * * @since 3.6 */ protected function getName($fieldName) { $name = ''; // If there is a form control set for the attached form add it first. if ($this->formControl) { $name .= $this->formControl; } // If the field is in a group add the group control to the field name. if ($this->group) { // If we already have a name segment add the group control as another level. $groups = explode('.', $this->group); if ($name) { foreach ($groups as $group) { $name .= '[' . $group . ']'; } } else { $name .= array_shift($groups); foreach ($groups as $group) { $name .= '[' . $group . ']'; } } } // If we already have a name segment add the field name as another level. if ($name) { $name .= '[' . $fieldName . ']'; } else { $name .= $fieldName; } return $name; } /** * Loads the form instance for the subform. * * @return Form The form instance. * * @throws \InvalidArgumentException if no form provided. * @throws \RuntimeException if the form could not be loaded. * * @since 3.9.7 */ public function loadSubForm() { $control = $this->name; if ($this->multiple) { $control .= '[' . $this->fieldname . 'X]'; } // Prepare the form template $formname = 'subform.' . str_replace(['jform[', '[', ']'], ['', '.', ''], $this->name); $tmpl = Form::getInstance($formname, $this->formsource, ['control' => $control]); return $tmpl; } /** * Binds given data to the subform and its elements. * * @param Form $subForm Form instance of the subform. * * @return Form[] Array of Form instances for the rows. * * @since 3.9.7 */ protected function loadSubFormData(Form $subForm) { $value = $this->value ? (array) $this->value : []; // Simple form, just bind the data and return one row. if (!$this->multiple) { $subForm->bind($value); return [$subForm]; } // Multiple rows possible: Construct array and bind values to their respective forms. $forms = []; $value = array_values($value); // Show as many rows as we have values, but at least min and at most max. $c = max($this->min, min(\count($value), $this->max)); for ($i = 0; $i < $c; $i++) { $control = $this->name . '[' . $this->fieldname . $i . ']'; $itemForm = Form::getInstance($subForm->getName() . $i, $this->formsource, ['control' => $control]); if (!empty($value[$i])) { $itemForm->bind($value[$i]); } $forms[] = $itemForm; } return $forms; } /** * Method to filter a field value. * * @param mixed $value The optional value to use as the default for the field. * @param string $group The optional dot-separated form group path on which to find the field. * @param ?Registry $input An optional Registry object with the entire data set to filter * against the entire form. * * @return mixed The filtered value. * * @since 4.0.0 * @throws \UnexpectedValueException */ public function filter($value, $group = null, Registry $input = null) { // Make sure there is a valid SimpleXMLElement. if (!($this->element instanceof \SimpleXMLElement)) { throw new \UnexpectedValueException(sprintf('%s::filter `element` is not an instance of SimpleXMLElement', \get_class($this))); } // Get the field filter type. $filter = (string) $this->element['filter']; if ($filter !== '') { return parent::filter($value, $group, $input); } // Dirty way of ensuring required fields in subforms are submitted and filtered the way other fields are $subForm = $this->loadSubForm(); // Subform field may have a default value, that is a JSON string if ($value && is_string($value)) { $value = json_decode($value, true); // The string is invalid json if (!$value) { return null; } } if ($this->multiple) { $return = []; if ($value) { foreach ($value as $key => $val) { $return[$key] = $subForm->filter($val); } } } else { $return = $subForm->filter($value); } return $return; } } PK ��\5�N]0 0 Field/MeterField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Form\FormField; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Provides a meter to show value in a range. * * @link https://html.spec.whatwg.org/multipage/input.html#text-(type=text)-state-and-search-state-(type=search) * @since 3.2 */ class MeterField extends FormField { /** * The form field type. * * @var string * @since 3.2 */ protected $type = 'Meter'; /** * Whether the field is active or not. * * @var boolean * @since 3.2 */ protected $active = false; /** * Whether the field is animated or not. * * @var boolean * @since 3.2 */ protected $animated = true; /** * The min value of the progress bar * * @var int * @since 4.4.0 */ protected $min = 0; /** * The max value of the progress bar * * @var int * @since 4.0.0 */ protected $max = 100; /** * The width of the progress bar * * @var string * @since 4.4.0 */ protected $width; /** * The color of the progress bar * * @var string * @since 4.4.0 */ protected $color; /** * The striped class for the progress bar * * @var boolean * @since 4.0.0 */ protected $striped; /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.meter'; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { switch ($name) { case 'active': case 'width': case 'animated': case 'color': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'max': case 'min': $this->$name = (int) $value; break; case 'width': case 'color': $this->$name = (string) $value; break; case 'active': $value = (string) $value; $this->active = ($value === 'true' || $value === $name || $value === '1'); break; case 'animated': $value = (string) $value; $this->animated = !($value === 'false' || $value === 'off' || $value === '0'); break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 3.2 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { $this->width = isset($this->element['width']) ? (string) $this->element['width'] : ''; $this->color = isset($this->element['color']) ? (string) $this->element['color'] : ''; $active = (string) $this->element['active']; $this->active = ($active === 'true' || $active === 'on' || $active === '1'); $animated = (string) $this->element['animated']; $this->animated = !($animated === 'false' || $animated === 'off' || $animated === '0'); } return $return; } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 3.2 */ protected function getInput() { // Trim the trailing line in the layout file return rtrim($this->getRenderer($this->layout)->render($this->getLayoutData()), PHP_EOL); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.5 */ protected function getLayoutData() { $data = parent::getLayoutData(); // Initialize some field attributes. $extraData = [ 'width' => $this->width, 'color' => $this->color, 'animated' => $this->animated, 'active' => $this->active, 'max' => $this->max, 'min' => $this->min, ]; return array_merge($data, $extraData); } } PK ��\U�J�� � Field/ModulepositionField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Module Position field. * * @since 1.6 */ class ModulepositionField extends TextField { /** * The form field type. * * @var string * @since 1.6 */ protected $type = 'ModulePosition'; /** * The client ID. * * @var integer * @since 3.2 */ protected $clientId; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { if ($name === 'clientId') { return $this->clientId; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'clientId': $this->clientId = (int) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 3.2 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $result = parent::setup($element, $value, $group); if ($result === true) { // Get the client id. $clientId = $this->element['client_id']; if (!isset($clientId)) { $clientName = $this->element['client']; if (isset($clientName)) { $client = ApplicationHelper::getClientInfo($clientName, true); $clientId = $client->id; } } if (!isset($clientId) && $this->form instanceof Form) { $clientId = $this->form->getValue('client_id'); } $this->clientId = (int) $clientId; } return $result; } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 1.6 */ protected function getInput() { // Build the script. $script = []; $script[] = ' function jSelectPosition_' . $this->id . '(name) {'; $script[] = ' document.getElementById("' . $this->id . '").value = name;'; $script[] = ' jModalClose();'; $script[] = ' }'; // Add the script to the document head. Factory::getDocument()->addScriptDeclaration(implode("\n", $script)); // Setup variables for display. $html = []; $link = 'index.php?option=com_modules&view=positions&layout=modal&tmpl=component&function=jSelectPosition_' . $this->id . '&client_id=' . $this->clientId; // The current user display field. $html[] = '<div class="input-append">'; $html[] = parent::getInput() . '<a class="btn" title="' . Text::_('COM_MODULES_CHANGE_POSITION_TITLE') . '" href="' . $link . '" data-bs-toggle="modal" data-bs-target="#modulePositionModal">' . Text::_('COM_MODULES_CHANGE_POSITION_BUTTON') . '</a>'; $html[] = HTMLHelper::_( 'bootstrap.renderModal', 'modulePositionModal', [ 'url' => $link, 'title' => Text::_('COM_MODULES_CHANGE_POSITION_BUTTON'), 'height' => '100%', 'width' => '100%', 'modalWidth' => '800', 'bodyHeight' => '450', 'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-hidden="true">' . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>', ] ); $html[] = '</div>'; return implode("\n", $html); } } PK ��\�=� Field/ContentlanguageField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\HTML\HTMLHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides a list of content languages * * @see \Joomla\CMS\Form\Field\LanguageField for a select list of application languages. * @since 1.6 */ class ContentlanguageField extends ListField { /** * The form field type. * * @var string * @since 1.6 */ public $type = 'ContentLanguage'; /** * Method to get the field options for content languages. * * @return object[] The options the field is going to show. * * @since 1.6 */ protected function getOptions() { return array_merge(parent::getOptions(), HTMLHelper::_('contentlanguage.existing')); } } PK ��\�k!W�4 �4 Field/MediaField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Form\FormField; use Joomla\CMS\Helper\MediaHelper; use Joomla\CMS\Uri\Uri; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides a modal media selector including upload mechanism * * @since 1.6 */ class MediaField extends FormField { /** * The form field type. * * @var string * @since 1.6 */ protected $type = 'Media'; /** * The authorField. * * @var string * @since 3.2 */ protected $authorField; /** * The asset. * * @var string * @since 3.2 */ protected $asset; /** * The link. * * @var string * @since 3.2 */ protected $link; /** * Modal width. * * @var integer * @since 3.4.5 */ protected $width; /** * Modal height. * * @var integer * @since 3.4.5 */ protected $height; /** * The preview. * * @var string * @since 3.2 */ protected $preview; /** * The directory. * * @var string * @since 3.2 */ protected $directory; /** * The previewWidth. * * @var integer * @since 3.2 */ protected $previewWidth; /** * The previewHeight. * * @var integer * @since 3.2 */ protected $previewHeight; /** * The folder. * * @var string * @since 4.3.0 */ protected $folder; /** * Comma separated types of files for Media Manager * Possible values: images,audios,videos,documents * * @var string * @since 4.0.0 */ protected $types; /** * Layout to render * * @var string * @since 3.5 */ protected $layout = 'joomla.form.field.media'; /** * The parent class of the field * * @var string * @since 4.0.0 */ protected $parentclass; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { switch ($name) { case 'authorField': case 'asset': case 'link': case 'width': case 'height': case 'preview': case 'directory': case 'previewWidth': case 'previewHeight': case 'folder': case 'types': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'authorField': case 'asset': case 'link': case 'preview': case 'directory': case 'folder': case 'types': $this->$name = (string) $value; break; case 'height': case 'previewWidth': case 'previewHeight': case 'width': $this->$name = (int) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 3.2 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $result = parent::setup($element, $value, $group); if ($result === true) { $assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; $this->authorField = $this->element['created_by_field'] ? (string) $this->element['created_by_field'] : 'created_by'; $this->asset = $this->form->getValue($assetField) ?: (string) $this->element['asset_id']; $this->link = (string) $this->element['link']; $this->width = isset($this->element['width']) ? (int) $this->element['width'] : 800; $this->height = isset($this->element['height']) ? (int) $this->element['height'] : 500; $this->preview = (string) $this->element['preview']; $this->directory = (string) $this->element['directory']; $this->previewWidth = isset($this->element['preview_width']) ? (int) $this->element['preview_width'] : 200; $this->previewHeight = isset($this->element['preview_height']) ? (int) $this->element['preview_height'] : 200; $this->types = isset($this->element['types']) ? (string) $this->element['types'] : 'images'; } return $result; } /** * Method to get the field input markup for a media selector. * Use attributes to identify specific created_by and asset_id fields * * @return string The field input markup. * * @since 1.6 */ protected function getInput() { if (empty($this->layout)) { throw new \UnexpectedValueException(sprintf('%s has no layout assigned.', $this->name)); } return $this->getRenderer($this->layout)->render($this->getLayoutData()); } /** * Get the data that is going to be passed to the layout * * @return array */ public function getLayoutData() { // Get the basic field data $data = parent::getLayoutData(); $asset = $this->asset; if ($asset === '') { $asset = Factory::getApplication()->getInput()->get('option'); } // Value in new format such as images/headers/blue-flower.jpg#joomlaImage://local-images/headers/blue-flower.jpg?width=700&height=180 if ($this->value && strpos($this->value, '#') !== false) { $uri = new Uri(explode('#', $this->value)[1]); $adapter = $uri->getHost(); $path = $uri->getPath(); // Remove filename from stored path to get the path to the folder which file is stored $pos = strrpos($path, '/'); if ($pos !== false) { $path = substr($path, 0, $pos); } if ($path === '') { $path = '/'; } $this->folder = $adapter . ':' . $path; } elseif ($this->value && is_file(JPATH_ROOT . '/' . $this->value)) { /** * Local image, for example images/sampledata/cassiopeia/nasa2-640.jpg. We need to validate and make sure * the top level folder is one of the directories configured in the filesystem local plugin to avoid an error * message being displayed when users click on Select button to select a new image. */ $paths = explode('/', Path::clean($this->value, '/')); // Remove filename from $paths array array_pop($paths); if (MediaHelper::isValidLocalDirectory($paths[0])) { $adapterName = array_shift($paths); $this->folder = 'local-' . $adapterName . ':/' . implode('/', $paths); } } elseif ($this->directory && is_dir(JPATH_ROOT . '/' . ComponentHelper::getParams('com_media')->get('image_path', 'images') . '/' . $this->directory)) { /** * This is the case where a folder is configured in directory attribute of the form field. The directory needs * to be a relative folder of the folder configured in Path to Images Folder config option of Media component. * Same with an already stored local image above, we need to validate and make sure the top level folder is one of the * directories configured in the filesystem local plugin. */ $path = ComponentHelper::getParams('com_media')->get('image_path', 'images') . '/' . $this->directory; $paths = explode('/', Path::clean($path, '/')); if (MediaHelper::isValidLocalDirectory($paths[0])) { $adapterName = array_shift($paths); $this->folder = 'local-' . $adapterName . ':/' . implode('/', $paths); } } elseif ($this->directory && strpos($this->directory, ':')) { /** * Directory contains adapter information and path, for example via programming or directly defined in xml * via directory attribute */ $this->folder = $this->directory; } else { $this->folder = ''; } $mediaTypes = array_map('trim', explode(',', $this->types)); $types = []; $imagesExt = array_map( 'trim', explode( ',', ComponentHelper::getParams('com_media')->get( 'image_extensions', 'bmp,gif,jpg,jpeg,png,webp' ) ) ); $audiosExt = array_map( 'trim', explode( ',', ComponentHelper::getParams('com_media')->get( 'audio_extensions', 'mp3,m4a,mp4a,ogg' ) ) ); $videosExt = array_map( 'trim', explode( ',', ComponentHelper::getParams('com_media')->get( 'video_extensions', 'mp4,mp4v,mpeg,mov,webm' ) ) ); $documentsExt = array_map( 'trim', explode( ',', ComponentHelper::getParams('com_media')->get( 'doc_extensions', 'doc,odg,odp,ods,odt,pdf,ppt,txt,xcf,xls,csv' ) ) ); $imagesAllowedExt = []; $audiosAllowedExt = []; $videosAllowedExt = []; $documentsAllowedExt = []; // Cleanup the media types array_map( function ($mediaType) use (&$types, &$imagesAllowedExt, &$audiosAllowedExt, &$videosAllowedExt, &$documentsAllowedExt, $imagesExt, $audiosExt, $videosExt, $documentsExt) { switch ($mediaType) { case 'images': $types[] = '0'; $imagesAllowedExt = $imagesExt; break; case 'audios': $types[] = '1'; $audiosAllowedExt = $audiosExt; break; case 'videos': $types[] = '2'; $videosAllowedExt = $videosExt; break; case 'documents': $types[] = '3'; $documentsAllowedExt = $documentsExt; break; default: break; } }, $mediaTypes ); sort($types); $extraData = [ 'asset' => $asset, 'authorField' => $this->authorField, 'authorId' => $this->form->getValue($this->authorField), 'folder' => $this->folder, 'link' => $this->link, 'preview' => $this->preview, 'previewHeight' => $this->previewHeight, 'previewWidth' => $this->previewWidth, 'mediaTypes' => implode(',', $types), 'imagesExt' => $imagesExt, 'audiosExt' => $audiosExt, 'videosExt' => $videosExt, 'documentsExt' => $documentsExt, 'imagesAllowedExt' => $imagesAllowedExt, 'audiosAllowedExt' => $audiosAllowedExt, 'videosAllowedExt' => $videosAllowedExt, 'documentsAllowedExt' => $documentsAllowedExt, ]; return array_merge($data, $extraData); } } PK ��\��Jm m Field/ModulelayoutField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormField; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Database\ParameterType; use Joomla\Filesystem\Folder; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field to display a list of the layouts for module display from the module or template overrides. * * @since 1.6 */ class ModulelayoutField extends FormField { /** * The form field type. * * @var string * @since 1.6 */ protected $type = 'ModuleLayout'; /** * Method to get the field input for module layouts. * * @return string The field input. * * @since 1.6 */ protected function getInput() { // Get the client id. $clientId = $this->element['client_id']; if ($clientId === null && $this->form instanceof Form) { $clientId = $this->form->getValue('client_id'); } $clientId = (int) $clientId; $client = ApplicationHelper::getClientInfo($clientId); // Get the module. $module = (string) $this->element['module']; if (empty($module) && ($this->form instanceof Form)) { $module = $this->form->getValue('module'); } $module = preg_replace('#\W#', '', $module); // Get the template. $template = (string) $this->element['template']; $template = preg_replace('#\W#', '', $template); // Get the style. $template_style_id = 0; if ($this->form instanceof Form) { $template_style_id = $this->form->getValue('template_style_id', null, 0); $template_style_id = (int) preg_replace('#\W#', '', $template_style_id); } // If an extension and view are present build the options. if ($module && $client) { // Load language file $lang = Factory::getLanguage(); $lang->load($module . '.sys', $client->path) || $lang->load($module . '.sys', $client->path . '/modules/' . $module); // Get the database object and a new query object. $db = $this->getDatabase(); $query = $db->getQuery(true); // Build the query. $query->select( [ $db->quoteName('element'), $db->quoteName('name'), ] ) ->from($db->quoteName('#__extensions', 'e')) ->where( [ $db->quoteName('e.client_id') . ' = :clientId', $db->quoteName('e.type') . ' = ' . $db->quote('template'), $db->quoteName('e.enabled') . ' = 1', ] ) ->bind(':clientId', $clientId, ParameterType::INTEGER); if ($template) { $query->where($db->quoteName('e.element') . ' = :template') ->bind(':template', $template); } if ($template_style_id) { $query->join('LEFT', $db->quoteName('#__template_styles', 's'), $db->quoteName('s.template') . ' = ' . $db->quoteName('e.element')) ->where($db->quoteName('s.id') . ' = :style') ->bind(':style', $template_style_id, ParameterType::INTEGER); } // Set the query and load the templates. $db->setQuery($query); $templates = $db->loadObjectList('element'); // Build the search paths for module layouts. $module_path = Path::clean($client->path . '/modules/' . $module . '/tmpl'); // Prepare array of component layouts $module_layouts = []; // Prepare the grouped list $groups = []; // Add the layout options from the module path. if (is_dir($module_path) && ($module_layouts = Folder::files($module_path, '^[^_]*\.php$'))) { // Create the group for the module $groups['_'] = []; $groups['_']['id'] = $this->id . '__'; $groups['_']['text'] = Text::sprintf('JOPTION_FROM_MODULE'); $groups['_']['items'] = []; foreach ($module_layouts as $file) { // Add an option to the module group $value = basename($file, '.php'); $text = $lang->hasKey($key = strtoupper($module . '_LAYOUT_' . $value)) ? Text::_($key) : $value; $groups['_']['items'][] = HTMLHelper::_('select.option', '_:' . $value, $text); } } // Loop on all templates if ($templates) { foreach ($templates as $template) { // Load language file $lang->load('tpl_' . $template->element . '.sys', $client->path) || $lang->load('tpl_' . $template->element . '.sys', $client->path . '/templates/' . $template->element); $template_path = Path::clean($client->path . '/templates/' . $template->element . '/html/' . $module); // Add the layout options from the template path. if (is_dir($template_path) && ($files = Folder::files($template_path, '^[^_]*\.php$'))) { foreach ($files as $i => $file) { // Remove layout that already exist in component ones if (\in_array($file, $module_layouts)) { unset($files[$i]); } } if (\count($files)) { // Create the group for the template $groups[$template->element] = []; $groups[$template->element]['id'] = $this->id . '_' . $template->element; $groups[$template->element]['text'] = Text::sprintf('JOPTION_FROM_TEMPLATE', $template->name); $groups[$template->element]['items'] = []; foreach ($files as $file) { // Add an option to the template group $value = basename($file, '.php'); $text = $lang->hasKey($key = strtoupper('TPL_' . $template->element . '_' . $module . '_LAYOUT_' . $value)) ? Text::_($key) : $value; $groups[$template->element]['items'][] = HTMLHelper::_('select.option', $template->element . ':' . $value, $text); } } } } } // Compute attributes for the grouped list $attr = $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; $attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; // Prepare HTML code $html = []; // Compute the current selected values $selected = [$this->value]; // Add a grouped list $html[] = HTMLHelper::_( 'select.groupedlist', $groups, $this->name, ['id' => $this->id, 'group.id' => 'id', 'list.attr' => $attr, 'list.select' => $selected] ); return implode($html); } else { return ''; } } } PK ��\"�U^ ^ Field/ImagelistField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Supports an HTML select list of image * * @since 1.7.0 */ class ImagelistField extends FilelistField { /** * The form field type. * * @var string * @since 1.7.0 */ protected $type = 'Imagelist'; /** * Method to get the list of images field options. * Use the filter attribute to specify allowable file extensions. * * @return object[] The field option objects. * * @since 1.7.0 */ protected function getOptions() { // Define the image file type filter. $this->fileFilter = '\.png$|\.gif$|\.jpg$|\.bmp$|\.ico$|\.jpeg$|\.psd$|\.eps$|\.avif$|\.webp$|\.heic$|\.wp2$'; // Get the field options. return parent::getOptions(); } } PK ��\��]�% �% Field/SqlField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Database\Exception\ExecutionFailureException; use Joomla\Database\QueryInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Supports a custom SQL select list * * @since 1.7.0 */ class SqlField extends ListField { /** * The form field type. * * @var string * @since 1.7.0 */ public $type = 'SQL'; /** * The keyField. * * @var string * @since 3.2 */ protected $keyField; /** * The valueField. * * @var string * @since 3.2 */ protected $valueField; /** * The translate. * * @var boolean * @since 3.2 */ protected $translate = false; /** * The header. * * @var mixed * @since 4.3.0 */ protected $header; /** * The query. * * @var string * @since 3.2 */ protected $query; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { switch ($name) { case 'keyField': case 'valueField': case 'translate': case 'header': case 'query': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'translate': $this->$name = (bool) $value; break; case 'keyField': case 'valueField': case 'header': case 'query': $this->$name = (string) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 3.2 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { // Check if its using the old way $this->query = (string) $this->element['query']; if (empty($this->query)) { // Get the query from the form $query = []; $defaults = []; $sql_select = (string) $this->element['sql_select']; $sql_from = (string) $this->element['sql_from']; if ($sql_select && $sql_from) { $query['select'] = $sql_select; $query['from'] = $sql_from; $query['join'] = (string) $this->element['sql_join']; $query['where'] = (string) $this->element['sql_where']; $query['group'] = (string) $this->element['sql_group']; $query['order'] = (string) $this->element['sql_order']; // Get the filters $filters = isset($this->element['sql_filter']) ? explode(',', $this->element['sql_filter']) : []; // Get the default value for query if empty foreach ($filters as $filter) { $name = "sql_default_{$filter}"; $attrib = (string) $this->element[$name]; if (!empty($attrib)) { $defaults[$filter] = $attrib; } } // Process the query $this->query = $this->processQuery($query, $filters, $defaults); } } $this->keyField = (string) $this->element['key_field'] ?: 'value'; $this->valueField = (string) $this->element['value_field'] ?: (string) $this->element['name']; $this->translate = (string) $this->element['translate'] ?: false; $this->header = (string) $this->element['header'] ?: false; } return $return; } /** * Method to process the query from form. * * @param string[] $conditions The conditions from the form. * @param string[] $filters The columns to filter. * @param string[] $defaults The defaults value to set if condition is empty. * * @return QueryInterface The query object. * * @since 3.5 */ protected function processQuery($conditions, $filters, $defaults) { // Get the database object. $db = $this->getDatabase(); // Get the query object $query = $db->getQuery(true); // Select fields $query->select($conditions['select']); // From selected table $query->from($conditions['from']); // Join over the groups if (!empty($conditions['join'])) { $query->join('LEFT', $conditions['join']); } // Where condition if (!empty($conditions['where'])) { $query->where($conditions['where']); } // Group by if (!empty($conditions['group'])) { $query->group($conditions['group']); } // Process the filters if (\is_array($filters)) { // @TODO: Loading the filtering value from the request need to be deprecated. $html_filters = $this->context ? Factory::getApplication()->getUserStateFromRequest($this->context . '.filter', 'filter', [], 'array') : false; $form = $this->form; foreach ($filters as $k => $value) { // Get the filter value from the linked filter field $filterFieldValue = $form->getValue($value, $this->group); if ($html_filters && !empty($html_filters[$value])) { $escape = $db->quote($db->escape($html_filters[$value]), false); $query->where("{$value} = {$escape}"); } elseif ($filterFieldValue !== null) { $escape = $db->quote($db->escape($filterFieldValue), false); $query->where("{$value} = {$escape}"); } elseif (!empty($defaults[$value])) { $escape = $db->quote($db->escape($defaults[$value]), false); $query->where("{$value} = {$escape}"); } } } // Add order to query if (!empty($conditions['order'])) { $query->order($conditions['order']); } return $query; } /** * Method to get the custom field options. * Use the query attribute to supply a query to generate the list. * * @return object[] The field option objects. * * @since 1.7.0 */ protected function getOptions() { $options = []; // Initialize some field attributes. $key = $this->keyField; $value = $this->valueField; $header = $this->header; if ($this->query) { // Get the database object. $db = $this->getDatabase(); // Set the query and get the result list. $db->setQuery($this->query); try { $items = $db->loadObjectList(); } catch (ExecutionFailureException $e) { Factory::getApplication()->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); } } // Add header. if (!empty($header)) { $header_title = Text::_($header); $options[] = HTMLHelper::_('select.option', '', $header_title); } // Build the field options. if (!empty($items)) { foreach ($items as $item) { if ($this->translate == true) { $options[] = HTMLHelper::_('select.option', $item->$key, Text::_($item->$value)); } else { $options[] = HTMLHelper::_('select.option', $item->$key, $item->$value); } } } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; } } PK ��\��ׁ� � ( Field/WorkflowComponentSectionsField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Workflow\WorkflowServiceInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Framework. * * @since 4.0.0 */ class WorkflowComponentSectionsField extends ComponentsField { /** * The form field type. * * @var string * @since 4.0.0 */ protected $type = 'WorkflowComponentSections'; /** * Method to get a list of options for a list input. * * @return object[] An array of JHtml options. * * @since 4.0.0 */ protected function getOptions() { $app = Factory::getApplication(); $items = parent::getOptions(); $options = []; $options[] = HTMLHelper::_('select.option', ' ', Text::_('JNONE')); foreach ($items as $item) { if (substr($item->value, 0, 4) !== 'com_') { continue; } $component = $app->bootComponent($item->value); if (!($component instanceof WorkflowServiceInterface)) { continue; } foreach ($component->getWorkflowContexts() as $extension => $text) { $options[] = HTMLHelper::_('select.option', $extension, Text::sprintf('JWORKFLOW_FIELD_COMPONENT_SECTIONS_TEXT', $item->text, $text)); } } return $options; } } PK ��\��=�� � Field/WorkflowstageField.phpnu �[��� <?php /** * Joomla! Content Management System * * @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\CMS\Form\Field; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Workflow Stages field. * * @since 4.0.0 */ class WorkflowstageField extends GroupedlistField { /** * The form field type. * * @var string * @since 4.0.0 */ protected $type = 'Workflowstage'; /** * The component and section separated by ".". * * @var string * @since 4.0.0 */ protected $extension = ''; /** * Show only the stages which has an item attached * * @var boolean * @since 4.0.0 */ protected $activeonly = false; /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @since 4.0.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $result = parent::setup($element, $value, $group); if ($result) { if (\strlen($element['extension'])) { $this->extension = (string) $element['extension']; } else { $this->extension = Factory::getApplication()->getInput()->getCmd('extension'); } if ((string) $element['activeonly'] === '1' || (string) $element['activeonly'] === 'true') { $this->activeonly = true; } } return $result; } /** * Method to get the field option groups. * * @return array[] The field option objects as a nested array in groups. * * @since 4.0.0 * @throws \UnexpectedValueException */ protected function getGroups() { $db = $this->getDatabase(); $query = $db->getQuery(true); // Select distinct stages for existing articles $query ->select( [ 'DISTINCT ' . $db->quoteName('ws.id', 'workflow_stage_id'), $db->quoteName('ws.title', 'workflow_stage_title'), $db->quoteName('w.title', 'workflow_title'), $db->quoteName('w.id', 'workflow_id'), $db->quoteName('w.ordering', 'ordering'), $db->quoteName('ws.ordering', 'workflow_stage_ordering'), ] ) ->from($db->quoteName('#__workflow_stages', 'ws')) ->from($db->quoteName('#__workflows', 'w')) ->where( [ $db->quoteName('ws.workflow_id') . ' = ' . $db->quoteName('w.id'), $db->quoteName('w.extension') . ' = :extension', ] ) ->bind(':extension', $this->extension) ->order( [ $db->quoteName('w.ordering'), $db->quoteName('ws.ordering'), ] ); if ($this->activeonly) { $query ->from($db->quoteName('#__workflow_associations', 'wa')) ->where( [ $db->quoteName('wa.stage_id') . ' = ' . $db->quoteName('ws.id'), $db->quoteName('wa.extension') . ' = :associationExtension', ] ) ->bind(':associationExtension', $this->extension); } $stages = $db->setQuery($query)->loadObjectList(); $workflowStages = []; // Grouping the stages by workflow foreach ($stages as $stage) { // Using workflow ID to differentiate workflows having same title $workflowStageKey = Text::_($stage->workflow_title) . ' (' . $stage->workflow_id . ')'; if (!\array_key_exists($workflowStageKey, $workflowStages)) { $workflowStages[$workflowStageKey] = []; } $workflowStages[$workflowStageKey][] = HTMLHelper::_('select.option', $stage->workflow_stage_id, Text::_($stage->workflow_stage_title)); } // Merge any additional options in the XML definition. return array_merge(parent::getGroups(), $workflowStages); } } PK ��\@���� � Field/NoteField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Form\FormField; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Supports a one line text field. * * @link https://html.spec.whatwg.org/multipage/input.html#text-(type=text)-state-and-search-state-(type=search) * @since 1.7.0 */ class NoteField extends FormField { /** * The form field type. * * @var string * @since 1.7.0 */ protected $type = 'Note'; /** * Hide the label when rendering the form field. * * @var boolean * @since 4.0.0 */ protected $hiddenLabel = true; /** * Hide the description when rendering the form field. * * @var boolean * @since 4.0.0 */ protected $hiddenDescription = true; /** * Method to get the field label markup. * * @return string The field label markup. * * @since 1.7.0 */ protected function getLabel() { if (empty($this->element['label']) && empty($this->element['description'])) { return ''; } $html = []; $class = []; if (!empty($this->class)) { $class[] = $this->class; } if ($close = (string) $this->element['close']) { HTMLHelper::_('bootstrap.alert'); $close = $close === 'true' ? 'alert' : $close; $html[] = '<button type="button" class="btn-close" data-bs-dismiss="' . $close . '"></button>'; $class[] = 'alert-dismissible show'; } $class = $class ? ' class="' . implode(' ', $class) . '"' : ''; $title = $this->element['label'] ? (string) $this->element['label'] : ($this->element['title'] ? (string) $this->element['title'] : ''); $heading = $this->element['heading'] ? (string) $this->element['heading'] : 'h4'; $description = (string) $this->element['description']; $html[] = !empty($title) ? '<' . $heading . '>' . Text::_($title) . '</' . $heading . '>' : ''; $html[] = !empty($description) ? Text::_($description) : ''; return '</div><div ' . $class . '>' . implode('', $html); } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 1.7.0 */ protected function getInput() { return ''; } } PK ��\��Y� � ! Field/DatabaseconnectionField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Language\Text; use Joomla\Database\DatabaseDriver; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Provides a list of available database connections, optionally limiting to * a given list. * * @see DatabaseDriver * @since 1.7.3 */ class DatabaseconnectionField extends ListField { /** * The form field type. * * @var string * @since 1.7.3 */ protected $type = 'Databaseconnection'; /** * Method to get the list of database options. * * This method produces a drop down list of available databases supported * by DatabaseDriver classes that are also supported by the application. * * @return array The field option objects. * * @since 1.7.3 * @see DatabaseDriver::getConnectors() */ protected function getOptions() { $options = []; // This gets the connectors available in the platform and supported by the server. $available = array_map('strtolower', DatabaseDriver::getConnectors()); /** * This gets the list of database types supported by the application. * This should be entered in the form definition as a comma separated list. * If no supported databases are listed, it is assumed all available databases * are supported. */ $supported = $this->element['supported']; if (!empty($supported)) { $supported = explode(',', $supported); foreach ($supported as $support) { if (\in_array($support, $available)) { $options[$support] = Text::_(ucfirst($support)); } } } else { foreach ($available as $support) { $options[$support] = Text::_(ucfirst($support)); } } // This will come into play if an application is installed that requires // a database that is not available on the server. if (empty($options)) { $options[''] = Text::_('JNONE'); } return $options; } } PK ��\�g� � � Field/EmailField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Provides and input field for email addresses * * @link https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email) * @see \Joomla\CMS\Form\Rule\EmailRule * @since 1.7.0 */ class EmailField extends TextField { /** * The form field type. * * @var string * @since 1.7.0 */ protected $type = 'Email'; /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email'; /** * Method to get the field input markup for email addresses. * * @return string The field input markup. * * @since 1.7.0 */ protected function getInput() { // Trim the trailing line in the layout file return rtrim($this->getRenderer($this->layout)->render($this->getLayoutData()), PHP_EOL); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.5 */ protected function getLayoutData() { $data = parent::getLayoutData(); $extraData = [ 'maxLength' => $this->maxLength, 'multiple' => $this->multiple, ]; return array_merge($data, $extraData); } } PK ��\x,!>m m Field/RedirectStatusField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Redirect Status field. * * @since 3.8.0 */ class RedirectStatusField extends PredefinedlistField { /** * The form field type. * * @var string * @since 3.8.0 */ public $type = 'Redirect_Status'; /** * Available statuses * * @var string[] * @since 3.8.0 */ protected $predefinedOptions = [ '-2' => 'JTRASHED', '0' => 'JDISABLED', '1' => 'JENABLED', '2' => 'JARCHIVED', '*' => 'JALL', ]; } PK ��\p:t9� � Field/HeadertagField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\HTML\HTMLHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla! CMS. * * @since 3.0 */ class HeadertagField extends ListField { /** * The form field type. * * @var string * @since 3.0 */ protected $type = 'HeaderTag'; /** * Method to get the field options. * * @return object[] The field option objects. * * @since 3.0 */ protected function getOptions() { $options = []; $tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div']; // Create one new option object for each tag foreach ($tags as $tag) { $tmp = HTMLHelper::_('select.option', $tag, $tag); $options[] = $tmp; } reset($options); return $options; } } PK ��\��,��% �% Field/RulesField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Access\Access; use Joomla\CMS\Access\Rules; use Joomla\CMS\Form\FormField; use Joomla\CMS\Helper\UserGroupsHelper; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Field for assigning permissions to groups for a given asset * * @see JAccess * @since 1.7.0 */ class RulesField extends FormField { /** * The form field type. * * @var string * @since 1.7.0 */ protected $type = 'Rules'; /** * Name of the layout being used to render the field * * @var string * @since 4.0.0 */ protected $layout = 'joomla.form.field.rules'; /** * The section. * * @var string * @since 3.2 */ protected $section; /** * The component. * * @var string * @since 3.2 */ protected $component; /** * The assetField. * * @var string * @since 3.2 */ protected $assetField; /** * The flag which indicates if it is the global config * * @var bool * @since 4.3.0 */ protected $isGlobalConfig; /** * The asset rules * * @var Rules * @since 4.3.0 */ protected $assetRules; /** * The actions * * @var object[] * @since 4.3.0 */ protected $actions; /** * The groups * * @var object[] * @since 4.3.0 */ protected $groups; /** * The asset Id * * @var int * @since 4.3.0 */ protected $assetId; /** * The parent asset Id * * @var int * @since 4.3.0 */ protected $parentAssetId; /** * The flag to indicate that it is a new item * * @var bool * @since 4.3.0 */ protected $newItem; /** * The parent class of the field * * @var string * @since 4.0.0 */ protected $parentclass; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.2 */ public function __get($name) { switch ($name) { case 'section': case 'component': case 'assetField': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.2 */ public function __set($name, $value) { switch ($name) { case 'section': case 'component': case 'assetField': $this->$name = (string) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 3.2 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { $this->section = $this->element['section'] ? (string) $this->element['section'] : ''; $this->component = $this->element['component'] ? (string) $this->element['component'] : ''; $this->assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; } return $return; } /** * Method to get the field input markup for Access Control Lists. * Optionally can be associated with a specific component and section. * * @return string The field input markup. * * @since 1.7.0 * @todo: Add access check. */ protected function getInput() { // Initialise some field attributes. $section = $this->section; $assetField = $this->assetField; $component = empty($this->component) ? 'root.1' : $this->component; // Current view is global config? $this->isGlobalConfig = $component === 'root.1'; // Get the actions for the asset. $this->actions = Access::getActionsFromFile( JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', "/access/section[@name='" . $section . "']/" ); if ($this->actions === false) { $this->actions = []; } // Iterate over the children and add to the actions. foreach ($this->element->children() as $el) { if ($el->getName() === 'action') { $this->actions[] = (object) [ 'name' => (string) $el['name'], 'title' => (string) $el['title'], 'description' => (string) $el['description'], ]; } } // Get the asset id. // Note that for global configuration, com_config injects asset_id = 1 into the form. $this->assetId = (int) $this->form->getValue($assetField); $this->newItem = empty($this->assetId) && $this->isGlobalConfig === false && $section !== 'component'; // If the asset id is empty (component or new item). if (empty($this->assetId)) { // Get the component asset id as fallback. $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('id')) ->from($db->quoteName('#__assets')) ->where($db->quoteName('name') . ' = :component') ->bind(':component', $component); $db->setQuery($query); $this->assetId = (int) $db->loadResult(); /** * @todo: incorrect info * When creating a new item (not saving) it uses the calculated permissions from the component (item <-> component <-> global config). * But if we have a section too (item <-> section(s) <-> component <-> global config) this is not correct. * Also, currently it uses the component permission, but should use the calculated permissions for achild of the component/section. */ } // If not in global config we need the parent_id asset to calculate permissions. if (!$this->isGlobalConfig) { // In this case we need to get the component rules too. $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('parent_id')) ->from($db->quoteName('#__assets')) ->where($db->quoteName('id') . ' = :assetId') ->bind(':assetId', $this->assetId, ParameterType::INTEGER); $db->setQuery($query); $this->parentAssetId = (int) $db->loadResult(); } // Get the rules for just this asset (non-recursive). $this->assetRules = Access::getAssetRules($this->assetId, false, false); // Get the available user groups. $this->groups = $this->getUserGroups(); // Trim the trailing line in the layout file return trim($this->getRenderer($this->layout)->render($this->getLayoutData())); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 4.0.0 */ protected function getLayoutData() { $data = parent::getLayoutData(); $extraData = [ 'groups' => $this->groups, 'section' => $this->section, 'actions' => $this->actions, 'assetId' => $this->assetId, 'newItem' => $this->newItem, 'assetRules' => $this->assetRules, 'isGlobalConfig' => $this->isGlobalConfig, 'parentAssetId' => $this->parentAssetId, 'component' => $this->component, ]; return array_merge($data, $extraData); } /** * Get a list of the user groups. * * @return object[] * * @since 1.7.0 */ protected function getUserGroups() { $options = UserGroupsHelper::getInstance()->getAll(); foreach ($options as &$option) { $option->value = $option->id; $option->text = $option->title; } return array_values($options); } } PK ��\�p�X X Field/LanguageField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Language\LanguageHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the Joomla Platform. * Supports a list of installed application languages * * @see \Joomla\CMS\Form\Field\ContentlanguageField for a select list of content languages. * @since 1.7.0 */ class LanguageField extends ListField { /** * The form field type. * * @var string * @since 1.7.0 */ protected $type = 'Language'; /** * Method to get the field options. * * @return object[] The field option objects. * * @since 1.7.0 */ protected function getOptions() { // Initialize some field attributes. $client = (string) $this->element['client']; if ($client !== 'site' && $client !== 'administrator') { $client = 'site'; } // Make sure the languages are sorted base on locale instead of random sorting $languages = LanguageHelper::createLanguageList($this->value, \constant('JPATH_' . strtoupper($client)), true, true); if (\count($languages) > 1) { usort( $languages, function ($a, $b) { return strcmp($a['value'], $b['value']); } ); } // Merge any additional options in the XML definition. $options = array_merge( parent::getOptions(), $languages ); // Set the default value active language $langParams = ComponentHelper::getParams('com_languages'); switch ((string) $this->value) { case 'site': case 'frontend': case '0': $this->value = $langParams->get('site', 'en-GB'); break; case 'admin': case 'administrator': case 'backend': case '1': $this->value = $langParams->get('administrator', 'en-GB'); break; case 'active': case 'auto': $lang = Factory::getLanguage(); $this->value = $lang->getTag(); break; default: break; } return $options; } } PK ��\���w w Field/AuthorField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field to load a list of content authors * * @since 3.2 */ class AuthorField extends ListField { /** * The form field type. * * @var string * @since 3.2 */ public $type = 'Author'; /** * Cached array of the category items. * * @var array[] * @since 3.2 */ protected static $options = []; /** * Method to get the options to populate list * * @return object[] The field option objects. * * @since 3.2 */ protected function getOptions() { // Accepted modifiers $hash = md5($this->element); if (!isset(static::$options[$hash])) { static::$options[$hash] = parent::getOptions(); $db = $this->getDatabase(); // Construct the query $query = $db->getQuery(true) ->select( [ $db->quoteName('u.id', 'value'), $db->quoteName('u.name', 'text'), ] ) ->from($db->quoteName('#__users', 'u')) ->join('INNER', $db->quoteName('#__content', 'c'), $db->quoteName('c.created_by') . ' = ' . $db->quoteName('u.id')) ->group( [ $db->quoteName('u.id'), $db->quoteName('u.name'), ] ) ->order($db->quoteName('u.name')); // Setup the query $db->setQuery($query); // Return the result if ($options = $db->loadObjectList()) { static::$options[$hash] = array_merge(static::$options[$hash], $options); } } return static::$options[$hash]; } } PK ��\�o�� � Field/AccessiblemediaField.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Form\Field; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * The Field to load the form inside current form * * @since 4.0.0 */ class AccessiblemediaField extends SubformField { /** * The form field type. * * @var string * @since 4.0.0 */ protected $type = 'Accessiblemedia'; /** * The preview. * * @var string * @since 4.0.0 */ protected $preview; /** * The directory. * * @var string * @since 4.0.0 */ protected $directory; /** * The previewWidth. * * @var integer * @since 4.0.0 */ protected $previewWidth; /** * The previewHeight. * * @var integer * @since 4.0.0 */ protected $previewHeight; /** * Layout to render * * @var string * @since 4.0.0 */ protected $layout; /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 4.0.0 */ public function __get($name) { switch ($name) { case 'directory': case 'preview': case 'previewHeight': case 'previewWidth': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 4.0.0 */ public function __set($name, $value) { switch ($name) { case 'directory': case 'preview': $this->$name = (string) $value; break; case 'previewHeight': case 'previewWidth': $this->$name = (int) $value; break; default: parent::__set($name, $value); } } /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. * * @return boolean True on success. * * @since 4.0.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { /** * When you have subforms which are not repeatable (i.e. a subform custom field with the * repeat attribute set to 0) you get an array here since the data comes from decoding the * JSON into an associative array, including the media subfield's data. * * However, this method expects an object or a string, not an array. Typecasting the array * to an object solves the data format discrepancy. */ $value = is_array($value) ? (object) $value : $value; /** * If the value is not a string, it is * most likely within a custom field of type subform * and the value is a stdClass with properties * imagefile and alt_text. So it is fine. */ if (\is_string($value)) { json_decode($value); // Check if value is a valid JSON string. if ($value !== '' && json_last_error() !== JSON_ERROR_NONE) { /** * If the value is not empty and is not a valid JSON string, * it is most likely a custom field created in Joomla 3 and * the value is a string that contains the file name. */ if (is_file(JPATH_ROOT . '/' . $value)) { $value = '{"imagefile":"' . $value . '","alt_text":""}'; } else { $value = ''; } } } elseif ( !is_object($value) || !property_exists($value, 'imagefile') || !property_exists($value, 'alt_text') ) { return false; } if (!parent::setup($element, $value, $group)) { return false; } $this->directory = (string) $this->element['directory']; $this->preview = (string) $this->element['preview']; $this->previewHeight = isset($this->element['preview_height']) ? (int) $this->element['preview_height'] : 200; $this->previewWidth = isset($this->element['preview_width']) ? (int) $this->element['preview_width'] : 200; $xml = <<<XML <?xml version="1.0" encoding="utf-8"?> <form> <fieldset name="accessiblemedia" label="JLIB_FORM_FIELD_PARAM_ACCESSIBLEMEDIA_LABEL" > <field name="imagefile" type="media" label="JLIB_FORM_FIELD_PARAM_ACCESSIBLEMEDIA_PARAMS_IMAGEFILE_LABEL" directory="$this->directory" preview="$this->preview" preview_width="$this->previewWidth" preview_height="$this->previewHeight" schemes="http,https,ftp,ftps,data,file" validate="url" relative="true" /> <field name="alt_text" type="text" label="JLIB_FORM_FIELD_PARAM_ACCESSIBLEMEDIA_PARAMS_ALT_TEXT_LABEL" /> <field name="alt_empty" type="checkbox" label="JLIB_FORM_FIELD_PARAM_ACCESSIBLEMEDIA_PARAMS_ALT_EMPTY_LABEL" description="JLIB_FORM_FIELD_PARAM_ACCESSIBLEMEDIA_PARAMS_ALT_EMPTY_DESC" /> </fieldset> </form> XML; $this->formsource = $xml; $this->layout = 'joomla.form.field.media.accessiblemedia'; return true; } } PK ��\D�X'