Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/joomla4/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/joomla4/Form.tar

Field/AuthorField.php000064400000003036151160211160010502 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Form Field to load a list of content authors
 *
 * @since  3.2
 */
class AuthorField extends \JFormFieldList
{
	/**
	 * 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 = array();

	/**
	 * Method to get the options to populate list
	 *
	 * @return  array  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 = Factory::getDbo();

			// Construct the query
			$query = $db->getQuery(true)
				->select('u.id AS value, u.name AS text')
				->from('#__users AS u')
				->join('INNER', '#__content AS c ON c.created_by =
u.id')
				->group('u.id, u.name')
				->order('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];
	}
}
Field/CaptchaField.php000064400000010245151160211160010603 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Captcha\Captcha;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;

/**
 * Captcha field.
 *
 * @since  2.5
 */
class CaptchaField extends FormField
{
	/**
	 * The field type.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $type = 'Captcha';

	/**
	 * The captcha base instance of our type.
	 *
	 * @var Captcha
	 */
	protected $_captcha;

	/**
	 * 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 'plugin':
			case 'namespace':
				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 'plugin':
			case 'namespace':
				$this->$name = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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   2.5
	 */
	public function setup(\SimpleXMLElement $element, $value, $group = null)
	{
		$result = parent::setup($element, $value, $group);

		$app = Factory::getApplication();

		$default = $app->get('captcha');

		if ($app->isClient('site'))
		{
			$default = $app->getParams()->get('captcha', $default);
		}

		$plugin = $this->element['plugin'] ?
			(string) $this->element['plugin'] :
			$default;

		$this->plugin = $plugin;

		if ($plugin === 0 || $plugin === '0' || $plugin ===
'' || $plugin === null)
		{
			$this->hidden = true;

			return false;
		}
		else
		{
			// Force field to be required. There's no reason to have a captcha
if it is not required.
			// Obs: Don't put required="required" in the xml file,
you just need to have validate="captcha"
			$this->required = true;

			if (strpos($this->class, 'required') === false)
			{
				$this->class .= ' required';
			}
		}

		$this->namespace = $this->element['namespace'] ? (string)
$this->element['namespace'] : $this->form->getName();

		try
		{
			// Get an instance of the captcha class that we are using
			$this->_captcha = Captcha::getInstance($this->plugin,
array('namespace' => $this->namespace));

			/**
			 * Give the captcha instance a possibility to react on the
setup-process,
			 * e.g. by altering the XML structure of the field, for example hiding
the label
			 * when using invisible captchas.
			 */
			$this->_captcha->setupField($this, $element);
		}
		catch (\RuntimeException $e)
		{
			$this->_captcha = null;
			\JFactory::getApplication()->enqueueMessage($e->getMessage(),
'error');

			return false;
		}

		return $result;
	}

	/**
	 * Method to get the field input.
	 *
	 * @return  string  The field input.
	 *
	 * @since   2.5
	 */
	protected function getInput()
	{
		if ($this->hidden || $this->_captcha == null)
		{
			return '';
		}

		try
		{
			return $this->_captcha->display($this->name, $this->id,
$this->class);
		}
		catch (\RuntimeException $e)
		{
			\JFactory::getApplication()->enqueueMessage($e->getMessage(),
'error');
		}
		return '';
	}
}
Field/ChromestyleField.php000064400000013105151160211160011534
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('groupedlist');

/**
 * Chrome Styles field.
 *
 * @since  3.0
 */
class ChromestyleField extends \JFormFieldGroupedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.0
	 */
	public $type = 'ChromeStyle';

	/**
	 * 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)
	{
		switch ($name)
		{
			case '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 get 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 = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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     JFormField::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 = \JApplicationHelper::getClientInfo($clientName, true);
					$clientId = $client->id;
				}
			}

			if (!isset($clientId) && $this->form instanceof \JForm)
			{
				$clientId = $this->form->getValue('client_id');
			}

			$this->clientId = (int) $clientId;
		}

		return $result;
	}


	/**
	 * Method to get the list of template chrome style options
	 * grouped by template.
	 *
	 * @return  array  The field option objects as a nested array in groups.
	 *
	 * @since   3.0
	 */
	protected function getGroups()
	{
		$groups = array();

		// Add Module Style Field
		$tmp = '---' .
\JText::_('JLIB_FORM_VALUE_FROM_TEMPLATE') . '---';
		$groups[$tmp][] = \JHtml::_('select.option', '0',
\JText::_('JLIB_FORM_VALUE_INHERITED'));

		$templateStyles = $this->getTemplateModuleStyles();

		// Create one new option object for each available style, grouped by
templates
		foreach ($templateStyles as $template => $styles)
		{
			$template = ucfirst($template);
			$groups[$template] = array();

			foreach ($styles as $style)
			{
				$tmp = \JHtml::_('select.option', $template . '-' .
$style, $style);
				$groups[$template][] = $tmp;
			}
		}

		reset($groups);

		return $groups;
	}

	/**
	 * Method to get the templates module styles.
	 *
	 * @return  array  The array of styles, grouped by templates.
	 *
	 * @since   3.0
	 */
	protected function getTemplateModuleStyles()
	{
		$moduleStyles = array();

		$templates = array($this->getSystemTemplate());
		$templates = array_merge($templates, $this->getTemplates());
		$path      = JPATH_ADMINISTRATOR;

		if ($this->clientId === 0)
		{
			$path = JPATH_SITE;
		}

		foreach ($templates as $template)
		{
			$modulesFilePath = $path . '/templates/' .
$template->element . '/html/modules.php';

			// Is there modules.php for that template?
			if (file_exists($modulesFilePath))
			{
				$modulesFileData = file_get_contents($modulesFilePath);

				preg_match_all('/function[\s\t]*modChrome\_([a-z0-9\-\_]*)[\s\t]*\(/i',
$modulesFileData, $styles);

				if (!array_key_exists($template->element, $moduleStyles))
				{
					$moduleStyles[$template->element] = array();
				}

				$moduleStyles[$template->element] = $styles[1];
			}
		}

		return $moduleStyles;
	}

	/**
	 * Method to get the system template as an object.
	 *
	 * @return  \stdClass  The object of system template.
	 *
	 * @since   3.0
	 */
	protected function getSystemTemplate()
	{
		$template = new \stdClass;
		$template->element = 'system';
		$template->name    = 'system';

		return $template;
	}

	/**
	 * Return a list of templates
	 *
	 * @return  array  List of templates
	 *
	 * @since   3.2.1
	 */
	protected function getTemplates()
	{
		$db = Factory::getDbo();

		// Get the database object and a new query object.
		$query = $db->getQuery(true);

		// Build the query.
		$query->select('element, name')
			->from('#__extensions')
			->where('client_id = ' . $this->clientId)
			->where('type = ' . $db->quote('template'))
			->where('enabled = 1');

		// Set the query and load the templates.
		$db->setQuery($query);

		return $db->loadObjectList('element');
	}
}
Field/ContenthistoryField.php000064400000003626151160211160012301
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormField;
use Joomla\CMS\Session\Session;
use Joomla\CMS\Table\Table;

/**
 * Field to select Content History from a modal list.
 *
 * @since  3.2
 */
class ContenthistoryField extends FormField
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.2
	 */
	public $type = 'ContentHistory';

	/**
	 * Layout to render the label
	 *
	 * @var  string
	 */
	protected $layout = 'joomla.form.field.contenthistory';

	/**
	 * 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();

		$typeId =
Table::getInstance('Contenttype')->getTypeId($this->element['data-typeAlias']);
		$itemId = $this->form->getValue('id');
		$label  = \JText::_('JTOOLBAR_VERSIONS');

		$link   =
'index.php?option=com_contenthistory&amp;view=history&amp;layout=modal&amp;tmpl=component&amp;field='
			. $this->id . '&amp;item_id=' . $itemId .
'&amp;type_id=' . $typeId . '&amp;type_alias='
			. $this->element['data-typeAlias'] . '&amp;'
. Session::getFormToken() . '=1';

		$extraData = array(
				'type' => $typeId,
				'item' => $itemId,
				'label' => $label,
				'link' => $link,
		);

		return array_merge($data, $extraData);
	}

	/**
	 * Method to get the content history field input markup.
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   3.2
	 */
	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());
	}
}
Field/ContentlanguageField.php000064400000001655151160211160012363
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Provides a list of content languages
 *
 * @see    JFormFieldLanguage for a select list of application languages.
 * @since  1.6
 */
class ContentlanguageField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'ContentLanguage';

	/**
	 * Method to get the field options for content languages.
	 *
	 * @return  array  The options the field is going to show.
	 *
	 * @since   1.6
	 */
	protected function getOptions()
	{
		return array_merge(parent::getOptions(),
\JHtml::_('contentlanguage.existing'));
	}
}
Field/ContenttypeField.php000064400000004432151160211160011555
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Content Type field.
 *
 * @since  3.1
 */
class ContenttypeField extends \JFormFieldList
{
	/**
	 * A flexible tag list that respects access controls
	 *
	 * @var    string
	 * @since  3.1
	 */
	public $type = 'Contenttype';

	/**
	 * Method to get the field input for a list of content types.
	 *
	 * @return  string  The field input.
	 *
	 * @since   3.1
	 */
	protected function getInput()
	{
		if (!is_array($this->value))
		{
			if (is_object($this->value))
			{
				$this->value = $this->value->tags;
			}

			if (is_string($this->value))
			{
				$this->value = explode(',', $this->value);
			}
		}

		return parent::getInput();
	}

	/**
	 * Method to get a list of content types
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.1
	 */
	protected function getOptions()
	{
		$lang = Factory::getLanguage();
		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select('a.type_id AS value, a.type_title AS text, a.type_alias
AS alias')
			->from('#__content_types AS a')

			->order('a.type_title ASC');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$options = $db->loadObjectList();
		}
		catch (\RuntimeException $e)
		{
			return array();
		}

		foreach ($options as $option)
		{
			// Make up the string from the component sys.ini file
			$parts = explode('.', $option->alias);
			$comp = array_shift($parts);

			// Make sure the component sys.ini is loaded
			$lang->load($comp . '.sys', JPATH_ADMINISTRATOR, null,
false, true)
			|| $lang->load($comp . '.sys', JPATH_ADMINISTRATOR .
'/components/' . $comp, null, false, true);

			$option->string = implode('_', $parts);
			$option->string = $comp . '_CONTENT_TYPE_' .
$option->string;

			if ($lang->hasKey($option->string))
			{
				$option->text = \JText::_($option->string);
			}
		}

		// Merge any additional options in the XML definition.
		$options = array_merge(parent::getOptions(), $options);

		return $options;
	}
}
Field/EditorField.php000064400000017033151160211160010470 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Editor\Editor;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('textarea');

/**
 * A textarea field for content creation
 *
 * @see    JEditor
 * @since  1.6
 */
class EditorField extends \JFormFieldTextarea
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'Editor';

	/**
	 * The Editor object.
	 *
	 * @var    Editor
	 * @since  1.6
	 */
	protected $editor;

	/**
	 * The height of the editor.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $height;

	/**
	 * The width of the editor.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $width;

	/**
	 * The assetField of the editor.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $assetField;

	/**
	 * The authorField of the editor.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $authorField;

	/**
	 * The asset of the editor.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $asset;

	/**
	 * The buttons of the editor.
	 *
	 * @var    mixed
	 * @since  3.2
	 */
	protected $buttons;

	/**
	 * The hide of the editor.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $hide;

	/**
	 * The editorType of the editor.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $editorType;

	/**
	 * 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 'height':
			case 'width':
			case 'assetField':
			case 'authorField':
			case 'asset':
			case 'buttons':
			case 'hide':
			case 'editorType':
				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 'height':
			case 'width':
			case 'assetField':
			case 'authorField':
			case 'asset':
				$this->$name = (string) $value;
				break;

			case 'buttons':
				$value = (string) $value;

				if ($value === 'true' || $value === 'yes' || $value
=== '1')
				{
					$this->buttons = true;
				}
				elseif ($value === 'false' || $value === 'no' ||
$value === '0')
				{
					$this->buttons = false;
				}
				else
				{
					$this->buttons = explode(',', $value);
				}
				break;

			case 'hide':
				$value = (string) $value;
				$this->hide = $value ? explode(',', $value) : array();
				break;

			case 'editorType':
				// Can be in the form of: editor="desired|alternative".
				$this->editorType  = explode('|', trim((string) $value));
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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)
		{
			$this->height      = $this->element['height'] ? (string)
$this->element['height'] : '500';
			$this->width       = $this->element['width'] ? (string)
$this->element['width'] : '100%';
			$this->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($this->assetField) ?: (string)
$this->element['asset_id'];

			$buttons    = (string) $this->element['buttons'];
			$hide       = (string) $this->element['hide'];
			$editorType = (string) $this->element['editor'];

			if ($buttons === 'true' || $buttons === 'yes' ||
$buttons === '1')
			{
				$this->buttons = true;
			}
			elseif ($buttons === 'false' || $buttons === 'no' ||
$buttons === '0')
			{
				$this->buttons = false;
			}
			else
			{
				$this->buttons = !empty($hide) ? explode(',', $buttons) :
array();
			}

			$this->hide        = !empty($hide) ? explode(',', (string)
$this->element['hide']) : array();
			$this->editorType  = !empty($editorType) ? explode('|',
trim($editorType)) : array();
		}

		return $result;
	}

	/**
	 * Method to get the field input markup for the editor area
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   1.6
	 */
	protected function getInput()
	{
		// Get an editor object.
		$editor = $this->getEditor();
		$params = array(
			'autofocus' => $this->autofocus,
			'readonly'  => $this->readonly || $this->disabled,
			'syntax'    => (string)
$this->element['syntax'],
		);

		return $editor->display(
			$this->name,
			htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'),
			$this->width,
			$this->height,
			$this->columns,
			$this->rows,
			$this->buttons ? (is_array($this->buttons) ?
array_merge($this->buttons, $this->hide) : $this->hide) : false,
			$this->id,
			$this->asset,
			$this->form->getValue($this->authorField),
			$params
		);
	}

	/**
	 * Method to get an Editor object based on the form field.
	 *
	 * @return  Editor  The Editor object.
	 *
	 * @since   1.6
	 */
	protected function getEditor()
	{
		// Only create the editor if it is not already created.
		if (empty($this->editor))
		{
			$editor = null;

			if ($this->editorType)
			{
				// Get the list of editor types.
				$types = $this->editorType;

				// Get the database object.
				$db = Factory::getDbo();

				// Iterate over the types looking for an existing editor.
				foreach ($types as $element)
				{
					// Build the query.
					$query = $db->getQuery(true)
						->select('element')
						->from('#__extensions')
						->where('element = ' . $db->quote($element))
						->where('folder = ' .
$db->quote('editors'))
						->where('enabled = 1');

					// Check of the editor exists.
					$db->setQuery($query, 0, 1);
					$editor = $db->loadResult();

					// If an editor was found stop looking.
					if ($editor)
					{
						break;
					}
				}
			}

			// Create the JEditor instance based on the given editor.
			if ($editor === null)
			{
				$editor = Factory::getConfig()->get('editor');
			}

			$this->editor = Editor::getInstance($editor);
		}

		return $this->editor;
	}

	/**
	 * Method to get the JEditor output for an onSave event.
	 *
	 * @return  string  The JEditor object output.
	 *
	 * @since       1.6
	 * @deprecated  4.0  Will be removed without replacement
	 * @see         Editor::save()
	 */
	public function save()
	{
		$editor = $this->getEditor();

		if (!method_exists($editor, 'save'))
		{
			return '';
		}

		return $editor->save($this->id);
	}
}
Field/FrontendlanguageField.php000064400000003730151160211160012524
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Provides a list of published content languages with home pages
 *
 * @see    JFormFieldLanguage for a select list of application languages.
 * @since  3.5
 */
class FrontendlanguageField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.5
	 */
	public $type = 'Frontend_Language';

	/**
	 * Method to get the field options for frontend published content
languages with homes.
	 *
	 * @return  array  The options the field is going to show.
	 *
	 * @since   3.5
	 */
	protected function getOptions()
	{
		// Get the database object and a new query object.
		$db    = Factory::getDbo();
		$query = $db->getQuery(true);

		$query->select('a.lang_code AS value, a.title AS text')
			->from($db->quoteName('#__languages') . ' AS
a')
			->where('a.published = 1')
			->order('a.title');

		// Select the language home pages.
		$query->select('l.home, l.language')
			->innerJoin($db->quoteName('#__menu') . ' AS l ON
l.language=a.lang_code AND l.home=1 AND l.published=1 AND l.language
<> ' . $db->quote('*'))
			->innerJoin($db->quoteName('#__extensions') . ' AS
e ON e.element = a.lang_code')
			->where('e.client_id = 0')
			->where('e.enabled = 1')
			->where('e.state = 0');

		$db->setQuery($query);

		try
		{
			$languages = $db->loadObjectList();
		}
		catch (\RuntimeException $e)
		{
			$languages = array();

			if (Factory::getUser()->authorise('core.admin'))
			{
				Factory::getApplication()->enqueueMessage($e->getMessage(),
'error');
			}
		}

		// Merge any additional options in the XML definition.
		return array_merge(parent::getOptions(), $languages);
	}
}
Field/HeadertagField.php000064400000001775151160211160011134
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Form Field class for the Joomla! CMS.
 *
 * @since  3.0
 */
class HeadertagField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.0
	 */
	protected $type = 'HeaderTag';

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.0
	 */
	protected function getOptions()
	{
		$options = array();
		$tags = array('h1', 'h2', 'h3',
'h4', 'h5', 'h6', 'p',
'div');

		// Create one new option object for each tag
		foreach ($tags as $tag)
		{
			$tmp = \JHtml::_('select.option', $tag, $tag);
			$options[] = $tmp;
		}

		reset($options);

		return $options;
	}
}
Field/HelpsiteField.php000064400000003265151160211160011021
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\Help\Help;

FormHelper::loadFieldClass('list');

/**
 * Form Field class for the Joomla Platform.
 * Provides a select list of help sites.
 *
 * @since       1.6
 * @deprecated  4.0 To be removed
 */
class HelpsiteField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'Helpsite';

	/**
	 * Method to get the help site field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   1.6
	 */
	protected function getOptions()
	{
		// Merge any additional options in the XML definition.
		$options = array_merge(parent::getOptions(),
Help::createSiteList(JPATH_ADMINISTRATOR . '/help/helpsites.xml',
$this->value));

		return $options;
	}

	/**
	 * Override to add refresh button
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   3.2
	 */
	protected function getInput()
	{
		\JHtml::_('script', 'system/helpsite.js',
array('version' => 'auto', 'relative'
=> true));

		$showDefault = (string) $this->getAttribute('showDefault')
=== 'false' ? 'false' : 'true';

		$html = parent::getInput();
		$button = '<button
						type="button"
						class="btn btn-small"
						id="helpsite-refresh"
						rel="' . $this->id . '"
						showDefault="' . $showDefault . '"
					>
					<span>' . \JText::_('JGLOBAL_HELPREFRESH_BUTTON')
. '</span>
					</button>';

		return $html . $button;
	}
}
Field/LastvisitdaterangeField.php000064400000002763151160211170013104
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Field to show a list of available date ranges to filter on last visit
date.
 *
 * @since  3.6
 */
class LastvisitdaterangeField extends \JFormFieldPredefinedList
{
	/**
	 * 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)
	{
		parent::__construct($form);

		// Set the type
		$this->type = 'LastvisitDateRange';

		// Load the required language
		$lang = Factory::getLanguage();
		$lang->load('com_users', JPATH_ADMINISTRATOR);

		// Set the pre-defined options
		$this->predefinedOptions = array(
			'today'       => 'COM_USERS_OPTION_RANGE_TODAY',
			'past_week'   =>
'COM_USERS_OPTION_RANGE_PAST_WEEK',
			'past_1month' =>
'COM_USERS_OPTION_RANGE_PAST_1MONTH',
			'past_3month' =>
'COM_USERS_OPTION_RANGE_PAST_3MONTH',
			'past_6month' =>
'COM_USERS_OPTION_RANGE_PAST_6MONTH',
			'past_year'   =>
'COM_USERS_OPTION_RANGE_PAST_YEAR',
			'post_year'   =>
'COM_USERS_OPTION_RANGE_POST_YEAR',
			'never'       => 'COM_USERS_OPTION_RANGE_NEVER',
		);
	}
}
Field/LimitboxField.php000064400000004374151160211170011036
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Field to load a list of posible item count limits
 *
 * @since  3.2
 */
class LimitboxField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.2
	 */
	public $type = 'Limitbox';

	/**
	 * Cached array of the category items.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected static $options = array();

	/**
	 * Default options
	 *
	 * @var  array
	 */
	protected $defaultLimits = array(5, 10, 15, 20, 25, 30, 50, 100, 200,
500);

	/**
	 * Method to get the options to populate to populate list
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.2
	 */
	protected function getOptions()
	{
		// Accepted modifiers
		$hash = md5($this->element->asXML());

		if (!isset(static::$options[$hash]))
		{
			static::$options[$hash] = parent::getOptions();

			$options = array();
			$limits = $this->defaultLimits;

			// Limits manually specified
			if (isset($this->element['limits']))
			{
				$limits = explode(',',
$this->element['limits']);
			}

			// User wants to add custom limits
			if (isset($this->element['append']))
			{
				$limits = array_unique(array_merge($limits, explode(',',
$this->element['append'])));
			}

			// User wants to remove some default limits
			if (isset($this->element['remove']))
			{
				$limits = array_diff($limits, explode(',',
$this->element['remove']));
			}

			// Order the options
			asort($limits);

			// Add an option to show all?
			$showAll = isset($this->element['showall']) ? (string)
$this->element['showall'] === 'true' : true;

			if ($showAll)
			{
				$limits[] = 0;
			}

			if (!empty($limits))
			{
				foreach ($limits as $value)
				{
					$options[] = (object) array(
						'value' => $value,
						'text' => ($value != 0) ? \JText::_('J' .
$value) : \JText::_('JALL'),
					);
				}

				static::$options[$hash] = array_merge(static::$options[$hash],
$options);
			}
		}

		return static::$options[$hash];
	}
}
Field/MediaField.php000064400000014222151160211170010257 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Form\FormField;

/**
 * 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 authorField.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $preview;

	/**
	 * The preview.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $directory;

	/**
	 * The previewWidth.
	 *
	 * @var    int
	 * @since  3.2
	 */
	protected $previewWidth;

	/**
	 * The previewHeight.
	 *
	 * @var    int
	 * @since  3.2
	 */
	protected $previewHeight;

	/**
	 * Layout to render
	 *
	 * @var    string
	 * @since  3.5
	 */
	protected $layout = 'joomla.form.field.media';

	/**
	 * 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':
				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 'width':
			case 'height':
			case 'preview':
			case 'directory':
				$this->$name = (string) $value;
				break;

			case 'previewWidth':
			case 'previewHeight':
				$this->$name = (int) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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;
		}

		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 =
\JFactory::getApplication()->input->get('option');
		}

		if ($this->value && file_exists(JPATH_ROOT . '/' .
$this->value))
		{
			$this->folder = explode('/', $this->value);
			$this->folder = array_diff_assoc($this->folder,
explode('/',
ComponentHelper::getParams('com_media')->get('image_path',
'images')));
			array_pop($this->folder);
			$this->folder = implode('/', $this->folder);
		}
		elseif (file_exists(JPATH_ROOT . '/' .
ComponentHelper::getParams('com_media')->get('image_path',
'images') . '/' . $this->directory))
		{
			$this->folder = $this->directory;
		}
		else
		{
			$this->folder = '';
		}

		$extraData = array(
			'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,
		);

		return array_merge($data, $extraData);
	}
}
Field/MenuField.php000064400000005603151160211170010147 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

// Import the com_menus helper.
require_once realpath(JPATH_ADMINISTRATOR .
'/components/com_menus/helpers/menus.php');

FormHelper::loadFieldClass('GroupedList');

/**
 * Supports an HTML select list of menus
 *
 * @since  1.6
 */
class MenuField extends \JFormFieldGroupedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'Menu';

	/**
	 * Method to get the field option groups.
	 *
	 * @return  array  The field option objects as a nested array in groups.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	protected function getGroups()
	{
		$clientId   = (string) $this->element['clientid'];
		$accessType = (string) $this->element['accesstype'];
		$showAll    = (string) $this->element['showAll'] ==
'true';

		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->qn(array('id', 'menutype',
'title', 'client_id'), array('id',
'value', 'text', 'client_id')))
			->from($db->quoteName('#__menu_types'))
			->order('client_id, title');

		if (strlen($clientId))
		{
			$query->where('client_id = ' . (int) $clientId);
		}

		$menus = $db->setQuery($query)->loadObjectList();

		if ($accessType)
		{
			$user = Factory::getUser();

			foreach ($menus as $key => $menu)
			{
				switch ($accessType)
				{
					case 'create':
					case 'manage':
						if (!$user->authorise('core.' . $accessType,
'com_menus.menu.' . (int) $menu->id))
						{
							unset($menus[$key]);
						}
						break;

					// Editing a menu item is a bit tricky, we have to check the current
menutype for core.edit and all others for core.create
					case 'edit':
						$check = $this->value == $menu->value ? 'edit' :
'create';

						if (!$user->authorise('core.' . $check,
'com_menus.menu.' . (int) $menu->id))
						{
							unset($menus[$key]);
						}
						break;
				}
			}
		}

		$opts = array();

		// Protected menutypes can be shown if requested
		if ($clientId == 1 && $showAll)
		{
			$opts[] = (object) array(
				'value'     => 'main',
				'text'      =>
\JText::_('COM_MENUS_MENU_TYPE_PROTECTED_MAIN_LABEL'),
				'client_id' => 1,
			);
		}

		$options = array_merge($opts, $menus);
		$groups  = array();

		if (strlen($clientId))
		{
			$groups[0] = $options;
		}
		else
		{
			foreach ($options as $option)
			{
				// If client id is not specified we group the items.
				$label = ($option->client_id == 1 ?
\JText::_('JADMINISTRATOR') : \JText::_('JSITE'));

				$groups[$label][] = $option;
			}
		}

		// Merge any additional options in the XML definition.
		return array_merge(parent::getGroups(), $groups);
	}
}
Field/MenuitemField.php000064400000013637151160211170011034
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('groupedlist');

// Import the com_menus helper.
require_once realpath(JPATH_ADMINISTRATOR .
'/components/com_menus/helpers/menus.php');

/**
 * Supports an HTML grouped select list of menu item grouped by menu
 *
 * @since  1.6
 */
class MenuitemField extends \JFormFieldGroupedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'MenuItem';

	/**
	 * The menu type.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $menuType;

	/**
	 * The client id.
	 *
	 * @var    string
	 * @since  3.2
	 */
	protected $clientId;

	/**
	 * The language.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $language;

	/**
	 * The published status.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $published;

	/**
	 * The disabled status.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected $disable;

	/**
	 * 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 'menuType':
			case 'clientId':
			case 'language':
			case 'published':
			case 'disable':
				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 'menuType':
				$this->menuType = (string) $value;
				break;

			case 'clientId':
				$this->clientId = (int) $value;
				break;

			case 'language':
			case 'published':
			case 'disable':
				$value = (string) $value;
				$this->$name = $value ? explode(',', $value) : array();
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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)
		{
			$this->menuType  = (string) $this->element['menu_type'];
			$this->clientId  = (int) $this->element['client_id'];
			$this->published = $this->element['published'] ?
explode(',', (string) $this->element['published']) :
array();
			$this->disable   = $this->element['disable'] ?
explode(',', (string) $this->element['disable']) :
array();
			$this->language  = $this->element['language'] ?
explode(',', (string) $this->element['language']) :
array();
		}

		return $result;
	}

	/**
	 * Method to get the field option groups.
	 *
	 * @return  array  The field option objects as a nested array in groups.
	 *
	 * @since   1.6
	 */
	protected function getGroups()
	{
		$groups = array();

		$menuType = $this->menuType;

		// Get the menu items.
		$items = \MenusHelper::getMenuLinks($menuType, 0, 0, $this->published,
$this->language, $this->clientId);

		// Build group for a specific menu type.
		if ($menuType)
		{
			// If the menutype is empty, group the items by menutype.
			$db    = Factory::getDbo();
			$query = $db->getQuery(true)
				->select($db->quoteName('title'))
				->from($db->quoteName('#__menu_types'))
				->where($db->quoteName('menutype') . ' = ' .
$db->quote($menuType));
			$db->setQuery($query);

			try
			{
				$menuTitle = $db->loadResult();
			}
			catch (\RuntimeException $e)
			{
				$menuTitle = $menuType;
			}

			// Initialize the group.
			$groups[$menuTitle] = array();

			// Build the options array.
			foreach ($items as $link)
			{
				$levelPrefix = str_repeat('- ', max(0, $link->level - 1));

				// Displays language code if not set to All
				if ($link->language !== '*')
				{
					$lang = ' (' . $link->language . ')';
				}
				else
				{
					$lang = '';
				}

				$groups[$menuTitle][] = \JHtml::_('select.option',
								$link->value, $levelPrefix . $link->text . $lang,
								'value',
								'text',
								in_array($link->type, $this->disable)
							);
			}
		}
		// Build groups for all menu types.
		else
		{
			// Build the groups arrays.
			foreach ($items as $menu)
			{
				// Initialize the group.
				$groups[$menu->title] = array();

				// Build the options array.
				foreach ($menu->links as $link)
				{
					$levelPrefix = str_repeat('- ', max(0, $link->level -
1));

					// Displays language code if not set to All
					if ($link->language !== '*')
					{
						$lang = ' (' . $link->language . ')';
					}
					else
					{
						$lang = '';
					}

					$groups[$menu->title][] = \JHtml::_('select.option',
										$link->value, $levelPrefix . $link->text . $lang,
										'value',
										'text',
										in_array($link->type, $this->disable)
									);
				}
			}
		}

		// Merge any additional groups in the XML definition.
		$groups = array_merge(parent::getGroups(), $groups);

		return $groups;
	}
}
Field/ModuleorderField.php000064400000006457151160211170011534
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormField;
use Joomla\CMS\Session\Session;

/**
 * Module Order field.
 *
 * @since  1.6
 */
class ModuleorderField extends FormField
{
	/**
	 * The form field type.
	 *
	 * @var     string
	 * @since   1.6
	 */
	protected $type = 'ModuleOrder';

	/**
	 * Name of the layout being used to render the field
	 *
	 * @var    string
	 * @since  3.6.3
	 */
	protected $layout = 'joomla.form.field.moduleorder';

	/**
	 * 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.3
	 */
	public function __get($name)
	{
		switch ($name)
		{
			case 'linked':
				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.3
	 */
	public function __set($name, $value)
	{
		switch ($name)
		{
			case 'linked':
				$this->$name = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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.6.3
	 */
	public function setup(\SimpleXMLElement $element, $value, $group = null)
	{
		$return = parent::setup($element, $value, $group);

		if ($return)
		{
			$this->linked    = isset($this->element['linked']) ?
(int) $this->element['linked'] : 'position';
		}

		return $return;
	}

	/**
	 * Method to get the field input markup for the moduleorder field.
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   1.6
	 */
	protected function getInput()
	{
		return
$this->getRenderer($this->layout)->render($this->getLayoutData());
	}

	/**
	 * Method to get the data to be passed to the layout for rendering.
	 *
	 * @return  array
	 *
	 * @since  3.6.3
	 */
	protected function getLayoutData()
	{
		$data = parent::getLayoutData();

		$extraData = array(
			'ordering' =>
$this->form->getValue('ordering'),
			'clientId' =>
$this->form->getValue('client_id'),
			'moduleId' => $this->form->getValue('id'),
			'name'     => $this->name,
			'token'    => Session::getFormToken() . '=1',
			'element'  => $this->form->getName() . '_'
. $this->linked
		);

		return array_merge($data, $extraData);
	}
}
Field/ModulepositionField.php000064400000010112151160211170012244
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('text');

/**
 * Module Position field.
 *
 * @since  1.6
 */
class ModulepositionField extends \JFormFieldText
{
	/**
	 * 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)
	{
		switch ($name)
		{
			case '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 = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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()
	{
		// Load the modal behavior script.
		\JHtml::_('behavior.modal', 'a.modal');

		// Build the script.
		$script = array();
		$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 = array();
		$link =
'index.php?option=com_modules&view=positions&layout=modal&tmpl=component&function=jSelectPosition_'
. $this->id
			. '&amp;client_id=' . $this->clientId;

		// The current user display field.
		$html[] = '<div class="input-append">';
		$html[] = parent::getInput()
			. '<a class="btn modal" title="' .
\JText::_('COM_MODULES_CHANGE_POSITION_TITLE') . '" 
href="' . $link
			. '" rel="{handler: \'iframe\', size: {x: 800,
y: 450}}">'
			. \JText::_('COM_MODULES_CHANGE_POSITION_BUTTON') .
'</a>';
		$html[] = '</div>';

		return implode("\n", $html);
	}
}
Field/ModuletagField.php000064400000002046151160211170011162
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('list');

/**
 * Module Tag field.
 *
 * @since  3.0
 */
class ModuletagField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.0
	 */
	protected $type = 'ModuleTag';

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.0
	 */
	protected function getOptions()
	{
		$options = array();
		$tags    = array('address', 'article',
'aside', 'details', 'div',
'footer', 'header', 'main', 'nav',
'section', 'summary');

		// Create one new option object for each tag
		foreach ($tags as $tag)
		{
			$tmp = \JHtml::_('select.option', $tag, $tag);
			$options[] = $tmp;
		}

		reset($options);

		return $options;
	}
}
Field/OrderingField.php000064400000011275151160211170011016
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\UCM\UCMType;

/**
 * Ordering field.
 *
 * @since  3.2
 */
class OrderingField extends FormField
{
	/**
	 * The form field type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $type = 'Ordering';

	/**
	 * The form field content type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $contentType;

	/**
	 * 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 'contentType':
				return $this->contentType;
		}

		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 'contentType':
				$this->contentType = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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)
		{
			$this->contentType = (string)
$this->element['content_type'];
		}

		return $result;
	}

	/**
	 * Method to get the field input markup.
	 *
	 * @return  string	The field input markup.
	 *
	 * @since   3.2
	 */
	protected function getInput()
	{
		$html = array();
		$attr = '';

		// Initialize some field attributes.
		$attr .= !empty($this->class) ? ' class="' .
$this->class . '"' : '';
		$attr .= $this->disabled ? ' disabled' : '';
		$attr .= !empty($this->size) ? ' size="' .
$this->size . '"' : '';

		// Initialize JavaScript field attributes.
		$attr .= !empty($this->onchange) ? ' onchange="' .
$this->onchange . '"' : '';

		$itemId = (int) $this->getItemId();

		$query = $this->getQuery();

		// Create a read-only list (no name) with a hidden input to store the
value.
		if ($this->readonly)
		{
			$html[] = \JHtml::_('list.ordering', '', $query,
trim($attr), $this->value, $itemId ? 0 : 1);
			$html[] = '<input type="hidden" name="' .
$this->name . '" value="' . $this->value .
'"/>';
		}
		else
		{
			// Create a regular list.
			$html[] = \JHtml::_('list.ordering', $this->name, $query,
trim($attr), $this->value, $itemId ? 0 : 1);
		}

		return implode($html);
	}

	/**
	 * Builds the query for the ordering list.
	 *
	 * @return  \JDatabaseQuery  The query for the ordering form field
	 *
	 * @since   3.2
	 */
	protected function getQuery()
	{
		$categoryId   = (int) $this->form->getValue('catid');
		$ucmType      = new UCMType;
		$ucmRow       =
$ucmType->getType($ucmType->getTypeId($this->contentType));
		$ucmMapCommon = json_decode($ucmRow->field_mappings)->common;

		if (is_object($ucmMapCommon))
		{
			$ordering = $ucmMapCommon->core_ordering;
			$title    = $ucmMapCommon->core_title;
		}
		elseif (is_array($ucmMapCommon))
		{
			$ordering = $ucmMapCommon[0]->core_ordering;
			$title    = $ucmMapCommon[0]->core_title;
		}

		$db    = Factory::getDbo();
		$query = $db->getQuery(true);
		$query->select(array($db->quoteName($ordering, 'value'),
$db->quoteName($title, 'text')))
			->from($db->quoteName(json_decode($ucmRow->table)->special->dbtable))
			->where($db->quoteName('catid') . ' = ' .
(int) $categoryId)
			->order('ordering');

		return $query;
	}

	/**
	 * Retrieves the current Item's Id.
	 *
	 * @return  integer  The current item ID
	 *
	 * @since   3.2
	 */
	protected function getItemId()
	{
		return (int) $this->form->getValue('id');
	}
}
Field/PluginstatusField.php000064400000001353151160211170011743
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Plugin Status field.
 *
 * @since  3.5
 */
class PluginstatusField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.5
	 */
	public $type = 'Plugin_Status';

	/**
	 * Available statuses
	 *
	 * @var  array
	 * @since  3.5
	 */
	protected $predefinedOptions = array(
		'0'  => 'JDISABLED',
		'1'  => 'JENABLED',
	);
}
Field/RedirectStatusField.php000064400000001466151160211170012213
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Redirect Status field.
 *
 * @since  3.8.0
 */
class RedirectStatusField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.8.0
	 */
	public $type = 'Redirect_Status';

	/**
	 * Available statuses
	 *
	 * @var  array
	 * @since  3.8.0
	 */
	protected $predefinedOptions = array(
		'-2' => 'JTRASHED',
		'0'  => 'JDISABLED',
		'1'  => 'JENABLED',
		'2'  => 'JARCHIVED',
		'*'  => 'JALL',
	);
}
Field/RegistrationdaterangeField.php000064400000002760151160211170013571
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Registration Date Range field.
 *
 * @since  3.2
 */
class RegistrationdaterangeField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $type = 'RegistrationDateRange';

	/**
	 * Available options
	 *
	 * @var  array
	 * @since  3.2
	 */
	protected $predefinedOptions = array(
		'today'       => 'COM_USERS_OPTION_RANGE_TODAY',
		'past_week'   =>
'COM_USERS_OPTION_RANGE_PAST_WEEK',
		'past_1month' =>
'COM_USERS_OPTION_RANGE_PAST_1MONTH',
		'past_3month' =>
'COM_USERS_OPTION_RANGE_PAST_3MONTH',
		'past_6month' =>
'COM_USERS_OPTION_RANGE_PAST_6MONTH',
		'past_year'   =>
'COM_USERS_OPTION_RANGE_PAST_YEAR',
		'post_year'   =>
'COM_USERS_OPTION_RANGE_POST_YEAR',
	);

	/**
	 * 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)
	{
		parent::__construct($form);

		// Load the required language
		$lang = Factory::getLanguage();
		$lang->load('com_users', JPATH_ADMINISTRATOR);
	}
}
Field/StatusField.php000064400000001454151160211170010526 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Form Field to load a list of states
 *
 * @since  3.2
 */
class StatusField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.2
	 */
	public $type = 'Status';

	/**
	 * Available statuses
	 *
	 * @var  array
	 * @since  3.2
	 */
	protected $predefinedOptions = array(
		-2  => 'JTRASHED',
		0   => 'JUNPUBLISHED',
		1   => 'JPUBLISHED',
		2   => 'JARCHIVED',
		'*' => 'JALL',
	);
}
Field/TagField.php000064400000013073151160211170007756 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\Helper\TagsHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\Utilities\ArrayHelper;

FormHelper::loadFieldClass('list');

/**
 * List of Tags field.
 *
 * @since  3.1
 */
class TagField extends \JFormFieldList
{
	/**
	 * A flexible tag list that respects access controls
	 *
	 * @var    string
	 * @since  3.1
	 */
	public $type = 'Tag';

	/**
	 * Flag to work with nested tag field
	 *
	 * @var    boolean
	 * @since  3.1
	 */
	public $isNested = null;

	/**
	 * com_tags parameters
	 *
	 * @var    \Joomla\Registry\Registry
	 * @since  3.1
	 */
	protected $comParams = null;

	/**
	 * Constructor
	 *
	 * @since  3.1
	 */
	public function __construct()
	{
		parent::__construct();

		// Load com_tags config
		$this->comParams = ComponentHelper::getParams('com_tags');
	}

	/**
	 * Method to get the field input for a tag field.
	 *
	 * @return  string  The field input.
	 *
	 * @since   3.1
	 */
	protected function getInput()
	{
		// AJAX mode requires ajax-chosen
		if (!$this->isNested())
		{
			// Get the field id
			$id    = isset($this->element['id']) ?
$this->element['id'] : null;
			$cssId = '#' . $this->getId($id,
$this->element['name']);

			// Load the ajax-chosen customised field
			\JHtml::_('tag.ajaxfield', $cssId, $this->allowCustom());
		}

		if (!is_array($this->value) && !empty($this->value))
		{
			if ($this->value instanceof TagsHelper)
			{
				if (empty($this->value->tags))
				{
					$this->value = array();
				}
				else
				{
					$this->value = $this->value->tags;
				}
			}

			// String in format 2,5,4
			if (is_string($this->value))
			{
				$this->value = explode(',', $this->value);
			}
		}

		return parent::getInput();
	}

	/**
	 * Method to get a list of tags
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.1
	 */
	protected function getOptions()
	{
		$published = $this->element['published'] ?: array(0, 1);
		$app       = Factory::getApplication();
		$tag       = $app->getLanguage()->getTag();

		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT a.id AS value, a.path, a.title AS text,
a.level, a.published, a.lft')
			->from('#__tags AS a')
			->join('LEFT', $db->qn('#__tags') . ' AS
b ON a.lft > b.lft AND a.rgt < b.rgt');

		// Limit Options in multilanguage
		if ($app->isClient('site') &&
Multilanguage::isEnabled())
		{
			$lang =
ComponentHelper::getParams('com_tags')->get('tag_list_language_filter');

			if ($lang == 'current_language')
			{
				$query->where('a.language in (' . $db->quote($tag) .
',' . $db->quote('*') . ')');
			}
		}
		// Filter language
		elseif (!empty($this->element['language']))
		{
			if (strpos($this->element['language'], ',') !==
false)
			{
				$language = implode(',', $db->quote(explode(',',
$this->element['language'])));
			}
			else
			{
				$language = $db->quote($this->element['language']);
			}

			$query->where($db->quoteName('a.language') . ' IN
(' . $language . ')');
		}

		$query->where($db->qn('a.lft') . ' > 0');

		// Filter on the published state
		if (is_numeric($published))
		{
			$query->where('a.published = ' . (int) $published);
		}
		elseif (is_array($published))
		{
			$published = ArrayHelper::toInteger($published);
			$query->where('a.published IN (' . implode(',',
$published) . ')');
		}

		$query->order('a.lft ASC');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$options = $db->loadObjectList();
		}
		catch (\RuntimeException $e)
		{
			return array();
		}

		// Block the possibility to set a tag as it own parent
		if ($this->form->getName() === 'com_tags.tag')
		{
			$id   = (int) $this->form->getValue('id', 0);

			foreach ($options as $option)
			{
				if ($option->value == $id)
				{
					$option->disable = true;
				}
			}
		}

		// Merge any additional options in the XML definition.
		$options = array_merge(parent::getOptions(), $options);

		// Prepare nested data
		if ($this->isNested())
		{
			$this->prepareOptionsNested($options);
		}
		else
		{
			$options = TagsHelper::convertPathsToNames($options);
		}

		return $options;
	}

	/**
	 * Add "-" before nested tags, depending on level
	 *
	 * @param   array  &$options  Array of tags
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.1
	 */
	protected function prepareOptionsNested(&$options)
	{
		if ($options)
		{
			foreach ($options as &$option)
			{
				$repeat = (isset($option->level) && $option->level - 1
>= 0) ? $option->level - 1 : 0;
				$option->text = str_repeat('- ', $repeat) .
$option->text;
			}
		}

		return $options;
	}

	/**
	 * Determine if the field has to be tagnested
	 *
	 * @return  boolean
	 *
	 * @since   3.1
	 */
	public function isNested()
	{
		if ($this->isNested === null)
		{
			// If mode="nested" || ( mode not set & config = nested )
			if (isset($this->element['mode']) && (string)
$this->element['mode'] === 'nested'
				|| !isset($this->element['mode']) &&
$this->comParams->get('tag_field_ajax_mode', 1) == 0)
			{
				$this->isNested = true;
			}
		}

		return $this->isNested;
	}

	/**
	 * Determines if the field allows or denies custom values
	 *
	 * @return  boolean
	 */
	public function allowCustom()
	{
		if (isset($this->element['custom']) && (string)
$this->element['custom'] === 'deny')
		{
			return false;
		}

		return true;
	}
}
Field/TemplatestyleField.php000064400000011237151160211170012077
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('groupedlist');

/**
 * Supports a select grouped list of template styles
 *
 * @since  1.6
 */
class TemplatestyleField extends \JFormFieldGroupedList
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'TemplateStyle';

	/**
	 * The client name.
	 *
	 * @var    mixed
	 * @since  3.2
	 */
	protected $clientName;

	/**
	 * The template.
	 *
	 * @var    mixed
	 * @since  3.2
	 */
	protected $template;

	/**
	 * 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 'clientName':
			case 'template':
				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 'clientName':
			case 'template':
				$this->$name = (string) $value;
				break;

			default:
				parent::__set($name, $value);
		}
	}

	/**
	 * Method to attach a JForm 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 clientName template.
			$this->clientName = $this->element['client'] ? (string)
$this->element['client'] : 'site';
			$this->template = (string) $this->element['template'];
		}

		return $result;
	}

	/**
	 * Method to get the list of template style options grouped by template.
	 * Use the client attribute to specify a specific client.
	 * Use the template attribute to specify a specific template
	 *
	 * @return  array  The field option objects as a nested array in groups.
	 *
	 * @since   1.6
	 */
	protected function getGroups()
	{
		$groups = array();
		$lang = Factory::getLanguage();

		// Get the client and client_id.
		$client = ApplicationHelper::getClientInfo($this->clientName, true);

		// Get the template.
		$template = $this->template;

		// Get the database object and a new query object.
		$db = Factory::getDbo();
		$query = $db->getQuery(true);

		// Build the query.
		$query->select('s.id, s.title, e.name as name, s.template')
			->from('#__template_styles as s')
			->where('s.client_id = ' . (int) $client->id)
			->order('template')
			->order('title');

		if ($template)
		{
			$query->where('s.template = ' . $db->quote($template));
		}

		$query->join('LEFT', '#__extensions as e on
e.element=s.template')
			->where('e.enabled = 1')
			->where($db->quoteName('e.type') . ' = ' .
$db->quote('template'));

		// Set the query and load the styles.
		$db->setQuery($query);
		$styles = $db->loadObjectList();

		// Build the grouped list array.
		if ($styles)
		{
			foreach ($styles as $style)
			{
				$template = $style->template;
				$lang->load('tpl_' . $template . '.sys',
$client->path, null, false, true)
					|| $lang->load('tpl_' . $template . '.sys',
$client->path . '/templates/' . $template, null, false, true);
				$name = \JText::_($style->name);

				// Initialize the group if necessary.
				if (!isset($groups[$name]))
				{
					$groups[$name] = array();
				}

				$groups[$name][] = \JHtml::_('select.option', $style->id,
$style->title);
			}
		}

		// Merge any additional groups in the XML definition.
		$groups = array_merge(parent::getGroups(), $groups);

		return $groups;
	}
}
Field/UseractiveField.php000064400000002264151160211170011355
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Field to show a list of available user active statuses
 *
 * @since  3.2
 */
class UseractiveField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $type = 'UserActive';

	/**
	 * Available statuses
	 *
	 * @var  array
	 * @since  3.2
	 */
	protected $predefinedOptions = array(
		'0'  => 'COM_USERS_ACTIVATED',
		'1'  => 'COM_USERS_UNACTIVATED',
	);

	/**
	 * 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)
	{
		parent::__construct($form);

		// Load the required language
		$lang = Factory::getLanguage();
		$lang->load('com_users', JPATH_ADMINISTRATOR);
	}
}
Field/UserField.php000064400000007552151160211170010166 0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\User\User;

/**
 * Field to select a user ID from a modal list.
 *
 * @since  1.6
 */
class UserField extends FormField
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  1.6
	 */
	public $type = 'User';

	/**
	 * Filtering groups
	 *
	 * @var   array
	 * @since 3.5
	 */
	protected $groups = null;

	/**
	 * Users to exclude from the list of users
	 *
	 * @var   array
	 * @since 3.5
	 */
	protected $excluded = null;

	/**
	 * Layout to render
	 *
	 * @var   string
	 * @since 3.5
	 */
	protected $layout = 'joomla.form.field.user';

	/**
	 * Method to attach a JForm 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   3.7.0
	 *
	 * @see     JFormField::setup()
	 */
	public function setup(\SimpleXMLElement $element, $value, $group = null)
	{
		$return = parent::setup($element, $value, $group);

		// If user can't access com_users the field should be readonly.
		if ($return && !$this->readonly)
		{
			$this->readonly =
!Factory::getUser()->authorise('core.manage',
'com_users');
		}

		return $return;
	}

	/**
	 * Method to get the user field input markup.
	 *
	 * @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
	 *
	 * @since   3.5
	 */
	public function getLayoutData()
	{
		// Get the basic field data
		$data = parent::getLayoutData();

		// Initialize value
		$name = \JText::_('JLIB_FORM_SELECT_USER');

		if (is_numeric($this->value))
		{
			$name = User::getInstance($this->value)->name;
		}
		// Handle the special case for "current".
		elseif (strtoupper($this->value) === 'CURRENT')
		{
			// 'CURRENT' is not a reasonable value to be placed in the
html
			$current = Factory::getUser();

			$this->value = $current->id;

			$data['value'] = $this->value;

			$name = $current->name;
		}

		// User lookup went wrong, we assign the value instead.
		if ($name === null && $this->value)
		{
			$name = $this->value;
		}

		$extraData = array(
			'userName'  => $name,
			'groups'    => $this->getGroups(),
			'excluded'  => $this->getExcluded(),
		);

		return array_merge($data, $extraData);
	}

	/**
	 * Method to get the filtering groups (null means no filtering)
	 *
	 * @return  mixed  Array of filtering groups or null.
	 *
	 * @since   1.6
	 */
	protected function getGroups()
	{
		if (isset($this->element['groups']))
		{
			return explode(',', $this->element['groups']);
		}

		return;
	}

	/**
	 * Method to get the users to exclude from the list of users
	 *
	 * @return  mixed  Array of users to exclude or null to to not exclude
them
	 *
	 * @since   1.6
	 */
	protected function getExcluded()
	{
		if (isset($this->element['exclude']))
		{
			return explode(',', $this->element['exclude']);
		}

		return;
	}
}
Field/UsergrouplistField.php000064400000005364151160211170012136
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\Helper\UserGroupsHelper;

FormHelper::loadFieldClass('list');

/**
 * Field to load a dropdown list of available user groups
 *
 * @since  3.2
 */
class UsergrouplistField extends \JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $type = 'UserGroupList';

	/**
	 * Cached array of the category items.
	 *
	 * @var    array
	 * @since  3.2
	 */
	protected static $options = array();

	/**
	 * Method to attach a JForm 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)
	{
		if (is_string($value) && strpos($value, ',') !== false)
		{
			$value = explode(',', $value);
		}

		return parent::setup($element, $value, $group);
	}

	/**
	 * Method to get the options to populate list
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.2
	 */
	protected function getOptions()
	{
		$options        = parent::getOptions();
		$checkSuperUser = (int)
$this->getAttribute('checksuperusergroup', 0);

		// Cache user groups base on checksuperusergroup attribute value
		if (!isset(static::$options[$checkSuperUser]))
		{
			$groups       = UserGroupsHelper::getInstance()->getAll();
			$isSuperUser  =
Factory::getUser()->authorise('core.admin');
			$cacheOptions = array();

			foreach ($groups as $group)
			{
				// Don't show super user groups to non super users.
				if ($checkSuperUser && !$isSuperUser &&
Access::checkGroup($group->id, 'core.admin'))
				{
					continue;
				}

				$cacheOptions[] = (object) array(
					'text'  => str_repeat('- ', $group->level) .
$group->title,
					'value' => $group->id,
					'level' => $group->level,
				);
			}

			static::$options[$checkSuperUser] = $cacheOptions;
		}

		return array_merge($options, static::$options[$checkSuperUser]);
	}
}
Field/UserstateField.php000064400000001402151160211170011213
0ustar00<?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\Field;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

/**
 * Field to load a list of available users statuses
 *
 * @since  3.2
 */
class UserstateField extends \JFormFieldPredefinedList
{
	/**
	 * The form field type.
	 *
	 * @var		string
	 * @since   3.2
	 */
	protected $type = 'UserState';

	/**
	 * Available statuses
	 *
	 * @var  array
	 * @since  3.2
	 */
	protected $predefinedOptions = array(
		'0'  => 'JENABLED',
		'1'  => 'JDISABLED',
	);
}
Form.php000064400000202143151160211170006155 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;

\JLoader::import('joomla.filesystem.path');

/**
 * Form Class for the Joomla Platform.
 *
 * This class implements a robust API for constructing, populating,
filtering, and validating forms.
 * It uses XML definitions to construct form fields and a variety of field
and rule classes to
 * render and validate the form.
 *
 * @link   http://www.w3.org/TR/html4/interact/forms.html
 * @link   http://www.w3.org/TR/html5/forms.html
 * @since  1.7.0
 */
class Form
{
	/**
	 * The Registry data store for form fields during display.
	 *
	 * @var    Registry
	 * @since  1.7.0
	 */
	protected $data;

	/**
	 * The form object errors array.
	 *
	 * @var    array
	 * @since  1.7.0
	 */
	protected $errors = array();

	/**
	 * The name of the form instance.
	 *
	 * @var    string
	 * @since  1.7.0
	 */
	protected $name;

	/**
	 * The form object options for use in rendering and validation.
	 *
	 * @var    array
	 * @since  1.7.0
	 */
	protected $options = array();

	/**
	 * The form XML definition.
	 *
	 * @var    \SimpleXMLElement
	 * @since  1.7.0
	 */
	protected $xml;

	/**
	 * Form instances.
	 *
	 * @var    Form[]
	 * @since  1.7.0
	 */
	protected static $forms = array();

	/**
	 * Alows extensions to implement repeating elements
	 *
	 * @var    boolean
	 * @since  3.2
	 */
	public $repeat = false;

	/**
	 * Method to instantiate the form object.
	 *
	 * @param   string  $name     The name of the form.
	 * @param   array   $options  An array of form options.
	 *
	 * @since   1.7.0
	 */
	public function __construct($name, array $options = array())
	{
		// Set the name for the form.
		$this->name = $name;

		// Initialise the Registry data.
		$this->data = new Registry;

		// Set the options if specified.
		$this->options['control'] =
isset($options['control']) ? $options['control'] :
false;
	}

	/**
	 * Method to bind data to the form.
	 *
	 * @param   mixed  $data  An array or object of data to bind to the form.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 */
	public function bind($data)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		// The data must be an object or array.
		if (!is_object($data) && !is_array($data))
		{
			return false;
		}

		$this->bindLevel(null, $data);

		return true;
	}

	/**
	 * Method to bind data to the form for the group level.
	 *
	 * @param   string  $group  The dot-separated form group path on which to
bind the data.
	 * @param   mixed   $data   An array or object of data to bind to the form
for the group level.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected function bindLevel($group, $data)
	{
		// Ensure the input data is an array.
		if (is_object($data))
		{
			if ($data instanceof Registry)
			{
				// Handle a Registry.
				$data = $data->toArray();
			}
			elseif ($data instanceof \JObject)
			{
				// Handle a JObject.
				$data = $data->getProperties();
			}
			else
			{
				// Handle other types of objects.
				$data = (array) $data;
			}
		}

		// Process the input data.
		foreach ($data as $k => $v)
		{
			$level = $group ? $group . '.' . $k : $k;

			if ($this->findField($k, $group))
			{
				// If the field exists set the value.
				$this->data->set($level, $v);
			}
			elseif (is_object($v) || ArrayHelper::isAssociative($v))
			{
				// If the value is an object or an associative array, hand it off to
the recursive bind level method.
				$this->bindLevel($level, $v);
			}
		}
	}

	/**
	 * Method to filter the form data.
	 *
	 * @param   array   $data   An array of field values to filter.
	 * @param   string  $group  The dot-separated form group path on which to
filter the fields.
	 *
	 * @return  mixed  Array or false.
	 *
	 * @since   1.7.0
	 */
	public function filter($data, $group = null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		$input = new Registry($data);
		$output = new Registry;

		// Get the fields for which to filter the data.
		$fields = $this->findFieldsByGroup($group);

		if (!$fields)
		{
			// PANIC!
			return false;
		}

		// Filter the fields.
		foreach ($fields as $field)
		{
			$name = (string) $field['name'];

			// Get the field groups for the element.
			$attrs = $field->xpath('ancestor::fields[@name]/@name');
			$groups = array_map('strval', $attrs ? $attrs : array());
			$group = implode('.', $groups);

			$key = $group ? $group . '.' . $name : $name;

			// Filter the value if it exists.
			if ($input->exists($key))
			{
				$output->set($key, $this->filterField($field,
$input->get($key, (string) $field['default'])));
			}
		}

		return $output->toArray();
	}

	/**
	 * Return all errors, if any.
	 *
	 * @return  array  Array of error messages or RuntimeException objects.
	 *
	 * @since   1.7.0
	 */
	public function getErrors()
	{
		return $this->errors;
	}

	/**
	 * Method to get a form field represented as a JFormField object.
	 *
	 * @param   string  $name   The name of the form field.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 * @param   mixed   $value  The optional value to use as the default for
the field.
	 *
	 * @return  \JFormField|boolean  The JFormField object for the field or
boolean false on error.
	 *
	 * @since   1.7.0
	 */
	public function getField($name, $group = null, $value = null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Attempt to find the field by name and group.
		$element = $this->findField($name, $group);

		// If the field element was not found return false.
		if (!$element)
		{
			return false;
		}

		return $this->loadField($element, $group, $value);
	}

	/**
	 * Method to get an attribute value from a field XML element.  If the
attribute doesn't exist or
	 * is null then the optional default value will be used.
	 *
	 * @param   string  $name       The name of the form field for which to
get the attribute value.
	 * @param   string  $attribute  The name of the attribute for which to get
a value.
	 * @param   mixed   $default    The optional default value to use if no
attribute value exists.
	 * @param   string  $group      The optional dot-separated form group path
on which to find the field.
	 *
	 * @return  mixed  The attribute value for the field.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function getFieldAttribute($name, $attribute, $default = null,
$group = null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::getFieldAttribute
`xml` is not an instance of SimpleXMLElement', get_class($this)));
		}

		// Find the form field element from the definition.
		$element = $this->findField($name, $group);

		// If the element exists and the attribute exists for the field return
the attribute value.
		if (($element instanceof \SimpleXMLElement) && strlen((string)
$element[$attribute]))
		{
			return (string) $element[$attribute];
		}

		// Otherwise return the given default value.
		else
		{
			return $default;
		}
	}

	/**
	 * Method to get an array of JFormField objects in a given fieldset by
name.  If no name is
	 * given then all fields are returned.
	 *
	 * @param   string  $set  The optional name of the fieldset.
	 *
	 * @return  \JFormField[]  The array of JFormField objects in the
fieldset.
	 *
	 * @since   1.7.0
	 */
	public function getFieldset($set = null)
	{
		$fields = array();

		// Get all of the field elements in the fieldset.
		if ($set)
		{
			$elements = $this->findFieldsByFieldset($set);
		}

		// Get all fields.
		else
		{
			$elements = $this->findFieldsByGroup();
		}

		// If no field elements were found return empty.
		if (empty($elements))
		{
			return $fields;
		}

		// Build the result array from the found field elements.
		foreach ($elements as $element)
		{
			// Get the field groups for the element.
			$attrs = $element->xpath('ancestor::fields[@name]/@name');
			$groups = array_map('strval', $attrs ? $attrs : array());
			$group = implode('.', $groups);

			// If the field is successfully loaded add it to the result array.
			if ($field = $this->loadField($element, $group))
			{
				$fields[$field->id] = $field;
			}
		}

		return $fields;
	}

	/**
	 * Method to get an array of fieldset objects optionally filtered over a
given field group.
	 *
	 * @param   string  $group  The dot-separated form group path on which to
filter the fieldsets.
	 *
	 * @return  array  The array of fieldset objects.
	 *
	 * @since   1.7.0
	 */
	public function getFieldsets($group = null)
	{
		$fieldsets = array();
		$sets = array();

		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return $fieldsets;
		}

		if ($group)
		{
			// Get the fields elements for a given group.
			$elements = &$this->findGroup($group);

			foreach ($elements as &$element)
			{
				// Get an array of <fieldset /> elements and fieldset attributes
within the fields element.
				if ($tmp = $element->xpath('descendant::fieldset[@name] |
descendant::field[@fieldset]/@fieldset'))
				{
					$sets = array_merge($sets, (array) $tmp);
				}
			}
		}
		else
		{
			// Get an array of <fieldset /> elements and fieldset attributes.
			$sets = $this->xml->xpath('//fieldset[@name and
not(ancestor::field/form/*)] | //field[@fieldset and
not(ancestor::field/form/*)]/@fieldset');
		}

		// If no fieldsets are found return empty.
		if (empty($sets))
		{
			return $fieldsets;
		}

		// Process each found fieldset.
		foreach ($sets as $set)
		{
			if ((string) $set['hidden'] == 'true')
			{
				continue;
			}

			// Are we dealing with a fieldset element?
			if ((string) $set['name'])
			{
				// Only create it if it doesn't already exist.
				if (empty($fieldsets[(string) $set['name']]))
				{
					// Build the fieldset object.
					$fieldset = (object) array('name' => '',
'label' => '', 'description' =>
'');

					foreach ($set->attributes() as $name => $value)
					{
						$fieldset->$name = (string) $value;
					}

					// Add the fieldset object to the list.
					$fieldsets[$fieldset->name] = $fieldset;
				}
			}

			// Must be dealing with a fieldset attribute.
			else
			{
				// Only create it if it doesn't already exist.
				if (empty($fieldsets[(string) $set]))
				{
					// Attempt to get the fieldset element for data (throughout the entire
form document).
					$tmp = $this->xml->xpath('//fieldset[@name="' .
(string) $set . '"]');

					// If no element was found, build a very simple fieldset object.
					if (empty($tmp))
					{
						$fieldset = (object) array('name' => (string) $set,
'label' => '', 'description' =>
'');
					}

					// Build the fieldset object from the element.
					else
					{
						$fieldset = (object) array('name' => '',
'label' => '', 'description' =>
'');

						foreach ($tmp[0]->attributes() as $name => $value)
						{
							$fieldset->$name = (string) $value;
						}
					}

					// Add the fieldset object to the list.
					$fieldsets[$fieldset->name] = $fieldset;
				}
			}
		}

		return $fieldsets;
	}

	/**
	 * Method to get the form control. This string serves as a container for
all form fields. For
	 * example, if there is a field named 'foo' and a field named
'bar' and the form control is
	 * empty the fields will be rendered like: `<input name="foo"
/>` and `<input name="bar" />`.  If
	 * the form control is set to 'joomla' however, the fields would
be rendered like:
	 * `<input name="joomla[foo]" />` and `<input
name="joomla[bar]" />`.
	 *
	 * @return  string  The form control string.
	 *
	 * @since   1.7.0
	 */
	public function getFormControl()
	{
		return (string) $this->options['control'];
	}

	/**
	 * Method to get an array of JFormField objects in a given field group by
name.
	 *
	 * @param   string   $group   The dot-separated form group path for which
to get the form fields.
	 * @param   boolean  $nested  True to also include fields in nested groups
that are inside of the
	 *                            group for which to find fields.
	 *
	 * @return  \JFormField[]  The array of JFormField objects in the field
group.
	 *
	 * @since   1.7.0
	 */
	public function getGroup($group, $nested = false)
	{
		$fields = array();

		// Get all of the field elements in the field group.
		$elements = $this->findFieldsByGroup($group, $nested);

		// If no field elements were found return empty.
		if (empty($elements))
		{
			return $fields;
		}

		// Build the result array from the found field elements.
		foreach ($elements as $element)
		{
			// Get the field groups for the element.
			$attrs  = $element->xpath('ancestor::fields[@name]/@name');
			$groups = array_map('strval', $attrs ? $attrs : array());
			$group  = implode('.', $groups);

			// If the field is successfully loaded add it to the result array.
			if ($field = $this->loadField($element, $group))
			{
				$fields[$field->id] = $field;
			}
		}

		return $fields;
	}

	/**
	 * Method to get a form field markup for the field input.
	 *
	 * @param   string  $name   The name of the form field.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 * @param   mixed   $value  The optional value to use as the default for
the field.
	 *
	 * @return  string  The form field markup.
	 *
	 * @since   1.7.0
	 */
	public function getInput($name, $group = null, $value = null)
	{
		// Attempt to get the form field.
		if ($field = $this->getField($name, $group, $value))
		{
			return $field->input;
		}

		return '';
	}

	/**
	 * Method to get the label for a field input.
	 *
	 * @param   string  $name   The name of the form field.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 *
	 * @return  string  The form field label.
	 *
	 * @since   1.7.0
	 */
	public function getLabel($name, $group = null)
	{
		// Attempt to get the form field.
		if ($field = $this->getField($name, $group))
		{
			return $field->label;
		}

		return '';
	}

	/**
	 * Method to get the form name.
	 *
	 * @return  string  The name of the form.
	 *
	 * @since   1.7.0
	 */
	public function getName()
	{
		return $this->name;
	}

	/**
	 * Method to get the value of a field.
	 *
	 * @param   string  $name     The name of the field for which to get the
value.
	 * @param   string  $group    The optional dot-separated form group path
on which to get the value.
	 * @param   mixed   $default  The optional default value of the field
value is empty.
	 *
	 * @return  mixed  The value of the field or the default value if empty.
	 *
	 * @since   1.7.0
	 */
	public function getValue($name, $group = null, $default = null)
	{
		// If a group is set use it.
		if ($group)
		{
			$return = $this->data->get($group . '.' . $name,
$default);
		}
		else
		{
			$return = $this->data->get($name, $default);
		}

		return $return;
	}

	/**
	 * Method to get a control group with label and input.
	 *
	 * @param   string  $name     The name of the field for which to get the
value.
	 * @param   string  $group    The optional dot-separated form group path
on which to get the value.
	 * @param   mixed   $default  The optional default value of the field
value is empty.
	 *
	 * @return  string  A string containing the html for the control goup
	 *
	 * @since      3.2
	 * @deprecated 3.2.3  Use renderField() instead of getControlGroup
	 */
	public function getControlGroup($name, $group = null, $default = null)
	{
		\JLog::add('Form->getControlGroup() is deprecated use
Form->renderField().', \JLog::WARNING, 'deprecated');

		return $this->renderField($name, $group, $default);
	}

	/**
	 * Method to get all control groups with label and input of a fieldset.
	 *
	 * @param   string  $name  The name of the fieldset for which to get the
values.
	 *
	 * @return  string  A string containing the html for the control goups
	 *
	 * @since      3.2
	 * @deprecated 3.2.3 Use renderFieldset() instead of getControlGroups
	 */
	public function getControlGroups($name)
	{
		\JLog::add('Form->getControlGroups() is deprecated use
Form->renderFieldset().', \JLog::WARNING, 'deprecated');

		return $this->renderFieldset($name);
	}

	/**
	 * Method to get a control group with label and input.
	 *
	 * @param   string  $name     The name of the field for which to get the
value.
	 * @param   string  $group    The optional dot-separated form group path
on which to get the value.
	 * @param   mixed   $default  The optional default value of the field
value is empty.
	 * @param   array   $options  Any options to be passed into the rendering
of the field
	 *
	 * @return  string  A string containing the html for the control goup
	 *
	 * @since   3.2.3
	 */
	public function renderField($name, $group = null, $default = null,
$options = array())
	{
		$field = $this->getField($name, $group, $default);

		if ($field)
		{
			return $field->renderField($options);
		}

		return '';
	}

	/**
	 * Method to get all control groups with label and input of a fieldset.
	 *
	 * @param   string  $name     The name of the fieldset for which to get
the values.
	 * @param   array   $options  Any options to be passed into the rendering
of the field
	 *
	 * @return  string  A string containing the html for the control goups
	 *
	 * @since   3.2.3
	 */
	public function renderFieldset($name, $options = array())
	{
		$fields = $this->getFieldset($name);
		$html = array();

		foreach ($fields as $field)
		{
			$html[] = $field->renderField($options);
		}

		return implode('', $html);
	}

	/**
	 * Method to load the form description from an XML string or object.
	 *
	 * The replace option works per field.  If a field being loaded already
exists in the current
	 * form definition then the behavior or load will vary depending upon the
replace flag.  If it
	 * is set to true, then the existing field will be replaced in its exact
location by the new
	 * field being loaded.  If it is false, then the new field being loaded
will be ignored and the
	 * method will move on to the next field to load.
	 *
	 * @param   string  $data     The name of an XML string or object.
	 * @param   string  $replace  Flag to toggle whether form fields should be
replaced if a field
	 *                            already exists with the same group/name.
	 * @param   string  $xpath    An optional xpath to search for the fields.
	 *
	 * @return  boolean  True on success, false otherwise.
	 *
	 * @since   1.7.0
	 */
	public function load($data, $replace = true, $xpath = false)
	{
		// If the data to load isn't already an XML element or string return
false.
		if ((!($data instanceof \SimpleXMLElement)) &&
(!is_string($data)))
		{
			return false;
		}

		// Attempt to load the XML if a string.
		if (is_string($data))
		{
			try
			{
				$data = new \SimpleXMLElement($data);
			}
			catch (\Exception $e)
			{
				return false;
			}

			// Make sure the XML loaded correctly.
			if (!$data)
			{
				return false;
			}
		}

		// If we have no XML definition at this point let's make sure we get
one.
		if (empty($this->xml))
		{
			// If no XPath query is set to search for fields, and we have a <form
/>, set it and return.
			if (!$xpath && ($data->getName() == 'form'))
			{
				$this->xml = $data;

				// Synchronize any paths found in the load.
				$this->syncPaths();

				return true;
			}

			// Create a root element for the form.
			else
			{
				$this->xml = new
\SimpleXMLElement('<form></form>');
			}
		}

		// Get the XML elements to load.
		$elements = array();

		if ($xpath)
		{
			$elements = $data->xpath($xpath);
		}
		elseif ($data->getName() == 'form')
		{
			$elements = $data->children();
		}

		// If there is nothing to load return true.
		if (empty($elements))
		{
			return true;
		}

		// Load the found form elements.
		foreach ($elements as $element)
		{
			// Get an array of fields with the correct name.
			$fields = $element->xpath('descendant-or-self::field');

			foreach ($fields as $field)
			{
				// Get the group names as strings for ancestor fields elements.
				$attrs = $field->xpath('ancestor::fields[@name]/@name');
				$groups = array_map('strval', $attrs ? $attrs : array());

				// Check to see if the field exists in the current form.
				if ($current = $this->findField((string) $field['name'],
implode('.', $groups)))
				{
					// If set to replace found fields, replace the data and remove the
field so we don't add it twice.
					if ($replace)
					{
						$olddom = dom_import_simplexml($current);
						$loadeddom = dom_import_simplexml($field);
						$addeddom = $olddom->ownerDocument->importNode($loadeddom,
true);
						$olddom->parentNode->replaceChild($addeddom, $olddom);
						$loadeddom->parentNode->removeChild($loadeddom);
					}
					else
					{
						unset($field);
					}
				}
			}

			// Merge the new field data into the existing XML document.
			self::addNode($this->xml, $element);
		}

		// Synchronize any paths found in the load.
		$this->syncPaths();

		return true;
	}

	/**
	 * Method to load the form description from an XML file.
	 *
	 * The reset option works on a group basis. If the XML file references
	 * groups that have already been created they will be replaced with the
	 * fields in the new XML file unless the $reset parameter has been set
	 * to false.
	 *
	 * @param   string  $file   The filesystem path of an XML file.
	 * @param   string  $reset  Flag to toggle whether form fields should be
replaced if a field
	 *                          already exists with the same group/name.
	 * @param   string  $xpath  An optional xpath to search for the fields.
	 *
	 * @return  boolean  True on success, false otherwise.
	 *
	 * @since   1.7.0
	 */
	public function loadFile($file, $reset = true, $xpath = false)
	{
		// Check to see if the path is an absolute path.
		if (!is_file($file))
		{
			// Not an absolute path so let's attempt to find one using JPath.
			$file = \JPath::find(self::addFormPath(), strtolower($file) .
'.xml');

			// If unable to find the file return false.
			if (!$file)
			{
				return false;
			}
		}

		// Attempt to load the XML file.
		$xml = simplexml_load_file($file);

		return $this->load($xml, $reset, $xpath);
	}

	/**
	 * Method to remove a field from the form definition.
	 *
	 * @param   string  $name   The name of the form field for which remove.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 *
	 * @return  boolean  True on success, false otherwise.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function removeField($name, $group = null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::removeField `xml`
is not an instance of SimpleXMLElement', get_class($this)));
		}

		// Find the form field element from the definition.
		$element = $this->findField($name, $group);

		// If the element exists remove it from the form definition.
		if ($element instanceof \SimpleXMLElement)
		{
			$dom = dom_import_simplexml($element);
			$dom->parentNode->removeChild($dom);

			return true;
		}

		return false;
	}

	/**
	 * Method to remove a group from the form definition.
	 *
	 * @param   string  $group  The dot-separated form group path for the
group to remove.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function removeGroup($group)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::removeGroup `xml`
is not an instance of SimpleXMLElement', get_class($this)));
		}

		// Get the fields elements for a given group.
		$elements = &$this->findGroup($group);

		foreach ($elements as &$element)
		{
			$dom = dom_import_simplexml($element);
			$dom->parentNode->removeChild($dom);
		}

		return true;
	}

	/**
	 * Method to reset the form data store and optionally the form XML
definition.
	 *
	 * @param   boolean  $xml  True to also reset the XML form definition.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 */
	public function reset($xml = false)
	{
		unset($this->data);
		$this->data = new Registry;

		if ($xml)
		{
			unset($this->xml);
			$this->xml = new
\SimpleXMLElement('<form></form>');
		}

		return true;
	}

	/**
	 * Method to set a field XML element to the form definition.  If the
replace flag is set then
	 * the field will be set whether it already exists or not.  If it
isn't set, then the field
	 * will not be replaced if it already exists.
	 *
	 * @param   \SimpleXMLElement  $element   The XML element object
representation of the form field.
	 * @param   string             $group     The optional dot-separated form
group path on which to set the field.
	 * @param   boolean            $replace   True to replace an existing
field if one already exists.
	 * @param   string             $fieldset  The name of the fieldset we are
adding the field to.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function setField(\SimpleXMLElement $element, $group = null,
$replace = true, $fieldset = 'default')
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::setField `xml` is
not an instance of SimpleXMLElement', get_class($this)));
		}

		// Find the form field element from the definition.
		$old = $this->findField((string) $element['name'], $group);

		// If an existing field is found and replace flag is false do nothing and
return true.
		if (!$replace && !empty($old))
		{
			return true;
		}

		// If an existing field is found and replace flag is true remove the old
field.
		if ($replace && !empty($old) && ($old instanceof
\SimpleXMLElement))
		{
			$dom = dom_import_simplexml($old);

			// Get the parent element, this should be the fieldset
			$parent   = $dom->parentNode;
			$fieldset = $parent->getAttribute('name');

			$parent->removeChild($dom);
		}

		// Create the search path
		$path = '//';

		if (!empty($group))
		{
			$path .= 'fields[@name="' . $group .
'"]/';
		}

		$path .= 'fieldset[@name="' . $fieldset .
'"]';

		$fs = $this->xml->xpath($path);

		if (isset($fs[0]) && ($fs[0] instanceof \SimpleXMLElement))
		{
			// Add field to the form.
			self::addNode($fs[0], $element);

			// Synchronize any paths found in the load.
			$this->syncPaths();

			return true;
		}

		// We couldn't find a fieldset to add the field. Now we are
checking, if we have set only a group
		if (!empty($group))
		{
			$fields = &$this->findGroup($group);

			// If an appropriate fields element was found for the group, add the
element.
			if (isset($fields[0]) && ($fields[0] instanceof
\SimpleXMLElement))
			{
				self::addNode($fields[0], $element);
			}

			// Synchronize any paths found in the load.
			$this->syncPaths();

			return true;
		}

		// We couldn't find a parent so we are adding it at root level

		// Add field to the form.
		self::addNode($this->xml, $element);

		// Synchronize any paths found in the load.
		$this->syncPaths();

		return true;
	}

	/**
	 * Method to set an attribute value for a field XML element.
	 *
	 * @param   string  $name       The name of the form field for which to
set the attribute value.
	 * @param   string  $attribute  The name of the attribute for which to set
a value.
	 * @param   mixed   $value      The value to set for the attribute.
	 * @param   string  $group      The optional dot-separated form group path
on which to find the field.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function setFieldAttribute($name, $attribute, $value, $group =
null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::setFieldAttribute
`xml` is not an instance of SimpleXMLElement', get_class($this)));
		}

		// Find the form field element from the definition.
		$element = $this->findField($name, $group);

		// If the element doesn't exist return false.
		if (!($element instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Otherwise set the attribute and return true.
		else
		{
			$element[$attribute] = $value;

			// Synchronize any paths found in the load.
			$this->syncPaths();

			return true;
		}
	}

	/**
	 * Method to set some field XML elements to the form definition.  If the
replace flag is set then
	 * the fields will be set whether they already exists or not.  If it
isn't set, then the fields
	 * will not be replaced if they already exist.
	 *
	 * @param   array    &$elements  The array of XML element object
representations of the form fields.
	 * @param   string   $group      The optional dot-separated form group
path on which to set the fields.
	 * @param   boolean  $replace    True to replace existing fields if they
already exist.
	 * @param   string   $fieldset   The name of the fieldset we are adding
the field to.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 * @throws  \UnexpectedValueException
	 */
	public function setFields(&$elements, $group = null, $replace = true,
$fieldset = 'default')
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			throw new \UnexpectedValueException(sprintf('%s::setFields `xml` is
not an instance of SimpleXMLElement', get_class($this)));
		}

		// Make sure the elements to set are valid.
		foreach ($elements as $element)
		{
			if (!($element instanceof \SimpleXMLElement))
			{
				throw new \UnexpectedValueException(sprintf('$element not
SimpleXMLElement in %s::setFields', get_class($this)));
			}
		}

		// Set the fields.
		$return = true;

		foreach ($elements as $element)
		{
			if (!$this->setField($element, $group, $replace, $fieldset))
			{
				$return = false;
			}
		}

		// Synchronize any paths found in the load.
		$this->syncPaths();

		return $return;
	}

	/**
	 * Method to set the value of a field. If the field does not exist in the
form then the method
	 * will return false.
	 *
	 * @param   string  $name   The name of the field for which to set the
value.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 * @param   mixed   $value  The value to set for the field.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 */
	public function setValue($name, $group = null, $value = null)
	{
		// If the field does not exist return false.
		if (!$this->findField($name, $group))
		{
			return false;
		}

		// If a group is set use it.
		if ($group)
		{
			$this->data->set($group . '.' . $name, $value);
		}
		else
		{
			$this->data->set($name, $value);
		}

		return true;
	}

	/**
	 * Method to validate form data.
	 *
	 * Validation warnings will be pushed into JForm::errors and should be
	 * retrieved with JForm::getErrors() when validate returns boolean false.
	 *
	 * @param   array   $data   An array of field values to validate.
	 * @param   string  $group  The optional dot-separated form group path on
which to filter the
	 *                          fields to be validated.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 */
	public function validate($data, $group = null)
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		$return = true;

		// Create an input registry object from the data to validate.
		$input = new Registry($data);

		// Get the fields for which to validate the data.
		$fields = $this->findFieldsByGroup($group);

		if (!$fields)
		{
			// PANIC!
			return false;
		}

		// Validate the fields.
		foreach ($fields as $field)
		{
			$value = null;
			$name = (string) $field['name'];

			// Get the group names as strings for ancestor fields elements.
			$attrs = $field->xpath('ancestor::fields[@name]/@name');
			$groups = array_map('strval', $attrs ? $attrs : array());
			$group = implode('.', $groups);

			// Get the value from the input data.
			if ($group)
			{
				$value = $input->get($group . '.' . $name);
			}
			else
			{
				$value = $input->get($name);
			}

			// Validate the field.
			$valid = $this->validateField($field, $group, $value, $input);

			// Check for an error.
			if ($valid instanceof \Exception)
			{
				$this->errors[] = $valid;
				$return         = false;
			}
		}

		return $return;
	}

	/**
	 * Method to apply an input filter to a value based on field data.
	 *
	 * @param   string  $element  The XML element object representation of the
form field.
	 * @param   mixed   $value    The value to filter for the field.
	 *
	 * @return  mixed   The filtered value.
	 *
	 * @since   1.7.0
	 */
	protected function filterField($element, $value)
	{
		// Make sure there is a valid SimpleXMLElement.
		if (!($element instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Get the field filter type.
		$filter = (string) $element['filter'];

		// Process the input value based on the filter.
		$return = null;

		switch (strtoupper($filter))
		{
			// Access Control Rules.
			case 'RULES':
				$return = array();

				foreach ((array) $value as $action => $ids)
				{
					// Build the rules array.
					$return[$action] = array();

					foreach ($ids as $id => $p)
					{
						if ($p !== '')
						{
							$return[$action][$id] = ($p == '1' || $p ==
'true') ? true : false;
						}
					}
				}
				break;

			// Do nothing, thus leaving the return value as null.
			case 'UNSET':
				break;

			// No Filter.
			case 'RAW':
				$return = $value;
				break;

			// Filter the input as an array of integers.
			case 'INT_ARRAY':
				// Make sure the input is an array.
				if (is_object($value))
				{
					$value = get_object_vars($value);
				}

				$value = is_array($value) ? $value : array($value);

				$value = ArrayHelper::toInteger($value);
				$return = $value;
				break;

			// Filter safe HTML.
			case 'SAFEHTML':
				$return = \JFilterInput::getInstance(null, null, 1,
1)->clean($value, 'html');
				break;

			// Convert a date to UTC based on the server timezone offset.
			case 'SERVER_UTC':
				if ((int) $value > 0)
				{
					// Check if we have a localised date format
					$translateFormat = (string) $element['translateformat'];

					if ($translateFormat && $translateFormat != 'false')
					{
						$showTime = (string) $element['showtime'];
						$showTime = ($showTime && $showTime != 'false');
						$format   = ($showTime) ?
\JText::_('DATE_FORMAT_FILTER_DATETIME') :
\JText::_('DATE_FORMAT_FILTER_DATE');
						$date     = date_parse_from_format($format, $value);
						$value    = (int) $date['year'] . '-' . (int)
$date['month'] . '-' . (int) $date['day'];

						if ($showTime)
						{
							$value .= ' ' . (int) $date['hour'] .
':' . (int) $date['minute'] . ':' . (int)
$date['second'];
						}
					}

					// Get the server timezone setting.
					$offset = \JFactory::getConfig()->get('offset');

					// Return an SQL formatted datetime string in UTC.
					try
					{
						$return = \JFactory::getDate($value, $offset)->toSql();
					}
					catch (\Exception $e)
					{
						\JFactory::getApplication()->enqueueMessage(
							\JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID',
\JText::_((string) $element['label'])),
							'warning'
						);

						$return = '';
					}
				}
				else
				{
					$return = '';
				}
				break;

			// Convert a date to UTC based on the user timezone offset.
			case 'USER_UTC':
				if ((int) $value > 0)
				{
					// Check if we have a localised date format
					$translateFormat = (string) $element['translateformat'];

					if ($translateFormat && $translateFormat != 'false')
					{
						$showTime = (string) $element['showtime'];
						$showTime = ($showTime && $showTime != 'false');
						$format   = ($showTime) ?
\JText::_('DATE_FORMAT_FILTER_DATETIME') :
\JText::_('DATE_FORMAT_FILTER_DATE');
						$date     = date_parse_from_format($format, $value);
						$value    = (int) $date['year'] . '-' . (int)
$date['month'] . '-' . (int) $date['day'];

						if ($showTime)
						{
							$value .= ' ' . (int) $date['hour'] .
':' . (int) $date['minute'] . ':' . (int)
$date['second'];
						}
					}

					// Get the user timezone setting defaulting to the server timezone
setting.
					$offset = \JFactory::getUser()->getTimezone();

					// Return a MySQL formatted datetime string in UTC.
					try
					{
						$return = \JFactory::getDate($value, $offset)->toSql();
					}
					catch (\Exception $e)
					{
						\JFactory::getApplication()->enqueueMessage(
							\JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID',
\JText::_((string) $element['label'])),
							'warning'
						);

						$return = '';
					}
				}
				else
				{
					$return = '';
				}
				break;

			/*
			 * Ensures a protocol is present in the saved field unless the relative
flag is set.
			 * Only use when the only permitted protocols require '://'.
			 * See JFormRuleUrl for list of these.
			 */

			case 'URL':
				if (empty($value))
				{
					return false;
				}

				// This cleans some of the more dangerous characters but leaves special
characters that are valid.
				$value = \JFilterInput::getInstance()->clean($value,
'html');
				$value = trim($value);

				// <>" are never valid in a uri see
http://www.ietf.org/rfc/rfc1738.txt.
				$value = str_replace(array('<', '>',
'"'), '', $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 (($element['type'] == 'url' &&
!$protocol &&  !$element['relative'])
					|| (!$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 = \JUri::root() . $value;
					}

					// Otherwise we treat it as an external link.
					else
					{
						// Put the url back together.
						$value = $protocol . '://' . $value;
					}
				}

				// If relative URLS are allowed we assume that URLs without protocols
are internal.
				elseif (!$protocol && $element['relative'])
				{
					$host = \JUri::getInstance('SERVER')->gethost();

					// If it starts with the host string, just prepend the protocol.
					if (substr($value, 0) == $host)
					{
						$value = 'http://' . $value;
					}

					// Otherwise if it doesn't start with "/" prepend the
prefix of the current site.
					elseif (substr($value, 0, 1) != '/')
					{
						$value = \JUri::root(true) . '/' . $value;
					}
				}

				$value = \JStringPunycode::urlToPunycode($value);
				$return = $value;
				break;

			case 'TEL':
				$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;
				}

				// If not, does it match ITU-T?
				elseif (preg_match('/^\+(?:[0-9] ?){6,14}[0-9]$/', $value) ==
1)
				{
					$countrycode = substr($value, 0, strpos($value, ' '));
					$countrycode = (string) preg_replace('/[^\d]/',
'', $countrycode);
					$number = strstr($value, ' ');
					$number = (string) preg_replace('/[^\d]/', '',
$number);
					$result = $countrycode . '.' . $number;
				}

				// If not, does it match EPP?
				elseif (preg_match('/^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/',
$value) == 1)
				{
					if (strstr($value, 'x'))
					{
						$xpos = strpos($value, 'x');
						$value = substr($value, 0, $xpos);
					}

					$result = str_replace('+', '', $value);
				}

				// Maybe it is already ccc.nnnnnnn?
				elseif (preg_match('/[0-9]{1,3}\.[0-9]{4,14}$/', $value) ==
1)
				{
					$result = $value;
				}

				// If not, can we make it a string of digits?
				else
				{
					$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);
						}
					}

					// If not let's not save anything.
					else
					{
						$result = '';
					}
				}

				$return = $result;

				break;
			default:

				// Check for a callback filter.
				if (strpos($filter, '::') !== false &&
is_callable(explode('::', $filter)))
				{
					$return = call_user_func(explode('::', $filter), $value);
				}

				// Filter using a callback function if specified.
				elseif (function_exists($filter))
				{
					$return = call_user_func($filter, $value);
				}

				elseif ((string) $element['type'] === 'subform')
				{
					$field   = $this->loadField($element);
					$subForm = $field->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 ($field->multiple)
					{
						$return = array();

						if ($value)
						{
							foreach ($value as $key => $val)
							{
								$return[$key] = $subForm->filter($val);
							}
						}
					}
					else
					{
						$return = $subForm->filter($value);
					}

					break;
				}

				// Check for empty value and return empty string if no value is
required,
				// otherwise filter using JFilterInput. All HTML code is filtered by
default.
				else
				{
					$required = ((string) $element['required'] ==
'true' || (string) $element['required'] ==
'required');

					if (($value === '' || $value === null) && !
$required)
					{
						$return = '';
					}
					else
					{
						$return = \JFilterInput::getInstance()->clean($value, $filter);
					}
				}
				break;
		}

		return $return;
	}

	/**
	 * Method to get a form field represented as an XML element object.
	 *
	 * @param   string  $name   The name of the form field.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 *
	 * @return  \SimpleXMLElement|boolean  The XML element object for the
field or boolean false on error.
	 *
	 * @since   1.7.0
	 */
	protected function findField($name, $group = null)
	{
		$element = false;
		$fields = array();

		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Let's get the appropriate field element based on the method
arguments.
		if ($group)
		{
			// Get the fields elements for a given group.
			$elements = &$this->findGroup($group);

			// Get all of the field elements with the correct name for the fields
elements.
			foreach ($elements as $el)
			{
				// If there are matching field elements add them to the fields array.
				if ($tmp = $el->xpath('descendant::field[@name="' .
$name . '" and not(ancestor::field/form/*)]'))
				{
					$fields = array_merge($fields, $tmp);
				}
			}

			// Make sure something was found.
			if (!$fields)
			{
				return false;
			}

			// Use the first correct match in the given group.
			$groupNames = explode('.', $group);

			foreach ($fields as &$field)
			{
				// Get the group names as strings for ancestor fields elements.
				$attrs = $field->xpath('ancestor::fields[@name]/@name');
				$names = array_map('strval', $attrs ? $attrs : array());

				// If the field is in the exact group use it and break out of the loop.
				if ($names == (array) $groupNames)
				{
					$element = &$field;
					break;
				}
			}
		}
		else
		{
			// Get an array of fields with the correct name.
			$fields = $this->xml->xpath('//field[@name="' .
$name . '" and not(ancestor::field/form/*)]');

			// Make sure something was found.
			if (!$fields)
			{
				return false;
			}

			// Search through the fields for the right one.
			foreach ($fields as &$field)
			{
				// If we find an ancestor fields element with a group name then it
isn't what we want.
				if ($field->xpath('ancestor::fields[@name]'))
				{
					continue;
				}

				// Found it!
				else
				{
					$element = &$field;
					break;
				}
			}
		}

		return $element;
	}

	/**
	 * Method to get an array of `<field>` elements from the form XML
document which are in a specified fieldset by name.
	 *
	 * @param   string  $name  The name of the fieldset.
	 *
	 * @return  \SimpleXMLElement[]|boolean  Boolean false on error or array
of SimpleXMLElement objects.
	 *
	 * @since   1.7.0
	 */
	protected function &findFieldsByFieldset($name)
	{
		$false = false;

		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return $false;
		}

		/*
		 * Get an array of <field /> elements that are underneath a
<fieldset /> element
		 * with the appropriate name attribute, and also any <field />
elements with
		 * the appropriate fieldset attribute. To allow repeatable elements only
fields
		 * which are not descendants of other fields are selected.
		 */
		$fields = $this->xml->xpath('(//fieldset[@name="' .
$name . '"]//field | //field[@fieldset="' . $name .
'"])[not(ancestor::field)]');

		return $fields;
	}

	/**
	 * Method to get an array of `<field>` elements from the form XML
document which are in a control group by name.
	 *
	 * @param   mixed    $group   The optional dot-separated form group path
on which to find the fields.
	 *                            Null will return all fields. False will
return fields not in a group.
	 * @param   boolean  $nested  True to also include fields in nested groups
that are inside of the
	 *                            group for which to find fields.
	 *
	 * @return  \SimpleXMLElement[]|boolean  Boolean false on error or array
of SimpleXMLElement objects.
	 *
	 * @since   1.7.0
	 */
	protected function &findFieldsByGroup($group = null, $nested = false)
	{
		$false = false;
		$fields = array();

		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return $false;
		}

		// Get only fields in a specific group?
		if ($group)
		{
			// Get the fields elements for a given group.
			$elements = &$this->findGroup($group);

			// Get all of the field elements for the fields elements.
			foreach ($elements as $element)
			{
				// If there are field elements add them to the return result.
				if ($tmp = $element->xpath('descendant::field'))
				{
					// If we also want fields in nested groups then just merge the arrays.
					if ($nested)
					{
						$fields = array_merge($fields, $tmp);
					}

					// If we want to exclude nested groups then we need to check each
field.
					else
					{
						$groupNames = explode('.', $group);

						foreach ($tmp as $field)
						{
							// Get the names of the groups that the field is in.
							$attrs =
$field->xpath('ancestor::fields[@name]/@name');
							$names = array_map('strval', $attrs ? $attrs : array());

							// If the field is in the specific group then add it to the return
list.
							if ($names == (array) $groupNames)
							{
								$fields = array_merge($fields, array($field));
							}
						}
					}
				}
			}
		}
		elseif ($group === false)
		{
			// Get only field elements not in a group.
			$fields =
$this->xml->xpath('descendant::fields[not(@name)]/field |
descendant::fields[not(@name)]/fieldset/field ');
		}
		else
		{
			// Get an array of all the <field /> elements.
			$fields =
$this->xml->xpath('//field[not(ancestor::field/form/*)]');
		}

		return $fields;
	}

	/**
	 * Method to get a form field group represented as an XML element object.
	 *
	 * @param   string  $group  The dot-separated form group path on which to
find the group.
	 *
	 * @return  \SimpleXMLElement[]|boolean  An array of XML element objects
for the group or boolean false on error.
	 *
	 * @since   1.7.0
	 */
	protected function &findGroup($group)
	{
		$false = false;
		$groups = array();
		$tmp = array();

		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return $false;
		}

		// Make sure there is actually a group to find.
		$group = explode('.', $group);

		if (!empty($group))
		{
			// Get any fields elements with the correct group name.
			$elements = $this->xml->xpath('//fields[@name="' .
(string) $group[0] . '" and not(ancestor::field/form/*)]');

			// Check to make sure that there are no parent groups for each element.
			foreach ($elements as $element)
			{
				if (!$element->xpath('ancestor::fields[@name]'))
				{
					$tmp[] = $element;
				}
			}

			// Iterate through the nested groups to find any matching form field
groups.
			for ($i = 1, $n = count($group); $i < $n; $i++)
			{
				// Initialise some loop variables.
				$validNames = array_slice($group, 0, $i + 1);
				$current = $tmp;
				$tmp = array();

				// Check to make sure that there are no parent groups for each element.
				foreach ($current as $element)
				{
					// Get any fields elements with the correct group name.
					$children =
$element->xpath('descendant::fields[@name="' . (string)
$group[$i] . '"]');

					// For the found fields elements validate that they are in the correct
groups.
					foreach ($children as $fields)
					{
						// Get the group names as strings for ancestor fields elements.
						$attrs =
$fields->xpath('ancestor-or-self::fields[@name]/@name');
						$names = array_map('strval', $attrs ? $attrs : array());

						// If the group names for the fields element match the valid names at
this
						// level add the fields element.
						if ($validNames == $names)
						{
							$tmp[] = $fields;
						}
					}
				}
			}

			// Only include valid XML objects.
			foreach ($tmp as $element)
			{
				if ($element instanceof \SimpleXMLElement)
				{
					$groups[] = $element;
				}
			}
		}

		return $groups;
	}

	/**
	 * Method to load, setup and return a JFormField object based on field
data.
	 *
	 * @param   string  $element  The XML element object representation of the
form field.
	 * @param   string  $group    The optional dot-separated form group path
on which to find the field.
	 * @param   mixed   $value    The optional value to use as the default for
the field.
	 *
	 * @return  \JFormField|boolean  The JFormField object for the field or
boolean false on error.
	 *
	 * @since   1.7.0
	 */
	protected function loadField($element, $group = null, $value = null)
	{
		// Make sure there is a valid SimpleXMLElement.
		if (!($element instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Get the field type.
		$type = $element['type'] ? (string) $element['type']
: 'text';

		// Load the JFormField object for the field.
		$field = $this->loadFieldType($type);

		// If the object could not be loaded, get a text field object.
		if ($field === false)
		{
			$field = $this->loadFieldType('text');
		}

		/*
		 * Get the value for the form field if not set.
		 * Default to the translated version of the 'default' attribute
		 * if 'translate_default' attribute if set to 'true'
or '1'
		 * else the value of the 'default' attribute for the field.
		 */
		if ($value === null)
		{
			$default = (string) ($element['default'] ?
$element['default'] : $element->default);

			if (($translate = $element['translate_default']) &&
((string) $translate == 'true' || (string) $translate ==
'1'))
			{
				$lang = \JFactory::getLanguage();

				if ($lang->hasKey($default))
				{
					$debug = $lang->setDebug(false);
					$default = \JText::_($default);
					$lang->setDebug($debug);
				}
				else
				{
					$default = \JText::_($default);
				}
			}

			$value = $this->getValue((string) $element['name'], $group,
$default);
		}

		// Setup the JFormField object.
		$field->setForm($this);

		if ($field->setup($element, $value, $group))
		{
			return $field;
		}
		else
		{
			return false;
		}
	}

	/**
	 * Proxy for {@link FormHelper::loadFieldType()}.
	 *
	 * @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
	 * @deprecated  4.0  Use FormHelper::loadFieldType() directly
	 */
	protected function loadFieldType($type, $new = true)
	{
		return FormHelper::loadFieldType($type, $new);
	}

	/**
	 * Proxy for FormHelper::loadRuleType().
	 *
	 * @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.
	 *
	 * @see     FormHelper::loadRuleType()
	 * @since   1.7.0
	 * @deprecated  4.0  Use FormHelper::loadRuleType() directly
	 */
	protected function loadRuleType($type, $new = true)
	{
		return FormHelper::loadRuleType($type, $new);
	}

	/**
	 * Method to synchronize any field, form or rule paths contained in the
XML document.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 * @todo    Maybe we should receive all addXXXpaths attributes at once?
	 */
	protected function syncPaths()
	{
		// Make sure there is a valid JForm XML document.
		if (!($this->xml instanceof \SimpleXMLElement))
		{
			return false;
		}

		// Get any addfieldpath attributes from the form definition.
		$paths =
$this->xml->xpath('//*[@addfieldpath]/@addfieldpath');
		$paths = array_map('strval', $paths ? $paths : array());

		// Add the field paths.
		foreach ($paths as $path)
		{
			$path = JPATH_ROOT . '/' . ltrim($path, '/\\');
			self::addFieldPath($path);
		}

		// Get any addformpath attributes from the form definition.
		$paths =
$this->xml->xpath('//*[@addformpath]/@addformpath');
		$paths = array_map('strval', $paths ? $paths : array());

		// Add the form paths.
		foreach ($paths as $path)
		{
			$path = JPATH_ROOT . '/' . ltrim($path, '/\\');
			self::addFormPath($path);
		}

		// Get any addrulepath attributes from the form definition.
		$paths =
$this->xml->xpath('//*[@addrulepath]/@addrulepath');
		$paths = array_map('strval', $paths ? $paths : array());

		// Add the rule paths.
		foreach ($paths as $path)
		{
			$path = JPATH_ROOT . '/' . ltrim($path, '/\\');
			self::addRulePath($path);
		}

		// Get any addfieldprefix attributes from the form definition.
		$prefixes =
$this->xml->xpath('//*[@addfieldprefix]/@addfieldprefix');
		$prefixes = array_map('strval', $prefixes ? $prefixes :
array());

		// Add the field prefixes.
		foreach ($prefixes as $prefix)
		{
			FormHelper::addFieldPrefix($prefix);
		}

		// Get any addformprefix attributes from the form definition.
		$prefixes =
$this->xml->xpath('//*[@addformprefix]/@addformprefix');
		$prefixes = array_map('strval', $prefixes ? $prefixes :
array());

		// Add the field prefixes.
		foreach ($prefixes as $prefix)
		{
			FormHelper::addFormPrefix($prefix);
		}

		// Get any addruleprefix attributes from the form definition.
		$prefixes =
$this->xml->xpath('//*[@addruleprefix]/@addruleprefix');
		$prefixes = array_map('strval', $prefixes ? $prefixes :
array());

		// Add the field prefixes.
		foreach ($prefixes as $prefix)
		{
			FormHelper::addRulePrefix($prefix);
		}

		return true;
	}

	/**
	 * Method to validate a JFormField object based on field data.
	 *
	 * @param   \SimpleXMLElement  $element  The XML element object
representation of the form field.
	 * @param   string             $group    The optional dot-separated form
group path on which to find the field.
	 * @param   mixed              $value    The optional value to use as the
default for the field.
	 * @param   Registry           $input    An optional Registry object with
the entire data set to validate
	 *                                      against the entire form.
	 *
	 * @return  boolean  Boolean true if field value is valid, Exception on
failure.
	 *
	 * @since   1.7.0
	 * @throws  \InvalidArgumentException
	 * @throws  \UnexpectedValueException
	 */
	protected function validateField(\SimpleXMLElement $element, $group =
null, $value = null, Registry $input = null)
	{
		$valid = true;

		// Define field name for messages
		if ($element['label'])
		{
			$fieldLabel = \JText::_($element['label']);
		}
		else
		{
			$fieldLabel = \JText::_($element['name']);
		}

		// Check if the field is required.
		$required = ((string) $element['required'] == 'true'
|| (string) $element['required'] == 'required');

		if ($input)
		{
			$disabled = ((string) $element['disabled'] == 'true'
|| (string) $element['disabled'] == 'disabled');

			$fieldExistsInRequestData = $input->exists((string)
$element['name']) || $input->exists($group . '.' .
(string) $element['name']);

			// If the field is disabled but it is passed in the request this is
invalid as disabled fields are not added to the request
			if ($disabled && $fieldExistsInRequestData)
			{
				$message =
\JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $fieldLabel);

				return new \RuntimeException($message);
			}
		}

		if ($required)
		{
			// If the field is required and the value is empty return an error
message.
			if (($value === '') || ($value === null))
			{
				$message =
\JText::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED',
$fieldLabel);

				return new \RuntimeException($message);
			}
		}

		// Get the field validation rule.
		if ($type = (string) $element['validate'])
		{
			// Load the JFormRule object for the field.
			$rule = $this->loadRuleType($type);

			// If the object could not be loaded return an error message.
			if ($rule === false)
			{
				throw new \UnexpectedValueException(sprintf('%s::validateField()
rule `%s` missing.', get_class($this), $type));
			}

			// Run the field validation rule test.
			$valid = $rule->test($element, $value, $group, $input, $this);

			// Check for an error in the validation test.
			if ($valid instanceof \Exception)
			{
				return $valid;
			}
		}

		if ($valid !== false && (string) $element['type'] ===
'subform')
		{
			// Load the subform validation rule.
			$rule = $this->loadRuleType('SubForm');

			// Run the field validation rule test.
			$valid = $rule->test($element, $value, $group, $input, $this);

			// Check for an error in the validation test.
			if ($valid instanceof \Exception)
			{
				return $valid;
			}
		}

		// Check if the field is valid.
		if ($valid === false)
		{
			// Does the field have a defined error message?
			$message = (string) $element['message'];

			if ($message)
			{
				$message = \JText::_($element['message']);

				return new \UnexpectedValueException($message);
			}
			else
			{
				$message =
\JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $fieldLabel);

				return new \UnexpectedValueException($message);
			}
		}

		return true;
	}

	/**
	 * Proxy for {@link FormHelper::addFieldPath()}.
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @since   1.7.0
	 */
	public static function addFieldPath($new = null)
	{
		return FormHelper::addFieldPath($new);
	}

	/**
	 * Proxy for FormHelper::addFormPath().
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @see     FormHelper::addFormPath()
	 * @since   1.7.0
	 */
	public static function addFormPath($new = null)
	{
		return FormHelper::addFormPath($new);
	}

	/**
	 * Proxy for FormHelper::addRulePath().
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @see     FormHelper::addRulePath()
	 * @since   1.7.0
	 */
	public static function addRulePath($new = null)
	{
		return FormHelper::addRulePath($new);
	}

	/**
	 * Method to get an instance of a form.
	 *
	 * @param   string          $name     The name of the form.
	 * @param   string          $data     The name of an XML file or string to
load as the form definition.
	 * @param   array           $options  An array of form options.
	 * @param   boolean         $replace  Flag to toggle whether form fields
should be replaced if a field
	 *                                    already exists with the same
group/name.
	 * @param   string|boolean  $xpath    An optional xpath to search for the
fields.
	 *
	 * @return  Form  JForm instance.
	 *
	 * @since   1.7.0
	 * @throws  \InvalidArgumentException if no data provided.
	 * @throws  \RuntimeException if the form could not be loaded.
	 */
	public static function getInstance($name, $data = null, $options =
array(), $replace = true, $xpath = false)
	{
		// Reference to array with form instances
		$forms = &self::$forms;

		// Only instantiate the form if it does not already exist.
		if (!isset($forms[$name]))
		{
			$data = trim($data);

			if (empty($data))
			{
				throw new \InvalidArgumentException(sprintf('%1$s(%2$s,
*%3$s*)', __METHOD__, $name, gettype($data)));
			}

			// Instantiate the form.
			$forms[$name] = new static($name, $options);

			// Load the data.
			if (substr($data, 0, 1) == '<')
			{
				if ($forms[$name]->load($data, $replace, $xpath) == false)
				{
					throw new \RuntimeException(sprintf('%s() could not load
form', __METHOD__));
				}
			}
			else
			{
				if ($forms[$name]->loadFile($data, $replace, $xpath) == false)
				{
					throw new \RuntimeException(sprintf('%s() could not load
file', __METHOD__));
				}
			}
		}

		return $forms[$name];
	}

	/**
	 * Adds a new child SimpleXMLElement node to the source.
	 *
	 * @param   \SimpleXMLElement  $source  The source element on which to
append.
	 * @param   \SimpleXMLElement  $new     The new element to append.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected static function addNode(\SimpleXMLElement $source,
\SimpleXMLElement $new)
	{
		// Add the new child node.
		$node = $source->addChild($new->getName(),
htmlspecialchars(trim($new)));

		// Add the attributes of the child node.
		foreach ($new->attributes() as $name => $value)
		{
			$node->addAttribute($name, $value);
		}

		// Add any children of the new node.
		foreach ($new->children() as $child)
		{
			self::addNode($node, $child);
		}
	}

	/**
	 * Update the attributes of a child node
	 *
	 * @param   \SimpleXMLElement  $source  The source element on which to
append the attributes
	 * @param   \SimpleXMLElement  $new     The new element to append
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected static function mergeNode(\SimpleXMLElement $source,
\SimpleXMLElement $new)
	{
		// Update the attributes of the child node.
		foreach ($new->attributes() as $name => $value)
		{
			if (isset($source[$name]))
			{
				$source[$name] = (string) $value;
			}
			else
			{
				$source->addAttribute($name, $value);
			}
		}
	}

	/**
	 * Merges new elements into a source `<fields>` element.
	 *
	 * @param   \SimpleXMLElement  $source  The source element.
	 * @param   \SimpleXMLElement  $new     The new element to merge.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	protected static function mergeNodes(\SimpleXMLElement $source,
\SimpleXMLElement $new)
	{
		// The assumption is that the inputs are at the same relative level.
		// So we just have to scan the children and deal with them.

		// Update the attributes of the child node.
		foreach ($new->attributes() as $name => $value)
		{
			if (isset($source[$name]))
			{
				$source[$name] = (string) $value;
			}
			else
			{
				$source->addAttribute($name, $value);
			}
		}

		foreach ($new->children() as $child)
		{
			$type = $child->getName();
			$name = $child['name'];

			// Does this node exist?
			$fields = $source->xpath($type . '[@name="' . $name .
'"]');

			if (empty($fields))
			{
				// This node does not exist, so add it.
				self::addNode($source, $child);
			}
			else
			{
				// This node does exist.
				switch ($type)
				{
					case 'field':
						self::mergeNode($fields[0], $child);
						break;

					default:
						self::mergeNodes($fields[0], $child);
						break;
				}
			}
		}
	}

	/**
	 * Returns the value of an attribute of the form itself
	 *
	 * @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->xml instanceof \SimpleXMLElement)
		{
			$attributes = $this->xml->attributes();

			// Ensure that the attribute exists
			if (property_exists($attributes, $name))
			{
				$value = $attributes->$name;

				if ($value !== null)
				{
					return (string) $value;
				}
			}
		}

		return $default;
	}

	/**
	 * Getter for the form data
	 *
	 * @return   Registry  Object with the data
	 *
	 * @since    3.2
	 */
	public function getData()
	{
		return $this->data;
	}

	/**
	 * Method to get the XML form object
	 *
	 * @return  \SimpleXMLElement  The form XML object
	 *
	 * @since   3.2
	 */
	public function getXml()
	{
		return $this->xml;
	}

	/**
	 * Method to get a form field represented as an XML element object.
	 *
	 * @param   string  $name   The name of the form field.
	 * @param   string  $group  The optional dot-separated form group path on
which to find the field.
	 *
	 * @return  \SimpleXMLElement|boolean  The XML element object for the
field or boolean false on error.
	 *
	 * @since   3.7.0
	 */
	public function getFieldXml($name, $group = null)
	{
		return $this->findField($name, $group);
	}
}
FormField.php000064400000055741151160211170007133 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Layout\FileLayout;
use Joomla\String\Normalise;
use Joomla\String\StringHelper;

/**
 * Abstract Form Field class for the Joomla Platform.
 *
 * @since  1.7.0
 */
abstract class FormField
{
	/**
	 * 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 JForm 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;

	/**
	 * 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
	 */
	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 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';

	/**
	 * 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':
				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();
		}

		return;
	}

	/**
	 * 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));

			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 'default':
				$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;

			case 'required':
			case 'disabled':
			case 'readonly':
			case 'autofocus':
			case 'hidden':
				$value = (string) $value;
				$this->$name = ($value === 'true' || $value === $name ||
$value === '1');
				break;

			case 'autocomplete':
				$value = (string) $value;
				$value = ($value == 'on' || $value == '') ?
'on' : $value;
				$this->$name = ($value === 'false' || $value ===
'off' || $value === '0') ? false : $value;
				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:
				if (property_exists(__CLASS__, $name))
				{
					\JLog::add("Cannot access protected / private property $name of
" . __CLASS__);
				}
				else
				{
					$this->$name = $value;
				}
		}
	}

	/**
	 * Method to attach a JForm object to the field.
	 *
	 * @param   Form  $form  The JForm 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 JForm 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 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 JFormField 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 = array(
			'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;
		}

		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 || (string)
$element['type'] == 'hidden');

		$this->layout = !empty($this->element['layout']) ?
(string) $this->element['layout'] : $this->layout;

		// 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 ? $fieldId : $fieldName);
		}
		else
		{
			$id .= ($fieldId ? $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 ? \JText::_($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 = $this->element['name'] == 'alias' ?
' data-placement="bottom" ' : '';

		// Here mainly for B/C with old layouts. This can be done in the layouts
directly
		$extraData = array(
			'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 a control group with label and input.
	 *
	 * @return  string  A string containing the html for the control group
	 *
	 * @since      3.2
	 * @deprecated 3.2.3 Use renderField() instead
	 */
	public function getControlGroup()
	{
		\JLog::add('FormField->getControlGroup() is deprecated use
FormField->renderField().', \JLog::WARNING,
'deprecated');

		return $this->renderField();
	}

	/**
	 * 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 = array())
	{
		$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 = array())
	{
		if ($this->hidden)
		{
			return $this->getInput();
		}

		if (!isset($options['class']))
		{
			$options['class'] = '';
		}

		$options['rel'] = '';

		if (empty($options['hiddenLabel']) &&
$this->getAttribute('hiddenLabel'))
		{
			$options['hiddenLabel'] = true;
		}

		if ($this->showon)
		{
			$options['rel']           = ' data-showon=\'' .
				json_encode(FormHelper::parseShowOnConditions($this->showon,
$this->formControl, $this->group)) . '\'';
			$options['showonEnabled'] = true;
		}

		$data = array(
			'input'   => $this->getInput(),
			'label'   => $this->getLabel(),
			'options' => $options,
		);

		return $this->getRenderer($this->renderLayout)->render($data);
	}

	/**
	 * Method to get the data to be passed to the layout for rendering.
	 *
	 * @return  array
	 *
	 * @since 3.5
	 */
	protected function getLayoutData()
	{
		// Label preprocess
		$label = $this->element['label'] ? (string)
$this->element['label'] : (string)
$this->element['name'];
		$label = $this->translateLabel ? \JText::_($label) : $label;

		// Description preprocess
		$description = !empty($this->description) ? $this->description :
null;
		$description = !empty($description) &&
$this->translateDescription ? \JText::_($description) : $description;

		$alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_',
$this->fieldname);

		return array(
			'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 ?
\JText::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,
		);
	}

	/**
	 * 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';
	}
}
FormHelper.php000064400000031163151160211170007317 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\String\Normalise;
use Joomla\String\StringHelper;

\JLoader::import('joomla.filesystem.path');

/**
 * 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   string
	 * @since 3.8.0
	 */
	protected static $prefixes = array('field' => array(),
'form' => array(), 'rule' => array());

	/**
	 * 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 = array('field' => array(),
'form' => array(), 'rule' => array());

	/**
	 * 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 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 JFormField class file if it isn't already
imported.
	 * You can use this method outside of JForm 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 JFormRule class file if it isn't already
imported.
	 * You can use this method outside of JForm 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);
	}

	/**
	 * 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));

			// Compile the classname
			$class = rtrim($prefix, '\\') . '\\' .
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 = \JPath::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   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  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   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  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   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  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 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   mixed   $new     A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @since   1.7.0
	 */
	protected static function addPath($entity, $new = null)
	{
		// Reference to an array with paths for current entity
		$paths = &self::$paths[$entity];

		// Add the default entity's search path if not set.
		if (empty($paths))
		{
			// While we support limited number of entities (form, field and rule)
			// we can do this simple pluralisation:
			$entity_plural = $entity . 's';

			/*
			 * But when someday we would want to support more entities, then we
should consider adding
			 * an inflector class to "libraries/joomla/utilities" and use
it here (or somebody can use a real inflector in his subclass).
			 * See also: pluralization snippet by Paul Osman in
JControllerForm's constructor.
			 */
			$paths[] = __DIR__ . '/' . $entity_plural;
		}

		// 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   mixed  $new  A namespaces or array of namespaces to add.
	 *
	 * @return  array  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   mixed  $new  A namespace or array of namespaces to add.
	 *
	 * @return  array  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   mixed  $new  A namespace or array of namespaces to add.
	 *
	 * @return  array  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 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   mixed   $new     A namespace or array of namespaces to add.
	 *
	 * @return  array  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 array();
		}

		$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  = array();
		$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);

			if (strpos($showOnPartBlocks[0], '.') !== false)
			{
				if ($formControl)
				{
					$field = $formControl . ('[' . str_replace('.',
'][', $showOnPartBlocks[0]) . ']');
				}
				else
				{
					$groupParts = explode('.', $showOnPartBlocks[0]);
					$field      = array_shift($groupParts) . '[' .
join('][', $groupParts) . ']';
				}
			}
			else
			{
				$field = $formPath ? $formPath . '[' . $showOnPartBlocks[0] .
']' : $showOnPartBlocks[0];
			}

			$showOnData[] = array(
				'field'  => $field,
				'values' => explode(',', $showOnPartBlocks[1]),
				'sign'   => $compareEqual === true ? '=' :
'!=',
				'op'     => $op,
			);

			if ($op !== '')
			{
				$op = '';
			}
		}

		return $showOnData;
	}
}
FormRule.php000064400000005041151160211200006775 0ustar00<?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;

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
	 *
	 * @var    boolean
	 * @since  1.6
	 */
	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 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)));
		}

		// Add unicode property support if available.
		if (JCOMPAT_UNICODE_PROPERTIES)
		{
			$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;
	}
}
FormWrapper.php000064400000006560151160211200007515 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

/**
 * Wrapper class for FormHelper
 *
 * @since       3.4
 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
 */
class FormWrapper
{
	/**
	 * Helper wrapper method for loadFieldType
	 *
	 * @param   string   $type  The field type.
	 * @param   boolean  $new   Flag to toggle whether we should get a new
instance of the object.
	 *
	 * @return  mixed  JFormField object on success, false otherwise.
	 *
	 * @see     FormHelper::loadFieldType()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function loadFieldType($type, $new = true)
	{
		return FormHelper::loadFieldType($type, $new);
	}

	/**
	 * Helper wrapper method for loadRuleType
	 *
	 * @param   string   $type  The field type.
	 * @param   boolean  $new   Flag to toggle whether we should get a new
instance of the object.
	 *
	 * @return  mixed  JFormField object on success, false otherwise.
	 *
	 * @see     FormHelper::loadRuleType()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function loadRuleType($type, $new = true)
	{
		return FormHelper::loadRuleType($type, $new);
	}

	/**
	 * Helper wrapper method for loadFieldClass
	 *
	 * @param   string  $type  Type of a field whose class should be loaded.
	 *
	 * @return  mixed  Class name on success or false otherwise.
	 *
	 * @see     FormHelper::loadFieldClass()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function loadFieldClass($type)
	{
		return FormHelper::loadFieldClass($type);
	}

	/**
	 * Helper wrapper method for loadRuleClass
	 *
	 * @param   string  $type  Type of a rule whose class should be loaded.
	 *
	 * @return  mixed  Class name on success or false otherwise.
	 *
	 * @see     FormHelper::loadRuleClass()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function loadRuleClass($type)
	{
		return FormHelper::loadRuleClass($type);
	}

	/**
	 * Helper wrapper method for addFieldPath
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @see     FormHelper::addFieldPath()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function addFieldPath($new = null)
	{
		return FormHelper::addFieldPath($new);
	}

	/**
	 * Helper wrapper method for addFormPath
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @see     FormHelper::addFormPath()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function addFormPath($new = null)
	{
		return FormHelper::addFormPath($new);
	}

	/**
	 * Helper wrapper method for addRulePath
	 *
	 * @param   mixed  $new  A path or array of paths to add.
	 *
	 * @return  array  The list of paths that have been added.
	 *
	 * @see     FormHelper::addRulePath()
	 * @since   3.4
	 * @deprecated  4.0  Use `Joomla\CMS\Form\FormHelper` directly
	 */
	public function addRulePath($new = null)
	{
		return FormHelper::addRulePath($new);
	}
}
Rule/BooleanRule.php000064400000001356151160211200010365 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\FormRule;

/**
 * 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';
}
Rule/CalendarRule.php000064400000003673151160211200010523 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Date\Date;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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 \JFactory::getDate($value) instanceof Date;
		}
		catch (\Exception $e)
		{
			return false;
		}
	}
}
Rule/CaptchaRule.php000064400000004162151160211200010347 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Captcha\Captcha;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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    = \JFactory::getApplication();
		$plugin = $app->get('captcha');

		if ($app->isClient('site'))
		{
			$plugin = $app->getParams()->get('captcha', $plugin);
		}

		$namespace = $element['namespace'] ?: $form->getName();

		// Use 0 for none
		if ($plugin === 0 || $plugin === '0')
		{
			return true;
		}

		try
		{
			$captcha = Captcha::getInstance((string) $plugin,
array('namespace' => (string) $namespace));
			return $captcha->checkAnswer($value);
		}
		catch (\RuntimeException $e)
		{
			\JFactory::getApplication()->enqueueMessage($e->getMessage(),
'error');
		}
		return false;
	}
}
Rule/ColorRule.php000064400000004076151160211200010066 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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;
	}
}
Rule/EmailRule.php000064400000014025151160211200010032 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * Form Rule class for the Joomla Platform.
 *
 * @since  1.7.0
 */
class EmailRule extends FormRule
{
	/**
	 * The regular expression to use in testing a form field value.
	 *
	 * @var    string
	 * @since  1.7.0
	 * @link   http://www.w3.org/TR/html-markup/input.email.html
	 */
	protected $regex =
"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[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, Exception on
failure.
	 *
	 * @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;
		}

		// 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 = \JStringPunycode::emailToPunycode($value);

			// Test the value against the regular expression.
			if (!parent::test($element, $value, $group, $input, $form))
			{
				return new
\UnexpectedValueException(\JText::_('JLIB_DATABASE_ERROR_VALID_MAIL'));
			}
		}
		else
		{
			$values = explode(',', $value);

			foreach ($values as $value)
			{
				// Handle idn email addresses by converting to punycode.
				$value = \JStringPunycode::emailToPunycode($value);

				// Test the value against the regular expression.
				if (!parent::test($element, $value, $group, $input, $form))
				{
					return new
\UnexpectedValueException(\JText::_('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 = (isset($element['validDomains']) &&
$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)
				{
					return new
\UnexpectedValueException(\JText::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 = \JFactory::getDbo();
			$query = $db->getQuery(true);

			// Build the query.
			$query->select('COUNT(*)')
				->from('#__users')
				->where('email = ' . $db->quote($value));

			// Get the extra field check attribute.
			$userId = ($form instanceof Form) ? $form->getValue('id') :
'';
			$query->where($db->quoteName('id') . ' <>
' . (int) $userId);

			// Set and query the database.
			$db->setQuery($query);
			$duplicate = (bool) $db->loadResult();

			if ($duplicate)
			{
				return new
\UnexpectedValueException(\JText::_('JLIB_DATABASE_ERROR_EMAIL_INUSE'));
			}
		}

		return true;
	}
}
Rule/EqualsRule.php000064400000004611151160211200010235 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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;
	}
}
Rule/ExistsRule.php000064400000004253151160211200010264 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * Form rule class to determine if a value exists in a database table.
 *
 * @since  3.9.0
 */
class ExistsRule extends FormRule
{
	/**
	 * 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 = Factory::getDbo();

		// 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;
	}
}
Rule/FilePathRule.php000064400000004231151160211200010475 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Filesystem\Path;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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;
		}

		// Append the root path
		$value = JPATH_ROOT . '/' . $value;

		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;
	}
}
Rule/NotequalsRule.php000064400000004266151160211200010764 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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;
	}
}
Rule/NumberRule.php000064400000004167151160211200010241 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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;
	}
}
Rule/OptionsRule.php000064400000005476151160211200010450 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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 = array();

		// 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);
		}
	}
}
Rule/PasswordRule.php000064400000014405151160211200010607 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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'] : 4;
		$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;

		// 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');
			$minimumIntegersp  = $params->get('minimum_integers');
			$minimumSymbolsp   = $params->get('minimum_symbols');
			$minimumUppercasep = $params->get('minimum_uppercase');
			$minimumLowercasep = $params->get('minimum_lowercase');
			$meterp            = $params->get('meter');
			$thresholdp        = $params->get('threshold');

			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);

		// Load language file of com_users component
		\JFactory::getLanguage()->load('com_users');

		// We set a maximum length to prevent abuse since it is unfiltered.
		if ($valueLength > 4096)
		{
			\JFactory::getApplication()->enqueueMessage(\JText::_('COM_USERS_MSG_PASSWORD_TOO_LONG'),
'warning');
		}

		// 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)
		{
			\JFactory::getApplication()->enqueueMessage(
				\JText::_('COM_USERS_MSG_SPACES_IN_PASSWORD'),
				'warning'
			);

			$validPassword = false;
		}

		// Minimum number of integers required
		if (!empty($minimumIntegers))
		{
			$nInts = preg_match_all('/[0-9]/', $value, $imatch);

			if ($nInts < $minimumIntegers)
			{
				\JFactory::getApplication()->enqueueMessage(
					\JText::plural('COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N',
$minimumIntegers),
					'warning'
				);

				$validPassword = false;
			}
		}

		// Minimum number of symbols required
		if (!empty($minimumSymbols))
		{
			$nsymbols = preg_match_all('[\W]', $value, $smatch);

			if ($nsymbols < $minimumSymbols)
			{
				\JFactory::getApplication()->enqueueMessage(
					\JText::plural('COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N',
$minimumSymbols),
					'warning'
				);

				$validPassword = false;
			}
		}

		// Minimum number of upper case ASCII characters required
		if (!empty($minimumUppercase))
		{
			$nUppercase = preg_match_all('/[A-Z]/', $value, $umatch);

			if ($nUppercase < $minimumUppercase)
			{
				\JFactory::getApplication()->enqueueMessage(
					\JText::plural('COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N',
$minimumUppercase),
					'warning'
				);

				$validPassword = false;
			}
		}

		// Minimum number of lower case ASCII characters required
		if (!empty($minimumLowercase))
		{
			$nLowercase = preg_match_all('/[a-z]/', $value, $umatch);

			if ($nLowercase < $minimumLowercase)
			{
				\JFactory::getApplication()->enqueueMessage(
					\JText::plural('COM_USERS_MSG_NOT_ENOUGH_LOWERCASE_LETTERS_N',
$minimumLowercase),
					'warning'
				);

				$validPassword = false;
			}
		}

		// Minimum length option
		if (!empty($minimumLength))
		{
			if (strlen((string) $value) < $minimumLength)
			{
				\JFactory::getApplication()->enqueueMessage(
					\JText::plural('COM_USERS_MSG_PASSWORD_TOO_SHORT_N',
$minimumLength),
					'warning'
				);

				$validPassword = false;
			}
		}

		// If valid has violated any rules above return false.
		if (!$validPassword)
		{
			return false;
		}

		return true;
	}
}
Rule/RulesRule.php000064400000006661151160211200010104 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Access\Access;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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  array  A list of permission action names from the form field
value.
	 *
	 * @since   1.7.0
	 */
	protected function getValueActions($value)
	{
		$actions = array();

		// 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  array  A list of permission action names from the form field
element definition.
	 *
	 * @since   1.7.0
	 */
	protected function getFieldActions(\SimpleXMLElement $element)
	{
		$actions = array();

		// 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::getActions($component, $section);

		// 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;
	}
}
Rule/SubFormRule.php000064400000004654151160211200010367 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\Registry\Registry;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;

/**
 * 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 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 \JFormFieldSubform))
		{
			throw new \UnexpectedValueException(sprintf('%s is no subform
field.', $element['name']));
		}

		$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;
				}
			}
		}
		// Single value.
		else
		{
			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;
	}
}
Rule/TelRule.php000064400000006215151160211200007531 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * 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 = array(
			'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;
	}
}
Rule/UrlRule.php000064400000010520151160211200007541 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
use Joomla\Uri\UriHelper;

/**
 * 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    http://www.w3.org/Addressing/URL/url-spec.txt
	 * @see	    JString
	 */
	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;
		}

		$urlParts = UriHelper::parse_url($value);

		// See http://www.w3.org/Addressing/URL/url-spec.txt
		// Use the full list or optionally specify a list of permitted schemes.
		if ($element['schemes'] == '')
		{
			$scheme = array('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',
\JText::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 = array('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) &&
!is_int((int) $urlParts['port']))
		{
			return false;
		}

		if (array_key_exists('path', $urlParts) &&
!StringHelper::valid((string) $urlParts['path']))
		{
			return false;
		}

		return true;
	}
}
Rule/UsernameRule.php000064400000004073151160211200010564 0ustar00<?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;

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormRule;
use Joomla\Registry\Registry;

/**
 * Form Rule class for the Joomla Platform.
 *
 * @since  1.7.0
 */
class UsernameRule extends FormRule
{
	/**
	 * 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 = \JFactory::getDbo();
		$query = $db->getQuery(true);

		// Build the query.
		$query->select('COUNT(*)')
			->from('#__users')
			->where('username = ' . $db->quote($value));

		// Get the extra field check attribute.
		$userId = ($form instanceof Form) ? $form->getValue('id') :
'';
		$query->where($db->quoteName('id') . ' <>
' . (int) $userId);

		// Set and query the database.
		$db->setQuery($query);
		$duplicate = (bool) $db->loadResult();

		if ($duplicate)
		{
			return false;
		}

		return true;
	}
}
AbstractContainer.php000064400000002751151160515070010671 0ustar00<?php


namespace Nextend\Framework\Form;


abstract class AbstractContainer implements ContainerContainedInterface {

    use TraitContainer;

    /**
     * @var ContainerContainedInterface
     */
    protected $first, $last;

    protected $controlName = '';

    /**
     * @var ContainerInterface;
     */
    private $previous, $next;

    public function getPrevious() {
        return $this->previous;
    }

    /**
     * @param ContainedInterface|null $element
     */
    public function setPrevious($element = null) {
        $this->previous = $element;
    }

    public function getNext() {
        return $this->next;
    }

    /**
     * @param ContainedInterface|null $element
     */
    public function setNext($element = null) {
        $this->next = $element;
        if ($element) {
            $element->setPrevious($this);
        }
    }

    public function remove() {
        $this->getParent()
             ->removeElement($this);
    }

    public function render() {
        $this->renderContainer();
    }

    public function renderContainer() {
        $element = $this->first;
        while ($element) {
            $element->renderContainer();
            $element = $element->getNext();
        }
    }

    /**
     * @return string
     */
    public function getControlName() {
        return $this->controlName;
    }

    /**
     * @param string $controlName
     */
    public function setControlName($controlName) {
        $this->controlName = $controlName;
    }
}AbstractField.php000064400000017711151160515070007774 0ustar00<?php


namespace Nextend\Framework\Form;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Insert\AbstractInsert;
use Nextend\Framework\View\Html;

abstract class AbstractField implements ContainedInterface {

    /**
     * @var AbstractField;
     */
    private $previous, $next;

    public function getPrevious() {
        return $this->previous;
    }

    /**
     * @param AbstractField|null $element
     */
    public function setPrevious($element = null) {
        $this->previous = $element;
    }

    public function getNext() {
        return $this->next;
    }

    /**
     * @param AbstractField|null $element
     */
    public function setNext($element = null) {
        $this->next = $element;
        if ($element) {
            $element->setPrevious($this);
        }
    }

    public function remove() {
        $this->getParent()
             ->removeElement($this);
    }

    /**
     * @var TraitFieldset
     */
    protected $parent;

    protected $name = '';

    protected $label = '';

    protected $controlName = '';

    protected $defaultValue;

    protected $fieldID;

    private $exposeName = true;

    protected $tip = '';

    protected $tipLabel = '';

    protected $tipDescription = '';

    protected $tipLink = '';

    protected $rowClass = '';

    protected $rowAttributes = array();

    protected $class = '';

    protected $style = '';

    protected $post = '';

    protected $relatedFields = array();

    protected $relatedFieldsOff = array();

    /**
     * AbstractField constructor.
     *
     * @param TraitFieldset|AbstractInsert $insertAt
     * @param string                       $name
     * @param string                       $label
     * @param string                       $default
     * @param array                        $parameters
     */
    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {

        $this->name  = $name;
        $this->label = $label;

        if ($insertAt instanceof ContainerInterface) {
            $this->parent = $insertAt;
            $this->parent->addElement($this);
        } else if ($insertAt instanceof AbstractInsert) {
            $this->parent = $insertAt->insert($this);
        }

        $this->controlName = $this->parent->getControlName();

        $this->fieldID = $this->generateId($this->controlName .
$this->name);

        $this->defaultValue = $default;

        foreach ($parameters as $option => $value) {
            $option = 'set' . $option;
            $this->{$option}($value);
        }
    }

    /**
     * @return string
     */
    public function getID() {
        return $this->fieldID;
    }

    public function setDefaultValue($defaultValue) {
        $this->defaultValue = $defaultValue;
    }

    public function setExposeName($exposeName) {
        $this->exposeName = $exposeName;
    }

    public function getPost() {
        return $this->post;
    }

    public function setPost($post) {
        $this->post = $post;
    }

    /**
     * @param string $tip
     */
    public function setTip($tip) {
        $this->tip = $tip;
    }

    /**
     * @param string $tipLabel
     */
    public function setTipLabel($tipLabel) {
        $this->tipLabel = $tipLabel;
    }

    /**
     * @param string $tipDescription
     */
    public function setTipDescription($tipDescription) {
        $this->tipDescription = $tipDescription;
    }

    /**
     * @param string $tipLink
     */
    public function setTipLink($tipLink) {
        $this->tipLink = $tipLink;
    }

    public function setRowClass($rowClass) {
        $this->rowClass .= $rowClass;
    }

    public function getRowClass() {
        return $this->rowClass;
    }

    public function getClass() {
        return $this->class;
    }

    public function setClass($class) {
        $this->class = $class;
    }

    protected function getFieldName() {
        if ($this->exposeName) {
            return $this->controlName . '[' . $this->name .
']';
        }

        return '';
    }

    public function render() {

        return array(
            $this->fetchTooltip(),
            $this->fetchElement()
        );
    }

    public function displayLabel() {

        echo $this->fetchTooltip();
    }

    public function displayElement() {

        echo $this->fetchElement();
    }

    protected function fetchTooltip() {

        if ($this->label === false || $this->label === '')
{
            return '';
        }

        $attributes = array(
            'for' => $this->fieldID
        );


        $post = '';
        if (!empty($this->tipDescription)) {
            $tipAttributes = array(
                'class'                => 'ssi_16
ssi_16--info',
                'data-tip-description' =>
$this->tipDescription
            );
            if (!empty($this->tipLabel)) {
                $tipAttributes['data-tip-label'] =
$this->tipLabel;
            }
            if (!empty($this->tipLink)) {
                $tipAttributes['data-tip-link'] =
$this->tipLink;
            }
            $post .= Html::tag('i', $tipAttributes);
        }

        return Html::tag('label', $attributes, $this->label) .
$post;
    }

    protected function fetchNoTooltip() {
        return "";
    }

    /**
     * @return string
     */
    abstract protected function fetchElement();

    public function getValue() {
        return $this->getForm()
                    ->get($this->name, $this->defaultValue);
    }

    public function setValue($value) {
        $this->parent->getForm()
                     ->set($this->name, $value);
    }

    /**
     * @param array $rowAttributes
     */
    public function setRowAttributes($rowAttributes) {
        $this->rowAttributes = $rowAttributes;
    }

    /**
     * @return array
     */
    public function getRowAttributes() {
        return $this->rowAttributes;
    }

    public function setStyle($style) {
        $this->style = $style;
    }

    protected function getStyle() {
        return $this->style;
    }

    /**
     * @param string $relatedFields
     */
    public function setRelatedFields($relatedFields) {
        $this->relatedFields = $relatedFields;
    }

    public function setRelatedFieldsOff($relatedFieldsOff) {
        $this->relatedFieldsOff = $relatedFieldsOff;
    }

    protected function renderRelatedFields() {
        if (!empty($this->relatedFields) ||
!empty($this->relatedFieldsOff)) {
            $options = array(
                'relatedFieldsOn'  => $this->relatedFields,
                'relatedFieldsOff' =>
$this->relatedFieldsOff
            );
            Js::addInline('new _N2.FormRelatedFields("' .
$this->fieldID . '", ' . json_encode($options) .
');');
        }
    }

    /**
     * @param $name
     *
     * @return string
     */
    protected function generateId($name) {

        return str_replace(array(
            '[',
            ']',
            ' '
        ), array(
            '',
            '',
            ''
        ), $name);
    }

    public function getLabelClass() {
        if ($this->label === false) {
            return 'n2_field--label-none';
        } else if ($this->label === '') {
            return 'n2_field--label-placeholder';
        }

        return '';
    }

    /**
     * @return bool
     */
    public function hasLabel() {
        return !empty($this->label);
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @return Form
     */
    public function getForm() {
        return $this->parent->getForm();
    }

    /**
     * @return string
     */
    public function getControlName() {
        return $this->controlName;
    }

    /**
     * @param string $controlName
     */
    public function setControlName($controlName) {
        $this->controlName = $controlName;
    }

    /**
     * @return TraitFieldset
     */
    public function getParent() {
        return $this->parent;
    }

    public function getPath() {
        return $this->parent->getPath() . '/' .
$this->name;
    }
}AbstractFieldset.php000064400000005644151160515070010512 0ustar00<?php


namespace Nextend\Framework\Form;

use Nextend\Framework\Form\Insert\AbstractInsert;

abstract class AbstractFieldset implements ContainerContainedInterface {

    use TraitFieldset;

    /**
     * @var ContainedInterface;
     */
    private $previous, $next;

    public function getPrevious() {
        return $this->previous;
    }

    public function setPrevious($element = null) {
        $this->previous = $element;
    }

    public function getNext() {
        return $this->next;
    }

    public function setNext($element = null) {
        $this->next = $element;
        if ($element) {
            $element->setPrevious($this);
        }
    }

    public function remove() {
        $this->getParent()
             ->removeElement($this);
    }

    /**
     * @var ContainerInterface
     */
    protected $parent;

    protected $name = '';

    protected $label = '';

    protected $controlName = '';

    protected $class = '';

    /**
     * Container constructor.
     *
     * @param ContainerInterface|AbstractInsert $insertAt
     * @param                                   $name
     * @param boolean|string                    $label
     * @param array                             $parameters
     */
    public function __construct($insertAt, $name, $label = false,
$parameters = array()) {

        $this->name  = $name;
        $this->label = $label;

        if ($insertAt instanceof ContainerInterface) {
            $this->parent = $insertAt;
            $this->parent->addElement($this);
        } else if ($insertAt instanceof AbstractInsert) {
            $this->parent = $insertAt->insert($this);
        }

        $this->controlName = $this->parent->getControlName();

        foreach ($parameters AS $option => $value) {
            $option = 'set' . $option;
            $this->{$option}($value);
        }

    }

    public function render() {
        $this->renderContainer();
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        ob_start();

        $element->displayElement();

        return ob_get_clean();
    }

    /**
     * @return bool
     */
    public function hasLabel() {
        return !empty($this->label);
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @return Form
     */
    public function getForm() {
        return $this->parent->getForm();
    }

    /**
     * @return string
     */
    public function getControlName() {
        return $this->controlName;
    }

    /**
     * @param string $controlName
     */
    public function setControlName($controlName) {
        $this->controlName = $controlName;
    }

    public function hasFields() {

        return !empty($this->flattenElements);
    }

    /**
     * @param string $class
     */
    public function setClass($class) {
        $this->class = $class;
    }
}AbstractFormManager.php000064400000000540151160515070011137
0ustar00<?php


namespace Nextend\Framework\Form;


use Nextend\Framework\Pattern\MVCHelperTrait;

abstract class AbstractFormManager {

    use MVCHelperTrait;

    /**
     * AbstractFormManager constructor.
     *
     * @param MVCHelperTrait $MVCHelper
     */
    public function __construct($MVCHelper) {

        $this->setMVCHelper($MVCHelper);
    }
}Base/PlatformFormBase.php000064400000000402151160515070011327
0ustar00<?php


namespace Nextend\Framework\Form\Base;

class PlatformFormBase {

    public function tokenize() {
        return '';
    }

    public function tokenizeUrl() {
        return '';
    }

    public function checkToken() {
        return true;
    }
}ContainedInterface.php000064400000001266151160515070011010
0ustar00<?php


namespace Nextend\Framework\Form;


interface ContainedInterface {

    /**
     * @return ContainedInterface|null
     */
    public function getPrevious();

    /**
     * @param ContainedInterface|null $element
     */
    public function setPrevious($element = null);

    /**
     * @return ContainedInterface|null
     */
    public function getNext();

    /**
     * @param ContainedInterface|null $element
     */
    public function setNext($element = null);

    public function remove();

    /**
     * @return ContainerInterface
     */
    public function getParent();

    /**
     * @return string
     */
    public function getPath();

    public function render();
}Container/ContainerAlternative.php000064400000000313151160515070013316
0ustar00<?php


namespace Nextend\Framework\Form\Container;


use Nextend\Framework\Form\ContainerGeneral;

class ContainerAlternative extends ContainerGeneral {

    public function renderContainer() {

    }
}Container/ContainerRowGroup.php000064400000001562151160515070012633
0ustar00<?php


namespace Nextend\Framework\Form\Container;


use Nextend\Framework\Form\ContainerGeneral;
use Nextend\Framework\Form\Fieldset\FieldsetRow;

class ContainerRowGroup extends ContainerGeneral {

    public function renderContainer() {
        echo '<div class="n2_form__table_row_group"
data-field="table-row-group-' . $this->name .
'">';
        if ($this->label !== false) {
            echo '<div
class="n2_form__table_row_group_label">';
            echo $this->label;
            echo '</div>';
        }

        echo '<div class="n2_form__table_row_group_rows"
data-field="table-row-group-rows-' . $this->name .
'">';
        parent::renderContainer();
        echo '</div>';
        echo '</div>';
    }

    /**
     * @param $name
     *
     * @return FieldsetRow
     */
    public function createRow($name) {

        return new FieldsetRow($this, $name);
    }
}Container/ContainerSubform.php000064400000000675151160515070012470
0ustar00<?php


namespace Nextend\Framework\Form\Container;


use Nextend\Framework\Form\ContainerGeneral;

class ContainerSubform extends ContainerGeneral {

    public function renderContainer() {
        echo '<div id="' . $this->getId() .
'" class="n2_form__subform">';
        parent::renderContainer();
        echo '</div>';
    }

    public function getId() {
        return 'n2_form__subform_' . $this->controlName .
'_' . $this->name;
    }
}Container/ContainerTab.php000064400000001062151160515070011550
0ustar00<?php


namespace Nextend\Framework\Form\Container;


use Nextend\Framework\Form\ContainerGeneral;

class ContainerTab extends ContainerGeneral {

    public function renderContainer() {
        echo '<div class="n2_form__tab"
data-related-form="' . $this->getForm()
                                                                   
->getId() . '" data-tab="' . $this->getId() .
'">';
        parent::renderContainer();
        echo '</div>';
    }

    public function getId() {
        return 'n2_form__tab_' . $this->controlName .
'_' . $this->name;
    }
}Container/ContainerTable.php000064400000004173151160515070012077
0ustar00<?php


namespace Nextend\Framework\Form\Container;

use Nextend\Framework\Form\ContainerGeneral;
use Nextend\Framework\Form\Fieldset\FieldsetRow;
use Nextend\Framework\Form\Fieldset\FieldsetTableLabel;

class ContainerTable extends ContainerGeneral {

    /**
     * @var FieldsetTableLabel
     */
    protected $fieldsetLabel;

    protected $fieldsetLabelPosition = 'start';

    public function __construct($insertAt, $name, $label = false,
$parameters = array()) {
        parent::__construct($insertAt, $name, $label, $parameters);

        $labelContainer      = new ContainerAlternative($this, $name .
'-container-label');
        $this->fieldsetLabel = new FieldsetTableLabel($labelContainer,
$name . '-label', false);
    }

    public function renderContainer() {
        echo '<div class="n2_form__table"
data-field="table-' . $this->name . '">';
        echo '<div
class="n2_form__table_label">';
        echo '<div
class="n2_form__table_label_title">';
        echo $this->label;
        echo '</div>';
        if ($this->fieldsetLabel->hasFields()) {
            echo '<div class="n2_form__table_label_fields
n2_form__table_label_fields--' . $this->fieldsetLabelPosition .
'">';
            $this->fieldsetLabel->renderContainer();
            echo '</div>';
        }
        echo '</div>';

        if ($this->first) {
            echo '<div class="n2_form__table_rows"
data-field="table-rows-' . $this->name .
'">';
            parent::renderContainer();
            echo '</div>';
        }
        echo '</div>';
    }

    /**
     * @param $name
     *
     * @return FieldsetRow
     */
    public function createRow($name) {

        return new FieldsetRow($this, $name);
    }

    /**
     * @param        $name
     * @param string $label
     *
     * @return ContainerRowGroup
     */
    public function createRowGroup($name, $label) {

        return new ContainerRowGroup($this, $name, $label);
    }

    /**
     * @return FieldsetTableLabel
     */
    public function getFieldsetLabel() {
        return $this->fieldsetLabel;
    }

    public function setFieldsetPositionEnd() {
        $this->fieldsetLabelPosition = 'end';
    }

}Container/LayerWindow/ContainerAnimation.php000064400000002107151160515070015226
0ustar00<?php


namespace Nextend\Framework\Form\Container\LayerWindow;


use Nextend\Framework\Form\ContainerGeneral;

class ContainerAnimation extends ContainerGeneral {

    /**
     * @param $name
     * @param $label
     *
     * @return ContainerAnimationTab
     */
    public function createTab($name, $label) {
        return new ContainerAnimationTab($this, $name, $label);
    }

    public function renderContainer() {
        echo '<div class="n2_container_animation"
data-field="animation-' . $this->name .
'">';
        echo '<div
class="n2_container_animation__buttons">';

        $element = $this->first;
        while ($element) {

            if ($element instanceof ContainerAnimationTab) {
                echo '<div
class="n2_container_animation__button"
data-related-tab="' . $element->getName() .
'">' . $element->getLabel() .
'</div>';
            }

            $element = $element->getNext();
        }

        echo '</div>';
        echo '<div
class="n2_container_animation__tabs">';
        parent::renderContainer();
        echo '</div>';
        echo '</div>';
    }
}Container/LayerWindow/ContainerAnimationTab.php000064400000000552151160515070015657
0ustar00<?php


namespace Nextend\Framework\Form\Container\LayerWindow;


use Nextend\Framework\Form\ContainerGeneral;

class ContainerAnimationTab extends ContainerGeneral {

    public function renderContainer() {
        echo '<div class="n2_container_animation__tab"
data-tab="' . $this->name . '">';
        parent::renderContainer();
        echo '</div>';
    }
}Container/LayerWindow/ContainerDesign.php000064400000002042151160515070014516
0ustar00<?php


namespace Nextend\Framework\Form\Container\LayerWindow;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\ContainerGeneral;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\View\Html;

class ContainerDesign extends ContainerGeneral {

    public function __construct(ContainerInterface $insertAt, $name) {
        parent::__construct($insertAt, $name);
    }

    public function renderContainer() {

        $id = 'n2_css_' . $this->name;

        echo Html::openTag('div', array(
            'id'    => $id,
            'class' => 'n2_ss_design_' .
$this->name
        ));

        $element = $this->first;
        while ($element) {
            $element->renderContainer();
            $element = $element->getNext();
        }

        echo Html::closeTag('div');

        $options = array(
            'ajaxUrl' => $this->getForm()
                              ->createAjaxUrl('css/index')
        );

        Js::addInline('new _N2.BasicCSS(' . json_encode($id) .
', ' . json_encode($options) . ');');
    }
}Container/LayerWindow/ContainerSettings.php000064400000001101151160515070015100
0ustar00<?php


namespace Nextend\Framework\Form\Container\LayerWindow;


use Nextend\Framework\Form\ContainerGeneral;
use Nextend\Framework\Form\ContainerInterface;

class ContainerSettings extends ContainerGeneral {

    public function __construct(ContainerInterface $insertAt, $name,
$parameters = array()) {
        parent::__construct($insertAt, $name, false, $parameters);
    }

    public function renderContainer() {
        echo '<div class="n2_ss_layer_window__tab_panel"
data-panel="' . $this->name . '">';
        parent::renderContainer();
        echo '</div>';
    }
}ContainerContainedInterface.php000064400000000205151160515070012643
0ustar00<?php


namespace Nextend\Framework\Form;


interface ContainerContainedInterface extends ContainerInterface,
ContainedInterface {

}ContainerGeneral.php000064400000005213151160515070010477 0ustar00<?php

namespace Nextend\Framework\Form;

use Nextend\Framework\Form\Insert\AbstractInsert;

class ContainerGeneral extends AbstractContainer {

    /**
     * @var ContainerInterface
     */
    protected $parent;

    protected $name = '';

    protected $label = '';

    protected $class = '';

    /**
     * Container constructor.
     *
     * @param ContainerInterface|AbstractInsert $insertAt
     * @param string                            $name
     * @param boolean|string                    $label
     * @param array                             $parameters
     */
    public function __construct($insertAt, $name, $label = false,
$parameters = array()) {

        $this->name  = $name;
        $this->label = $label;

        if ($insertAt instanceof ContainerInterface) {
            $this->parent = $insertAt;
            $this->parent->addElement($this);
        } else if ($insertAt instanceof AbstractInsert) {
            $this->parent = $insertAt->insert($this);
        }

        $this->controlName = $this->parent->getControlName();

        foreach ($parameters AS $option => $value) {
            $option = 'set' . $option;
            $this->{$option}($value);
        }

    }

    public function removeElement($element) {
        $previous = $element->getPrevious();
        $next     = $element->getNext();

        if ($this->first === $element) {
            $this->first = $next;
        }

        if ($this->last === $element) {
            $this->last = $previous;
        }

        if ($previous) {
            $previous->setNext($next);
        } else {
            $next->setPrevious();
        }
    }

    /**
     * @return ContainerInterface
     */
    public function getParent() {
        return $this->parent;
    }

    public function getPath() {
        return $this->parent->getPath() . '/' .
$this->name;
    }

    /**
     * @param string $class
     */
    public function setClass($class) {
        $this->class = $class;
    }

    /**
     * @return bool
     */
    public function hasLabel() {
        return !empty($this->label);
    }

    /**
     * @return string
     */
    public function getLabel() {
        return $this->label;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @return Form
     */
    public function getForm() {
        return $this->parent->getForm();
    }

    /**
     * @return string
     */
    public function getControlName() {
        return $this->controlName;
    }

    /**
     * @param string $controlName
     */
    public function setControlName($controlName) {
        $this->controlName = $controlName;
    }
}ContainerInterface.php000064400000002022151160515070011015
0ustar00<?php


namespace Nextend\Framework\Form;


interface ContainerInterface {

    /**
     * @param ContainedInterface $element
     */
    public function addElement($element);

    /**
     * @param ContainedInterface $element
     * @param ContainedInterface $target
     */
    public function insertElementBefore($element, $target);

    /**
     * @param ContainedInterface $element
     * @param ContainedInterface $target
     */
    public function insertElementAfter($element, $target);

    /**
     * @param ContainedInterface $element
     */
    public function removeElement($element);

    /**
     * @param $path
     *
     * @return ContainedInterface
     */
    public function getElement($path);

    /**
     * @return string
     */
    public function getPath();

    /**
     * @return Form
     */
    public function getForm();

    /**
     * @return string
     */
    public function getName();

    /**
     * @return string
     */
    public function getControlName();

    public function renderContainer();
}ContainerMain.php000064400000003074151160515070010011 0ustar00<?php


namespace Nextend\Framework\Form;


use Nextend\Framework\Form\Fieldset\FieldsetHidden;

class ContainerMain extends AbstractContainer {

    /**
     * @var Form
     */
    protected $form;

    /**
     * @var FieldsetHidden
     */
    protected $fieldsetHidden;

    /**
     * ContainerMain constructor.
     *
     * @param Form $form
     */
    public function __construct($form) {
        $this->form        = $form;
        $this->controlName = $form->getControlName();

        $this->fieldsetHidden = new FieldsetHidden($this);
    }

    public function removeElement($element) {
        $previous = $element->getPrevious();
        $next     = $element->getNext();

        if ($this->first === $element) {
            $this->first = $next;
        }

        if ($this->last === $element) {
            $this->last = $previous;
        }

        if ($previous) {
            $previous->setNext($next);
        } else {
            $next->setPrevious();
        }
    }

    public function getParent() {
        return false;
    }

    public function getPath() {
        return '';
    }

    /**
     * @return Form
     */
    public function getForm() {
        return $this->form;
    }

    /**
     * @return string
     */
    public function getName() {
        return 'ContainerMain';
    }

    /**
     * @return FieldsetHidden
     */
    public function getFieldsetHidden() {
        return $this->fieldsetHidden;
    }

    /**
     *
     * @return ContainerContainedInterface
     */
    public function getFirst() {
        return $this->first;
    }
}Element/AbstractChooser.php000064400000003177151160515070011745
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Localization\Localization;
use Nextend\Framework\View\Html;

abstract class AbstractChooser extends AbstractFieldHidden {

    protected $hasClear = true;

    protected $class = '';

    protected $width;

    abstract protected function addScript();

    protected function fetchElement() {

        $this->addScript();

        $this->renderRelatedFields();

        return Html::tag('div', array(
            'class' => 'n2_field_chooser ' .
$this->class
        ), $this->pre() . parent::fetchElement() . $this->field() .
$this->post());
    }

    protected function pre() {

    }

    protected function field() {
        $style = '';
        if ($this->width) {
            $style = 'width: ' . $this->width .
'px;';
        }

        return '<div class="n2_field_chooser__label"
style="' . $style . '"></div>';
    }

    protected function post() {

        $html = '';
        if ($this->hasClear) {
            $html .= Html::tag('a', array(
                'href'  => '#',
                'class' => 'n2_field_chooser__clear'
            ), Html::tag('i', array('class' =>
'ssi_16 ssi_16--circularremove'), ''));
        }

        $html .= Html::tag('a', array(
            'href'  => '#',
            'class' => 'n2_field_chooser__choose'
        ), '<i class="ssi_16
ssi_16--plus"></i>');

        return $html;
    }

    /**
     * @param bool $hasClear
     */
    public function setHasClear($hasClear) {
        $this->hasClear = $hasClear;
    }

    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }
}Element/AbstractChooserText.php000064400000004136151160515070012606
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\View\Html;

abstract class AbstractChooserText extends AbstractFieldHidden {

    protected $hasClear = true;

    protected $width = 130;

    protected $class = '';

    protected $type = 'text';

    abstract protected function addScript();

    protected function fetchElement() {

        $this->addScript();

        $this->renderRelatedFields();

        return Html::tag('div', array(
            'class' => 'n2_field_text' .
$this->class
        ), $this->pre() . $this->field() . $this->post());
    }

    protected function pre() {

    }

    protected function field() {

        if ($this->type === 'hidden') {
            return Html::tag('input', array(
                'type'     => 'text',
                'style'    => 'width: ' .
$this->width . 'px;',
                'disabled' => 'disabled'
            ), false, false);
        }

        return Html::tag('input', array(
            'id'           => $this->fieldID,
            'name'         => $this->getFieldName(),
            'value'        => $this->getValue(),
            'type'         => $this->type,
            'style'        => 'width: ' .
$this->width . 'px;',
            'autocomplete' => 'off'
        ), false, false);

    }

    protected function post() {

        $html = '';
        if ($this->hasClear) {
            $html .= Html::tag('a', array(
                'href'     => '#',
                'class'    =>
'n2_field_text__clear',
                'tabindex' => -1
            ), Html::tag('i', array('class' =>
'ssi_16 ssi_16--circularremove'), ''));
        }

        $html .= Html::tag('a', array(
            'href'       => '#',
            'class'      => 'n2_field_text__choose',
            'aria-label' => n2_('Choose')
        ), '<i class="ssi_16
ssi_16--plus"></i>');

        return $html;
    }

    /**
     * @param bool $hasClear
     */
    public function setHasClear($hasClear) {
        $this->hasClear = $hasClear;
    }

    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }
}Element/AbstractFieldHidden.php000064400000001723151160515070012475
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\View\Html;

class AbstractFieldHidden extends AbstractField {

    protected $hasTooltip = true;

    protected $type = 'hidden';

    public function __construct($insertAt, $name = '', $label =
false, $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);
    }

    protected function fetchTooltip() {
        if ($this->hasTooltip) {
            return parent::fetchTooltip();
        } else {
            return $this->fetchNoTooltip();
        }
    }

    protected function fetchElement() {

        return Html::tag('input', array(
            'id'           => $this->fieldID,
            'name'         => $this->getFieldName(),
            'value'        => $this->getValue(),
            'type'         => $this->type,
            'autocomplete' => 'off'
        ), false, false);
    }
}Element/Breakpoint.php000064400000007015151160515070010750
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;
use Nextend\Framework\View\Html;

class Breakpoint extends AbstractField implements ContainerInterface {

    use TraitFieldset;

    protected $fields = array();

    protected $enables = false;

    protected $global = false;

    public function __construct($insertAt, $name = '', $fields =
array(), $enables = false, $global = false) {

        $this->fields  = $fields;
        $this->enables = $enables;
        $this->global  = $global;

        parent::__construct($insertAt, $name, false, '');
    }

    public function getLabelClass() {

        return parent::getLabelClass() . ' n2_field--raw';
    }

    protected function fetchElement() {

        $orientation = new Tab($this, $this->name .
'-orientation', n2_('Orientation'),
'portrait', array(
            'options' => array(
                'portrait'  => n2_('Portrait'),
                'landscape' => n2_('Landscape')
            )
        ));
        $devices = array(
            array(
                'id'    => 'mobileportrait',
                'icon'  => 'ssi_16
ssi_16--mobileportrait',
                'label' => n2_('Mobile')
            ),
            array(
                'id'    => 'mobilelandscape',
                'icon'  => 'ssi_16
ssi_16--mobileportraitlarge',
                'label' => n2_('Large mobile')
            ),
            array(
                'id'    => 'tabletportrait',
                'icon'  => 'ssi_16
ssi_16--tabletportrait',
                'label' => n2_('Tablet')
            ),
            array(
                'id'    => 'tabletlandscape',
                'icon'  => 'ssi_16
ssi_16--tabletportraitlarge',
                'label' => n2_('Large tablet')
            ),
            array(
                'id'    => 'desktopportrait',
                'icon'  => 'ssi_16
ssi_16--desktopportrait',
                'label' => n2_('Desktop')
            ),
            array(
                'id'    => 'desktoplandscape',
                'icon'  => 'ssi_16
ssi_16--desktoplandscape',
                'label' => n2_('Large desktop')
            )
        );

        $preHtml = '';
        $element = $this->first;
        while ($element) {
            $preHtml .= $this->decorateElement($element);

            $element = $element->getNext();
        }

        $html = '';

        for ($i = 0; $i < count($devices); $i++) {
            $html .= Html::tag('div', array(
                'data-id' => $devices[$i]['id'],
                'class'   =>
'n2_field_breakpoint__device'
            ), '<div
class="n2_field_breakpoint__device_enable"
data-n2tip="' . $devices[$i]['label'] .
'"><i class="' . $devices[$i]['icon'] .
'"></i></div>');
        }

        $options = array(
            'orientation' => $orientation->getID(),
            'fields'      => $this->fields,
            'enables'     => $this->enables,
            'global'      => $this->global
        );

        Js::addInline('new _N2.FormElementBreakpoint("' .
$this->fieldID . '", ' . json_encode($options) .
');');


        return '<div id="' . $this->getID() .
'" class="n2_field_breakpoint"><div
class="n2_field_breakpoint__pre_fields">' . $preHtml .
'</div><div
class="n2_field_breakpoint__breakpoint_container"
data-orientation="portrait">' . $html .
'</div></div>';
    }

    public function decorateElement($element) {
        return $this->parent->decorateElement($element);
    }

}Element/Button/ButtonIcon.php000064400000001442151160515070012207
0ustar00<?php


namespace Nextend\Framework\Form\Element\Button;


use Nextend\Framework\Form\Element\Button;

class ButtonIcon extends Button {

    protected $hoverTip = '';

    public function __construct($insertAt, $name = '', $label =
'', $icon = '', $parameters = array()) {

        $this->classes[] = 'n2_field_button--icon';
        parent::__construct($insertAt, $name, $label, '<i
class="' . $icon . '"></i>',
$parameters);
    }

    protected function getAttributes() {
        $attributes = parent::getAttributes();

        if (!empty($this->hoverTip)) {
            $attributes['data-n2tip'] = $this->hoverTip;
        }

        return $attributes;
    }

    /**
     * @param string $hoverTip
     */
    public function setHoverTip($hoverTip) {
        $this->hoverTip = $hoverTip;
    }
}Element/Button/ButtonMoreLess.php000064400000001431151160515070013046
0ustar00<?php


namespace Nextend\Framework\Form\Element\Button;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Button;

class ButtonMoreLess extends Button {

    public function __construct($insertAt, $name, $label = '',
$parameters = array()) {
        parent::__construct($insertAt, $name, $label,
n2_('More'), $parameters);
    }

    protected function fetchElement() {

        $options = array(
            'labelMore' => n2_('More'),
            'labelLess' => n2_('Less')
        );

        if (!empty($this->relatedFields)) {
            $options['relatedFields'] = $this->relatedFields;
        }

        Js::addInline('new _N2.FormElementButtonMoreLess("'
. $this->fieldID . '", ' . json_encode($options) .
');');

        return parent::fetchElement();
    }
}Element/Button/ButtonRecordViewer.php000064400000001450151160515070013716
0ustar00<?php


namespace Nextend\Framework\Form\Element\Button;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Button;

class ButtonRecordViewer extends Button {

    public function __construct($insertAt, $name = '',
$parameters = array()) {
        parent::__construct($insertAt, $name, '', n2_('View
records'), $parameters);


        $this->addClass('n2_field_button--blue');
    }

    protected function fetchElement() {

        $ajaxRecordUrl = $this->getForm()
                              ->createAjaxUrl(array(
                                  'generator/recordstable'
                              ));
        Js::addInline('new _N2.FieldRecordViewer(' .
json_encode($this->fieldID) . ',' .
json_encode($ajaxRecordUrl) . ');');


        return parent::fetchElement();
    }
}Element/Button.php000064400000002646151160515070010132 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\View\Html;

class Button extends AbstractField {

    protected $url = '';

    protected $target = '';

    protected $buttonLabel = '';

    protected $classes = array('n2_field_button');

    public function __construct($insertAt, $name = '', $label =
'', $buttonLabel = '', $parameters = array()) {
        $this->buttonLabel = $buttonLabel;
        parent::__construct($insertAt, $name, $label, '',
$parameters);
    }

    protected function fetchElement() {

        return Html::tag('a', $this->getAttributes(),
$this->buttonLabel);
    }

    /**
     * @param $className
     */
    public function addClass($className) {
        $this->classes[] = $className;
    }

    /**
     * @return array
     */
    protected function getAttributes() {
        $attributes = array(
            'id'    => $this->fieldID,
            'class' => implode(' ',
$this->classes)
        );

        if (!empty($this->url)) {
            $attributes['href'] = $this->url;
            if (!empty($this->target)) {
                $attributes['target'] = $this->target;
            }
        } else {
            $attributes['href'] = '#';
        }

        return $attributes;
    }

    public function setUrl($url) {
        $this->url = $url;
    }

    public function setTarget($target) {
        $this->target = $target;
    }
}Element/CheckboxOnOff.php000064400000003212151160515070011323
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class CheckboxOnOff extends AbstractFieldHidden {

    /**
     * @var string
     */
    protected $icon;

    protected $invert = false;

    protected $checkboxTip;

    public function __construct($insertAt, $name, $label, $icon, $default =
0, $parameters = array()) {

        $this->icon = $icon;

        parent::__construct($insertAt, $name, $label, $default,
$parameters);
    }

    protected function fetchElement() {

        $options = array(
            'invert'        => $this->invert,
            'relatedFields' => $this->relatedFields
        );

        Js::addInline('new _N2.FormElementCheckboxOnOff("' .
$this->fieldID . '", ' . json_encode($options) .
');');

        $attr = array(
            'class' => 'n2_field_checkbox_onoff' .
($this->isActive() ? ' n2_field_checkbox_onoff--active' :
'')
        );

        if (!empty($this->checkboxTip)) {
            $attr['data-n2tip'] = $this->checkboxTip;
        }

        return Html::tag('div', $attr, '<i
class="' . $this->icon . '"></i>' .
parent::fetchElement());
    }

    protected function isActive() {

        $value = $this->getValue();

        if (!$this->invert && $value) {
            return true;
        } else if ($this->invert && !$value) {
            return true;
        }

        return false;
    }

    /**
     * @param bool $invert
     */
    public function setInvert($invert) {
        $this->invert = $invert;
    }

    /**
     * @param string $tip
     */
    public function setCheckboxTip($tip) {
        $this->checkboxTip = $tip;
    }

}Element/Connected.php000064400000001052151160515070010547 0ustar00<?php

namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Form\AbstractField;

class Connected extends MixedField {

    protected $rowClass = 'n2_field_connected ';

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return $elementHtml[1];
    }

    protected function decorate($html) {

        return '<div
class="n2_field_connected__container" style="' .
$this->style . '">' . $html .
'</div>';
    }
}Element/Decoration.php000064400000003357151160515070010746
0ustar00<?php


namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Decoration extends AbstractFieldHidden {

    protected $value = null;

    protected $options = array(
        'italic'    => 'ssi_16 ssi_16--italic',
        'underline' => 'ssi_16 ssi_16--underline'
    );

    protected $style = '';

    protected function fetchElement() {

        $this->value = explode('||', $this->getValue());

        $html = Html::tag('div', array(
            'class' => 'n2_field_decoration',
            'style' => $this->style
        ), $this->renderOptions() . parent::fetchElement());

        Js::addInline('new _N2.FormElementDecoration("' .
$this->fieldID . '", ' .
json_encode(array_keys($this->options)) . ');');

        return $html;
    }

    /**
     *
     * @return string
     */
    protected function renderOptions() {

        $length = count($this->options) - 1;

        $html = '';
        $i    = 0;
        foreach ($this->options AS $value => $class) {

            $html .= Html::tag('div', array(
                'class'      =>
'n2_field_decoration__option ' . ($this->isSelected($value) ?
' n2_field_decoration__option--selected' : ''),
                'data-value' => $value
            ), Html::tag('i', array('class' =>
$class)));
            $i++;
        }

        return $html;
    }

    function isSelected($value) {
        if (in_array($value, $this->value)) {
            return true;
        }

        return false;
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {
        $this->options = $options;
    }

    /**
     * @param string $style
     */
    public function setStyle($style) {
        $this->style = $style;
    }
}Element/Devices.php000064400000003034151160515070010231 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Devices extends AbstractFieldHidden {

    private $values = array();

    protected function fetchElement() {

        $html = Html::tag('div', array(
            'id'    => $this->fieldID,
            'class' => 'n2_field_radio_icon'
        ), $this->generateOptions());

        Js::addInline('new _N2.FormElementDevices("' .
$this->fieldID . '", ' . json_encode($this->values) .
');');

        return $html;
    }

    function generateOptions() {
        $options = array(
            'desktop-landscape' => 'ssi_16
ssi_16--desktoplandscape',
            'desktop-portrait'  => 'ssi_16
ssi_16--desktopportrait',
            'tablet-landscape'  => 'ssi_16
ssi_16--tabletportraitlarge',
            'tablet-portrait'   => 'ssi_16
ssi_16--tabletportrait',
            'mobile-landscape'  => 'ssi_16
ssi_16--mobileportraitlarge',
            'mobile-portrait'   => 'ssi_16
ssi_16--mobileportrait'
        );

        $html = '';
        $i    = 0;
        foreach ($options as $value => $class) {
            $this->values[] = $value;

            $html .= Html::tag('div', array(
                'class' => 'n2_field_radio__option'
            ), Html::tag('i', array(
                    'class' => $class
                )) . Html::tag('input', array(
                    'type' => 'hidden',
                    'id'   => $this->fieldID .
'-' . $value
                )));
            $i++;
        }

        return $html;
    }
}Element/EmptyArea.php000064400000000457151160515070010544 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\View\Html;

class EmptyArea extends AbstractField {

    protected function fetchElement() {

        return Html::tag('div', array(
            'id' => $this->fieldID
        ));
    }
}Element/Font.php000064400000003017151160515070007556 0ustar00<?php

namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Font\FontManager;
use Nextend\Framework\Font\FontParser;
use Nextend\Framework\View\Html;

class Font extends AbstractFieldHidden {

    protected $mode = '';

    protected $css = '';

    protected $style2 = '';

    protected $preview = '';


    protected function addScript() {

        FontManager::enqueue($this->getForm());

        Js::addInline('new _N2.FormElementFont("' .
$this->fieldID . '", {
            mode: "' . $this->mode . '",
            label: "' . $this->label . '",
            style: "' . $this->style . '",
            style2: "' . $this->style2 . '",
            preview: ' . json_encode($this->preview) . '
        });');
    }

    protected function fetchElement() {

        $this->addScript();

        return Html::tag('div', array(
            'class' => 'n2_field_font'
        ), n2_('Font') . parent::fetchElement());
    }

    public function getValue() {

        return FontParser::parse(parent::getValue());
    }

    /**
     * @param string $mode
     */
    public function setMode($mode) {
        $this->mode = $mode;
    }

    /**
     * @param string $css
     */
    public function setCss($css) {
        $this->css = $css;
    }

    /**
     * @param string $style2
     */
    public function setStyle2($style2) {
        $this->style2 = $style2;
    }

    /**
     * @param string $preview
     */
    public function setPreview($preview) {
        $this->preview = $preview;
    }

}Element/Group/GroupCheckboxOnOff.php000064400000000550151160515070013436
0ustar00<?php


namespace Nextend\Framework\Form\Element\Group;


use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\View\Html;

class GroupCheckboxOnOff extends Grouping {

    protected function fetchElement() {
        return Html::tag('div', array(
            'class' =>
'n2_field_group_checkbox_onoff'
        ), parent::fetchElement());
    }

}Element/Grouping.php000064400000001555151160515070010447 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;

class Grouping extends AbstractField implements ContainerInterface {

    use TraitFieldset;

    protected $rowClass = 'n2_field__grouping';

    public function __construct($insertAt, $name = '', $label =
false, $parameters = array()) {
        parent::__construct($insertAt, $name, $label, '',
$parameters);
    }

    protected function fetchElement() {

        $html = '';

        $element = $this->first;
        while ($element) {
            $html .= $this->decorateElement($element);

            $element = $element->getNext();
        }

        return $html;
    }

    public function decorateElement($element) {

        return $this->parent->decorateElement($element);
    }
}Element/Hidden/HiddenFont.php000064400000001356151160515070012071
0ustar00<?php

namespace Nextend\Framework\Form\Element\Hidden;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Font\FontManager;
use Nextend\Framework\Form\Element\AbstractFieldHidden;

class HiddenFont extends AbstractFieldHidden {

    protected $rowClass = 'n2_form_element--hidden';

    protected $mode = '';

    protected function fetchElement() {

        FontManager::enqueue($this->getForm());

        Js::addInline('new _N2.FormElementFontHidden("' .
$this->fieldID . '", {
            mode: "' . $this->mode . '",
            label: "' . $this->label . '"
        });');

        return parent::fetchElement();
    }

    /**
     * @param string $mode
     */
    public function setMode($mode) {
        $this->mode = $mode;
    }
}Element/Hidden/HiddenOnOff.php000064400000000300151160515070012156
0ustar00<?php


namespace Nextend\Framework\Form\Element\Hidden;


use Nextend\Framework\Form\Element\OnOff;

class HiddenOnOff extends OnOff {

    protected $rowClass = 'n2_form_element--hidden';

}Element/Hidden/HiddenStyle.php000064400000001363151160515070012261
0ustar00<?php

namespace Nextend\Framework\Form\Element\Hidden;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\AbstractFieldHidden;
use Nextend\Framework\Style\StyleManager;

class HiddenStyle extends AbstractFieldHidden {

    protected $rowClass = 'n2_form_element--hidden';

    protected $mode = '';

    protected function fetchElement() {

        StyleManager::enqueue($this->getForm());

        Js::addInline('new _N2.FormElementStyleHidden("' .
$this->fieldID . '", {
            mode: "' . $this->mode . '",
            label: "' . $this->label . '"
        });');

        return parent::fetchElement();
    }

    /**
     * @param string $mode
     */
    public function setMode($mode) {
        $this->mode = $mode;
    }
}Element/Hidden.php000064400000000614151160515070010043 0ustar00<?php


namespace Nextend\Framework\Form\Element;


class Hidden extends AbstractFieldHidden {

    protected $hasTooltip = false;

    public function __construct($insertAt, $name = '', $default =
'', $parameters = array()) {
        parent::__construct($insertAt, $name, false, $default,
$parameters);
    }

    public function getRowClass() {
        return 'n2_form_element--hidden';
    }
}Element/Icon.php000064400000001030151160515070007531 0ustar00<?php
/**
 * @required N2SSPRO
 */

namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;

class Icon extends AbstractChooser {

    protected $hasClear = false;

    protected $class = ' n2_field_icon';

    protected function addScript() {

        \Nextend\Framework\Icon\Icon::serveAdmin();

        Js::addInline('
            new _N2.FormElementIcon2Manager("' .
$this->fieldID . '");
        ');
    }

    protected function field() {
        return '<div
class="n2_field_icon__preview"></div>';
    }
}Element/IconTab.php000064400000005146151160515070010174 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class IconTab extends AbstractFieldHidden {

    protected $options = array();
    protected $relatedValueFields = array();
    protected $relatedAttribute = '';
    protected $tooltips = array();

    protected function fetchElement() {

        $value = $this->getValue();
        if (!empty($value)) {
            $this->defaultValue = $value;
        } else if (empty($this->defaultValue)) {
            $this->defaultValue = array_keys($this->options)[0];
        }

        $html = Html::openTag("div", array(
            "id"    => $this->fieldID .
"_icon_tab",
            "class" => "n2_field_icon_tab",
            "style" => $this->style
        ));

        $html .= $this->renderOptions();

        $html .= Html::closeTag("div");

        $html .= parent::fetchElement();

        if (!empty($this->relatedAttribute)) {
            $options['relatedAttribute'] =
$this->relatedAttribute;
        }

        $options = array();

        if (!empty($this->relatedValueFields)) {
            $options['relatedValueFields'] =
$this->relatedValueFields;
        }

        Js::addInline('new _N2.FormElementIconTab("' .
$this->fieldID . '", ' . json_encode($options) .
');');

        return $html;
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {

        $this->options = $options;
    }

    /**
     * @param array $tooltips
     */
    public function setTooltips($tooltips) {

        $this->tooltips = $tooltips;
    }

    /**
     * @param $relatedValueFields
     */
    public function setRelatedValueFields($relatedValueFields) {
        $this->relatedValueFields = $relatedValueFields;
    }

    public function renderOptions() {
        $html = '';
        foreach ($this->options AS $option => $icon) {
            $class = 'n2_field_icon_tab__option';
            if ($option == $this->defaultValue) {
                $class .= ' n2_field_icon_tab__option--selected';
            }

            $element = array(
                "class"       => $class,
                "data-ssoption" => $option
            );

            if (isset($this->tooltips[$option])) {
                $element += array(
                    "data-n2tip" =>
$this->tooltips[$option]
                );

            }
            $html .= Html::openTag("div", $element);
            $html .= Html::openTag("i", array(
                "class" => $icon
            ));
            $html .= Html::closeTag("i");
            $html .= Html::closeTag("div");
        }

        return $html;
    }
}Element/LayerWindowFocus.php000064400000003143151160515070012114
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;

class LayerWindowFocus extends AbstractField {

    /**
     * @var AbstractField
     */
    protected $fieldImage;

    /**
     * @var AbstractField
     */
    protected $fieldFocusX;

    /**
     * @var AbstractField
     */
    protected $fieldFocusY;


    /**
     * LayerWindowFocus constructor.
     *
     * @param               $insertAt
     * @param               $name
     * @param               $label
     * @param array         $parameters
     */
    public function __construct($insertAt, $name, $label, $parameters =
array()) {

        parent::__construct($insertAt, $name, $label, '',
$parameters);
    }

    /**
     * @param AbstractField $fieldImage
     * @param AbstractField $fieldFocusX
     * @param AbstractField $fieldFocusY
     */
    public function setFields($fieldImage, $fieldFocusX, $fieldFocusY) {

        $this->fieldImage  = $fieldImage;
        $this->fieldFocusX = $fieldFocusX;
        $this->fieldFocusY = $fieldFocusY;
    }

    protected function fetchElement() {

        Js::addInline('new
_N2.FormElementLayerWindowFocus("' . $this->fieldID .
'", ' . json_encode(array(
                'image'  => $this->fieldImage->getID(),
                'focusX' => $this->fieldFocusX->getID(),
                'focusY' => $this->fieldFocusY->getID(),
            )) . ');');

        return '<div id="' . $this->fieldID .
'" class="n2_field_layer_window_focus"
style="width:314px;"><img
class="n2_field_layer_window_focus__image"
alt="Error"></div>';
    }

}Element/MarginPadding.php000064400000004141151160515070011353
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;

class MarginPadding extends AbstractFieldHidden implements
ContainerInterface {

    use TraitFieldset;

    private static $separator = '|*|';

    protected $unit = false;

    protected function fetchElement() {
        $default = explode(self::$separator, $this->defaultValue);
        $value   = explode(self::$separator, $this->getValue());
        $value   = $value + $default;

        $html = "<div class='n2_field_margin_padding'
style='" . $this->style . "'>";

        $html        .= '<div
class="n2_field_margin_padding__pre_label"><i
class="ssi_16 ssi_16--unlink"></i></div>';
        $subElements = array();
        $i           = 0;

        $element = $this->first;
        while ($element) {
            $element->setExposeName(false);
            if (isset($value[$i])) {
                $element->setDefaultValue($value[$i]);
            }

            $html            .= $this->decorateElement($element);
            $subElements[$i] = $element->getID();
            $i++;

            $element = $element->getNext();
        }

        if ($this->unit) {
            $html .= '<div
class="n2_field_unit"><div
class="n2_field_unit__current_unit">' . $this->unit .
'</div></div>';
        }

        $html .= parent::fetchElement();
        $html .= "</div>";

        Js::addInline('new _N2.FormElementMarginPadding("' .
$this->fieldID . '", ' . json_encode($subElements) .
', "' . self::$separator . '");');

        $this->renderRelatedFields();

        return $html;
    }

    /**
     * @param string $unit
     */
    public function setUnit($unit) {
        $this->unit = $unit;
    }

    public function getControlName() {
        return $this->name . $this->controlName;
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return $elementHtml[1];
    }
}Element/Message/Notice.php000064400000000526151160515070011457
0ustar00<?php


namespace Nextend\Framework\Form\Element\Message;


use Nextend\Framework\Form\Element\Message;

class Notice extends Message {

    public function __construct($insertAt, $name, $label, $description) {
        $this->classes[] = 'n2_field_message--notice';
        parent::__construct($insertAt, $name, $label, $description);
    }
}Element/Message/Warning.php000064400000001013151160515070011633
0ustar00<?php


namespace Nextend\Framework\Form\Element\Message;

use Nextend\Framework\Form\Element\Message;

class Warning extends Message {

    protected $description = '';

    public function __construct($insertAt, $name, $description) {
        $this->classes[] = 'n2_field_message--warning';
        parent::__construct($insertAt, $name, n2_('Warning'),
$description);
    }

    protected function fetchElement() {
        echo '<div class="' . implode(' ',
$this->classes) . '">' . $this->description .
'</div>';
    }
}Element/Message.php000064400000001053151160515070010232 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Form\AbstractField;

abstract class Message extends AbstractField {

    protected $description = '';

    protected $classes = array('n2_field_message');

    public function __construct($insertAt, $name, $label, $description) {
        $this->description = $description;
        parent::__construct($insertAt, $name, $label);
    }

    protected function fetchElement() {
        echo '<div class="' . implode(' ',
$this->classes) . '">' . $this->description .
'</div>';
    }
}Element/MixedField/Border.php000064400000004252151160515070012101
0ustar00<?php


namespace Nextend\Framework\Form\Element\MixedField;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\View\Html;

class Border extends MixedField {

    protected $rowClass = 'n2_field_mixed_border ';

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        new NumberAutoComplete($this, $this->name . '-1',
false, '', array(
            'values'        => array(
                0,
                1,
                3,
                5
            ),
            'min'           => 0,
            'wide'          => 3,
            'unit'          => 'px',
            'relatedFields' => array(
                $this->generateId($this->getControlName() .
$this->name . '-2'),
                $this->generateId($this->getControlName() .
$this->name . '-3')
            )
        ));

        new Select($this, $this->name . '-2', false,
'', array(
            'options' => array(
                'none'   => n2_('None'),
                'dotted' => n2_('Dotted'),
                'dashed' => n2_('Dashed'),
                'solid'  => n2_('Solid'),
                'double' => n2_('Double'),
                'groove' => n2_('Groove'),
                'ridge'  => n2_('Ridge'),
                'inset'  => n2_('Inset'),
                'outset' => n2_('Outset')
            )
        ));

        new Color($this, $this->name . '-3', false,
'', array(
            'alpha' => true
        ));
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return Html::tag('div', array(
            'data-field' => $element->getID()
        ), $elementHtml[1]);
    }

    protected function decorate($html) {

        return '<div
class="n2_field_mixed_border__container" style="' .
$this->style . '">' . $html .
'</div>';
    }
}Element/MixedField/BoxShadow.php000064400000002266151160515070012565
0ustar00<?php


namespace Nextend\Framework\Form\Element\MixedField;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;

class BoxShadow extends MixedField {

    protected $rowClass = 'n2_field_mixed_box_shadow ';

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($this, $this->name . '-' .
$i, false, 0, array(
                'wide' => 3
            ));
        }
        new Color($this, $this->name . '-5', false,
'', array(
            'alpha' => true
        ));
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return $elementHtml[1];
    }

    protected function decorate($html) {

        return '<div
class="n2_field_mixed_box_shadow__container" style="' .
$this->style . '">' . $html .
'</div>';
    }
}Element/MixedField/FontSize.php000064400000003062151160515070012423
0ustar00<?php


namespace Nextend\Framework\Form\Element\MixedField;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Unit;

class FontSize extends MixedField {

    protected $rowClass = 'n2_field_mixed_font_size ';

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        new NumberSlider($this, $this->name . '-1', false,
'', array(
            'min'       => 1,
            'max'       => 10000,
            'sliderMax' => 100,
            'units'     => array(
                'pxMin'       => 1,
                'pxMax'       => 10000,
                'pxSliderMax' => 100,
                '%Min'        => 1,
                '%Max'        => 10000,
                '%SliderMax'  => 600
            ),
            'style'     => 'width: 22px;'
        ));
        new Unit($this, $this->name . '-2', false,
'', array(
            'units' => array(
                'px' => 'px',
                '%'  => '%'
            )
        ));
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return $elementHtml[1];
    }

    protected function decorate($html) {

        return '<div
class="n2_field_mixed_font_size__container" style="' .
$this->style . '">' . $html .
'</div>';
    }
}Element/MixedField/GeneratorOrder.php000064400000002117151160515070013604
0ustar00<?php


namespace Nextend\Framework\Form\Element\MixedField;


use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Radio;
use Nextend\Framework\Form\Element\Select;

class GeneratorOrder extends MixedField {

    protected $rowClass = 'n2_field_mixed_generator_order ';

    protected $options = array();

    public function __construct($insertAt, $name = '', $default =
'', $parameters = array()) {
        parent::__construct($insertAt, $name, false, $default,
$parameters);

        new Select($this, $name . '-1', n2_('Field'),
'', $this->options);

        new Radio($this, $name . '-2', n2_('Order'),
'', array(
            'options' => array(
                'asc'  => n2_('Ascending'),
                'desc' => n2_('Descending')
            )
        ));
    }

    protected function decorate($html) {

        return '<div
class="n2_field_mixed_generator_order__container"
style="' . $this->style . '">' . $html .
'</div>';
    }

    protected function setOptions($options) {
        $this->options = array(
            'options' => $options
        );
    }
}Element/MixedField/TextShadow.php000064400000002271151160515070012755
0ustar00<?php


namespace Nextend\Framework\Form\Element\MixedField;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;

class TextShadow extends MixedField {

    protected $rowClass = 'n2_field_mixed_text_shadow ';

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        for ($i = 1; $i < 4; $i++) {
            new NumberAutoComplete($this, $this->name . '-' .
$i, false, 0, array(
                'wide' => 3
            ));
        }
        new Color($this, $this->name . '-4', false,
'', array(
            'alpha' => true
        ));
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        $elementHtml = $element->render();

        return $elementHtml[1];
    }

    protected function decorate($html) {

        return '<div
class="n2_field_mixed_text_shadow__container" style="'
. $this->style . '">' . $html .
'</div>';
    }
}Element/MixedField.php000064400000003572151160515070010670
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;

class MixedField extends AbstractFieldHidden implements ContainerInterface
{

    use TraitFieldset;

    private $separator = '|*|';

    protected $style = '';

    protected $rowClass = 'n2_field_mixed ';

    protected function fetchElement() {

        $default = explode($this->separator, $this->defaultValue);
        $value   = explode($this->separator, $this->getValue());
        $value   = $value + $default;

        $html        = '';
        $subElements = array();
        $i           = 0;


        $element = $this->first;
        while ($element) {
            $element->setExposeName(false);
            if (isset($value[$i])) {
                $element->setDefaultValue($value[$i]);
            }

            $html .= $this->decorateElement($element);

            $subElements[$i] = $element->getID();
            $i++;

            $element = $element->getNext();
        }

        $html .= parent::fetchElement();

        Js::addInline('new _N2.FormElementMixed("' .
$this->fieldID . '", ' . json_encode($subElements) .
', "' . $this->separator . '");');

        return $this->decorate($html);
    }

    /**
     * @param string $style
     */
    public function setStyle($style) {
        $this->style = $style;
    }

    public function getControlName() {
        return $this->name . $this->controlName;
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        return $this->parent->decorateElement($element);
    }

    protected function decorate($html) {

        return '<div class="n2_field_mixed__container"
style="' . $this->style . '">' . $html .
'</div>';
    }
}Element/OnOff.php000064400000005235151160515070007663 0ustar00<?php

namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;

class OnOff extends AbstractFieldHidden {

    protected $relatedFieldsOn = array();

    protected $relatedAttribute = '';

    protected $values = array(
        0 => 0,
        1 => 1
    );

    protected $customValues = false;

    protected function fetchElement() {

        $html = '<div class="n2_field_onoff' .
$this->isOn() . '" role="switch"
aria-checked="false" tabindex="0"
aria-label="' . $this->label . '">' .
parent::fetchElement() . '<div
class="n2_field_onoff__slider"><div
class="n2_field_onoff__slider_bullet"></div></div><div
class="n2_field_onoff__labels"><div
class="n2_field_onoff__label n2_field_onoff__label_off">'
. n2_('Off') . '</div><div
class="n2_field_onoff__label n2_field_onoff__label_on">'
. n2_('On') . '</div></div></div>';

        $options = array();

        if ($this->customValues) {
            $options['values'] = $this->customValues;
        }
        if (!empty($this->relatedFieldsOff)) {
            $options['relatedFieldsOff'] =
$this->relatedFieldsOff;
        }
        if (!empty($this->relatedFieldsOn)) {
            $options['relatedFieldsOn'] =
$this->relatedFieldsOn;
        }
        if (!empty($this->relatedAttribute)) {
            $options['relatedAttribute'] =
$this->relatedAttribute;
        }

        Js::addInline('new _N2.FormElementOnoff("' .
$this->fieldID . '", ' . json_encode($options) .
');');

        return $html;
    }

    private function isOn() {
        $value = $this->getValue();
        if (($this->customValues &&
$this->customValues[$value]) || (!$this->customValues &&
$value)) {
            return ' n2_field_onoff--on';
        }

        return '';
    }

    /**
     * @param array $relatedFields
     */
    public function setRelatedFieldsOn($relatedFields) {
        $this->relatedFieldsOn = $relatedFields;
    }

    /**
     * @param array $relatedFields
     */
    public function setRelatedFieldsOff($relatedFields) {
        $this->relatedFieldsOff = $relatedFields;
    }

    public function setRelatedAttribute($relatedAttribute) {
        $this->relatedAttribute = $relatedAttribute;
    }

    public function setCustomValues($offValue = 0, $onValue = 1) {

        if ($offValue === 0 && $onValue === 1) {
            $this->customValues = false;
        } else {
            $this->customValues            = array();
            $this->customValues[$offValue] = 0;
            $this->customValues[$onValue]  = 1;
        }
    }

    public function setInvert($isInvert) {
        if ($isInvert) {
            $this->setCustomValues(1, 0);
        } else {
            $this->setCustomValues(0, 1);
        }
    }
}Element/Radio/AbstractRadioIcon.php000064400000001216151160515070013240
0ustar00<?php


namespace Nextend\Framework\Form\Element\Radio;


use Nextend\Framework\Form\Element\Radio;
use Nextend\Framework\View\Html;

abstract class AbstractRadioIcon extends Radio {

    protected $class = 'n2_field_radio_icon';

    protected function renderOptions() {

        $html = '';
        $i    = 0;
        foreach ($this->options AS $value => $class) {

            $html .= Html::tag('div', array(
                'class' => 'n2_field_radio__option'
. ($this->isSelected($value) ? '
n2_field_radio__option--selected' : '')
            ), Html::tag('i', array('class' =>
$class)));
            $i++;
        }

        return $html;
    }
}Element/Radio/ImageList.php000064400000004312151160515070011563
0ustar00<?php


namespace Nextend\Framework\Form\Element\Radio;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\AbstractFieldHidden;
use Nextend\Framework\Localization\Localization;
use Nextend\Framework\Url\Url;
use Nextend\Framework\View\Html;

abstract class ImageList extends AbstractFieldHidden {

    protected $hasDisabled = true;

    protected $width = 44;

    protected $column = 5;

    protected $options = array();

    protected function fetchElement() {

        $jsParameters = array(
            'width' => $this->width
        );

        if ($this->hasDisabled) {
            $jsParameters['hasDisabled'] = true;
        }

        $html = Html::openTag("div", array(
            'class' => 'n2_field_image_list',
            'style' => $this->style
        ));

        $html .= parent::fetchElement();
        $html .= '<div
class="n2_field_image_list__preview">';

        $html .= '</div>';
        $html .= '<i class="n2_field_image_list__arrow ssi_16
ssi_16--selectarrow"></i>';

        $html .= $this->postHTML();

        $html .= Html::closeTag('div');

        $frontendOptions = array();
        foreach ($this->options as $key => $option) {
            $frontendOptions[$key] = array(
                'url' =>
Url::pathToUri($option['path'])
            );

            if (!empty($option['label'])) {
                $frontendOptions[$key]['label'] =
$option['label'];
            }
        }

        $jsParameters['column']  = min($this->column,
count($this->options) + ($this->hasDisabled ? 1 : 0));
        $jsParameters['options'] = $frontendOptions;

        Js::addInline('new _N2.FormElementImageList("' .
$this->fieldID . '", ' . json_encode($jsParameters) .
', ' . json_encode($this->relatedFields) . ');');

        return $html;
    }

    /**
     * @param bool $hasDisabled
     */
    public function setHasDisabled($hasDisabled) {
        $this->hasDisabled = $hasDisabled;
    }

    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }

    /**
     * @param int $column
     */
    public function setColumn($column) {
        $this->column = $column;
    }

    protected function postHTML() {
        return '';
    }
}Element/Radio/ImageListFromFolder.php000064400000005553151160515070013553
0ustar00<?php

namespace Nextend\Framework\Form\Element\Radio;

use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;

class ImageListFromFolder extends ImageList implements ContainerInterface {

    use TraitFieldset;

    protected $folder = '';

    protected $filenameOnly = false;

    protected function fetchElement() {

        $this->initOptions();

        return parent::fetchElement();
    }

    private function initOptions() {

        $value        = $this->getValue();
        $currentValue = basename($value);
        if ($value !== $currentValue) {
            $this->setValue($currentValue);
        }


        $files = Filesystem::files($this->folder);
        for ($i = 0; $i < count($files); $i++) {
            $ext        = pathinfo($files[$i], PATHINFO_EXTENSION);
            $extensions = array(
                'jpg',
                'jpeg',
                'png',
                'svg',
                'gif',
                'webp'
            );
            if (in_array($ext, $extensions)) {

                $path = $this->folder . $files[$i];

                if ($this->filenameOnly) {
                    $value = pathinfo($files[$i], PATHINFO_FILENAME);
                } else {
                    $value = basename($files[$i]);
                }

                $this->options[$value] = array(
                    'path' => $path
                );
            }
        }

        if (!isset($this->options[$currentValue])) {
            foreach ($this->options AS $value => $option) {
                if (pathinfo($value, PATHINFO_FILENAME) == $currentValue) {
                    $currentValue = $value;
                    $this->setValue($currentValue);
                }
            }
        }
    }

    protected function postHTML() {
        if ($this->first) {
            $html = '<div
class="n2_field_image_list__fields">';

            $element = $this->first;
            while ($element) {
                $html .= $this->decorateElement($element);

                $element = $element->getNext();
            }

            $html .= '</div>';

            return $html;
        }

        return '';
    }

    public function setFolder($folder) {
        $this->folder = $folder;
    }

    public function setFilenameOnly($value) {
        $this->filenameOnly = $value;
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {
        $html = '<div class="n2_field">';
        $html .= '<div class="n2_field__label">';
        $html .= $element->fetchTooltip();
        $html .= '</div>';
        $html .= '<div
class="n2_field__element">';
        $html .= $element->fetchElement();
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }
}Element/Radio/TextAlign.php000064400000001215151160515070011603
0ustar00<?php

namespace Nextend\Framework\Form\Element\Radio;

class TextAlign extends AbstractRadioIcon {

    protected $options = array(
        'inherit' => 'ssi_16 ssi_16--none',
        'left'    => 'ssi_16 ssi_16--textleft',
        'center'  => 'ssi_16 ssi_16--textcenter',
        'right'   => 'ssi_16 ssi_16--textright',
        'justify' => 'ssi_16 ssi_16--textjustify'
    );

    /**
     * @param $excluded array
     */
    public function setExcludeOptions($excluded) {
        foreach ($excluded AS $exclude) {
            if (isset($this->options[$exclude])) {
                unset($this->options[$exclude]);
            }

        }
    }
}Element/Radio.php000064400000003416151160515070007711 0ustar00<?php


namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Radio extends AbstractFieldHidden {

    protected $options = array();

    protected $class = 'n2_field_radio';

    protected $style = '';

    protected $value;

    protected function addScript() {
        Js::addInline('new _N2.FormElementRadio("' .
$this->fieldID . '", ' .
json_encode(array_keys($this->options)) . ', ' .
json_encode($this->relatedFields) . ');');
    }

    protected function fetchElement() {

        $this->value = $this->getValue();

        $html = Html::tag('div', array(
            'class' => $this->class,
            'style' => $this->style
        ), $this->renderOptions() . parent::fetchElement());

        $this->addScript();

        return $html;
    }

    /**
     * @return string
     */
    protected function renderOptions() {

        $html = '';
        $i    = 0;
        foreach ($this->options AS $value => $label) {
            $html .= Html::tag('div', array(
                'class' => 'n2_field_radio__option'
. ($this->isSelected($value) ? '
n2_field_radio__option--selected' : '')
            ), Html::tag('div', array(
                    'class' =>
'n2_field_radio__option_marker'
                ), '<i class="ssi_16
ssi_16--check"></i>') . '<div
class="n2_field_radio__option_label">' . $label .
'</div>');
            $i++;
        }

        return $html;
    }

    function isSelected($value) {
        if ((string)$value == $this->value) {
            return true;
        }

        return false;
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {
        $this->options = $options;
    }

    public function setStyle($style) {
        $this->style = $style;
    }
}Element/RichTextarea.php000064400000003324151160515070011234
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\View\Html;

class RichTextarea extends AbstractField {

    protected $fieldStyle = '';

    protected function fetchElement() {

        Js::addInline('new _N2.FormElementRichText("' .
$this->fieldID . '");');

        $tools = array(
            Html::tag('div', array(
                'class'       =>
'n2_field_textarea_rich__button',
                'data-action' => 'bold'
            ), Html::tag('I', array('class' =>
'ssi_16 ssi_16--bold'))),
            Html::tag('div', array(
                'class'       =>
'n2_field_textarea_rich__button',
                'data-action' => 'italic'
            ), Html::tag('I', array('class' =>
'ssi_16 ssi_16--italic'))),
            Html::tag('div', array(
                'class'       =>
'n2_field_textarea_rich__button',
                'data-action' => 'link'
            ), Html::tag('I', array('class' =>
'ssi_16 ssi_16--link')))
        );

        $buttons = Html::tag('div', array(
            'class' =>
'n2_field_textarea_rich__buttons'
        ), implode('', $tools));

        return Html::tag('div', array(
            'class' => 'n2_field_textarea_rich',
            'style' => $this->style
        ), $buttons . Html::tag('textarea', array(
                'id'           => $this->fieldID,
                'name'         => $this->getFieldName(),
                'autocomplete' => 'off',
                'style'        => $this->fieldStyle
            ), $this->getValue()));
    }

    /**
     * @param string $fieldStyle
     */
    public function setFieldStyle($fieldStyle) {
        $this->fieldStyle = $fieldStyle;
    }
}Element/Select/Easing.php000064400000002755151160515070011305
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;

class Easing extends Select {

    protected $options = array(
        "linear"           => "Linear",
        "easeInQuad"       => "Quad In",
        "easeOutQuad"      => "Quad Out",
        "easeInOutQuad"    => "Quad In Out",
        "easeInCubic"      => "Cubic In",
        "easeOutCubic"     => "Cubic Out",
        "easeInOutCubic"   => "Cubic In Out",
        "easeInQuart"      => "Quart In",
        "easeOutQuart"     => "Quart Out",
        "easeInOutQuart"   => "Quart In Out",
        "easeInQuint"      => "Quint In",
        "easeOutQuint"     => "Quint Out",
        "easeInOutQuint"   => "Quint In Out",
        "easeInSine"       => "Sine In",
        "easeOutSine"      => "Sine Out",
        "easeInOutSine"    => "Sine In Out",
        "easeInExpo"       => "Expo In",
        "easeOutExpo"      => "Expo Out",
        "easeInOutExpo"    => "Expo In Out",
        "easeInCirc"       => "Circ In",
        "easeOutCirc"      => "Circ Out",
        "easeInOutCirc"    => "Circ In Out",
        "easeInElastic"    => "Elastic In",
        "easeOutElastic"   => "Elastic Out",
        "easeInOutElastic" => "Elastic In Out",
        "easeInBack"       => "Back In",
        "easeOutBack"      => "Back Out",
        "easeInOutBack"    => "Back In Out",
        "easeInBounce"     => "Bounce In",
        "easeOutBounce"    => "Bounce Out",
        "easeInOutBounce"  => "Bounce In Out"
    );
}Element/Select/FillMode.php000064400000001456151160515070011567
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;

use Nextend\Framework\Form\Element\Select;

class FillMode extends Select {

    protected $useGlobal = false;

    protected function fetchElement() {

        $this->options = array(
            'fill'    => n2_('Fill'),
            'blurfit' => n2_('Blur fit'),
            'fit'     => n2_('Fit'),
            'stretch' => n2_('Stretch'),
            'center'  => n2_('Center')
        );

        if ($this->useGlobal) {
            $this->options = array_merge(array(
                'default' => n2_('Slider\'s
default')
            ), $this->options);
        }

        return parent::fetchElement();
    }

    /**
     * @param bool $useGlobal
     */
    public function setUseGlobal($useGlobal) {
        $this->useGlobal = $useGlobal;
    }
}Element/Select/Filter.php000064400000001032151160515070011307
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;

class Filter extends Select {

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        $no_label = strtolower($this->label);

        $this->options = array(
            '0'  => n2_('All'),
            '1'  => $this->label,
            '-1' => sprintf(n2_('Not %s'),
$no_label)
        );
    }
}Element/Select/FontWeight.php000064400000001465151160515070012152
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;

class FontWeight extends Select {

    public function __construct($insertAt, $name = '', $label =
false, $default = '', $parameters = array()) {
        $this->options = array(
            '0'   => n2_('Normal'),
            '1'   => n2_('Bold'),
            '100' => '100',
            '200' => '200 - ' . n2_('Extra
light'),
            '300' => '300 - ' .
n2_('Light'),
            '400' => '400 - ' .
n2_('Normal'),
            '500' => '500',
            '600' => '600 - ' . n2_('Semi
bold'),
            '700' => '700 - ' .
n2_('Bold'),
            '800' => '800 - ' . n2_('Extra
bold'),
            '900' => '900'
        );
        parent::__construct($insertAt, $name, $label, $default,
$parameters);
    }
}Element/Select/Gradient.php000064400000001066151160515070011626
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;

class Gradient extends Select {

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        $this->options = array(
            'off'        => n2_('Off'),
            'vertical'   => '&darr;',
            'horizontal' => '&rarr;',
            'diagonal1'  => '&#8599;',
            'diagonal2'  => '&#8600;'
        );
    }
}Element/Select/LinkTarget.php000064400000001031151160515070012125
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;

class LinkTarget extends Select {

    public function __construct($insertAt, $name = '', $label =
'', $default = '_self', array $parameters = array()) {
        $this->options = array(
            '_self'   => n2_('Self'),
            '_blank'  => n2_('New'),
            '_parent' => n2_('Parent'),
            '_top'    => n2_('Top')
        );

        parent::__construct($insertAt, $name, $label, $default,
$parameters);
    }
}Element/Select/SelectFile.php000064400000002075151160515070012111
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Platform\Platform;

class SelectFile extends Select {

    /**
     * File constructor.
     *
     * @param        $insertAt
     * @param string $name
     * @param string $label
     * @param string $default
     * @param string $extension
     * @param array  $parameters
     *
     */
    public function __construct($insertAt, $name = '', $label =
'', $default = '', $extension = '',
$parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        $dir             = Platform::getPublicDirectory();
        $files           = scandir($dir);
        $validated_files = array();

        foreach ($files as $file) {
            if (strtolower(pathinfo($file, PATHINFO_EXTENSION)) ==
$extension) {
                $validated_files[] = $file;
            }
        }

        $this->options[''] = n2_('Choose');

        foreach ($validated_files AS $f) {
            $this->options[$f] = $f;
        }
    }
}Element/Select/Skin.php000064400000002111151160515070010765
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Localization\Localization;

class Skin extends Select {

    protected $fixed = false;

    protected function fetchElement() {

        $html = parent::fetchElement();

        Js::addInline('new _N2.FormElementSkin("' .
$this->fieldID . '", "' .
str_replace($this->name, '', $this->fieldID) .
'", ' . json_encode($this->options) . ', ' .
json_encode($this->fixed) . ');');

        return $html;
    }

    protected function renderOptions($options) {
        $html = '';
        if (!$this->fixed) {
            $html .= '<option value="0"
selected="selected">' . n2_('Choose') .
'</option>';
        }
        foreach ($options as $value => $option) {
            $html .= '<option ' . $this->isSelected($value)
. ' value="' . $value . '">' .
$option['label'] . '</option>';
        }

        return $html;
    }

    /**
     * @param bool $fixed
     */
    public function setFixed($fixed) {
        $this->fixed = $fixed;
    }
}Element/Select/SubFormIcon.php000064400000006011151160515070012252
0ustar00<?php


namespace Nextend\Framework\Form\Element\Select;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Container\ContainerSubform;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\Element\AbstractFieldHidden;
use Nextend\Framework\Form\TraitFieldset;
use Nextend\Framework\View\Html;

abstract class SubFormIcon extends AbstractFieldHidden {

    protected $ajaxUrl = '';

    /**
     * @var ContainerSubform
     */
    protected $containerSubform;

    protected $plugins = array();

    protected $options = array();

    /**
     * SubFormIcon constructor.
     *
     * @param TraitFieldset      $insertAt
     * @param string             $name
     * @param ContainerInterface $container
     * @param string             $ajaxUrl
     * @param string             $default
     * @param array              $parameters
     */
    public function __construct($insertAt, $name, $container, $ajaxUrl,
$default = '', $parameters = array()) {

        $this->ajaxUrl = $ajaxUrl;

        parent::__construct($insertAt, $name, '', $default,
$parameters);

        $this->loadOptions();

        $this->containerSubform = new ContainerSubform($container, $name
. '-subform');

        $this->getCurrentPlugin($this->getValue())
             ->renderFields($this->containerSubform);
    }

    protected function fetchElement() {

        $currentValue = $this->getValue();

        Js::addInline('
            new _N2.FormElementSubformIcon(
               "' . $this->fieldID . '",
              "' . $this->ajaxUrl . '",
               "' . $this->containerSubform->getId() .
'",
               "' . $currentValue . '"
            );
        ');
        $html = Html::openTag('div', array(
            'class' => 'n2_field_subform_icon'
        ));
        foreach ($this->options AS $value => $option) {
            $html .= Html::tag('div', array(
                'class'      =>
'n2_field_subform_icon__option' . ($value == $currentValue ?
' n2_field_subform_icon__option--selected' : ''),
                'data-value' => $value
            ), Html::tag('div', array(
                    'class' =>
'n2_field_subform_icon__option_icon'
                ), '<i class="' .
$option['icon'] . '"></i>') .
Html::tag('div', array(
                    'class' =>
'n2_field_subform_icon__option_label'
                ), $option['label']));
        }

        $html .= parent::fetchElement() . '</div>';

        return $html;
    }

    protected abstract function loadOptions();


    protected function getCurrentPlugin($value) {

        if (!isset($this->plugins[$value])) {
            list($value) = array_keys($this->plugins);
            $this->setValue($value);
        }

        return $this->plugins[$value];
    }

    /**
     * @param string $option
     */
    public function removeOption($option) {
        if (isset($this->options[$option])) {
            unset($this->options[$option]);

            if ($this->getValue() === $option) {
                $this->setValue($this->defaultValue);
            }
        }
    }
}Element/Select.php000064400000011030151160515070010061 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Select extends AbstractFieldHidden {

    public $value;

    protected $values = array();
    protected $options = array();
    protected $optgroup = array();
    protected $isMultiple = false;
    protected $size = '';

    protected $relatedValueFields = array();
    protected $relatedAttribute = '';

    protected function fetchElement() {

        $this->values = explode('||', $this->getValue());
        if (!is_array($this->values)) {
            $this->values = array();
        }

        $html = Html::openTag("div", array(
            "class" => "n2_field_select",
            "style" => $this->style
        ));

        $selectAttributes = array(
            'id'              => $this->fieldID .
'_select',
            'name'            => 'select' .
$this->getFieldName(),
            'aria-labelledby' => $this->fieldID,
            'autocomplete'    => 'off'
        );

        if (!empty($this->size)) {
            $selectAttributes['size'] = $this->size;
        }

        if ($this->isMultiple) {
            $selectAttributes['multiple'] = 'multiple';
            $selectAttributes['class']    =
'nextend-element-hastip';
            $selectAttributes['title']    = n2_('Hold down
the ctrl (Windows) or command (MAC) button to select multiple
options.');
        }

        $html .= Html::tag('select', $selectAttributes,
$this->renderOptions($this->options) . (!empty($this->optgroup) ?
$this->renderOptgroup() : ''));

        $html .= Html::closeTag("div");

        $html .= parent::fetchElement();

        $options = array();

        if (!empty($this->relatedFields)) {
            $options['relatedFields'] = $this->relatedFields;
        }

        if (!empty($this->relatedValueFields)) {
            $options['relatedValueFields'] =
$this->relatedValueFields;
        }

        if (!empty($this->relatedAttribute)) {
            $options['relatedAttribute'] =
$this->relatedAttribute;
        }

        Js::addInline('new _N2.FormElementList("' .
$this->fieldID . '", ' . json_encode($options) .
');');

        return $html;
    }

    /**
     *
     * @return string
     */
    protected function renderOptgroup() {
        $html = '';
        foreach ($this->optgroup as $label => $options) {
            if (is_array($options)) {
                $html .= "<optgroup label='" . $label .
"'>";
                $html .= $this->renderOptions($options);
                $html .= "</optgroup>";
            } else {
                $html .= $this->renderOption($label, $options);
            }
        }

        return $html;
    }

    /**
     * @param array $options
     *
     * @return string
     */
    protected function renderOptions($options) {
        $html = '';
        foreach ($options as $value => $label) {
            $html .= $this->renderOption($value, $label);
        }

        return $html;
    }

    protected function renderOption($value, $label) {

        return '<option value="' . $value . '"
' . $this->isSelected($value) . '>' . $label .
'</option>';
    }

    protected function isSelected($value) {
        if (in_array($value, $this->values)) {
            return ' selected="selected"';
        }

        return '';
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {

        $this->options = $options;
    }

    /**
     * @param array $optgroup
     */
    public function setOptgroup($optgroup) {
        $this->optgroup = $optgroup;
    }

    /**
     * @param bool $isMultiple
     */
    public function setIsMultiple($isMultiple) {
        $this->isMultiple = $isMultiple;
        $this->size       = 10;
    }

    /**
     * @param string $size
     */
    public function setSize($size) {
        $this->size = $size;
    }

    protected function createTree(&$list, &$new, $parent, $cindent
= '', $indent = '- ') {

        if (isset($new[$parent])) {
            for ($i = 0; $i < count($new[$parent]); $i++) {
                $new[$parent][$i]->treename = $cindent .
$new[$parent][$i]->name;
                $list[]                     = $new[$parent][$i];
                $this->createTree($list, $new,
$new[$parent][$i]->cat_ID, $cindent . $indent, $indent);
            }
        }

        return $list;
    }

    public function setRelatedValueFields($relatedValueFields) {
        $this->relatedValueFields = $relatedValueFields;
    }

    public function setRelatedAttribute($relatedAttribute) {
        $this->relatedAttribute = $relatedAttribute;
    }
}Element/SelectIcon.php000064400000003266151160515070010706
0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class SelectIcon extends AbstractFieldHidden {

    protected $options;

    public function __construct($insertAt, $name = '', $label =
false, $options = array(), $default = '', $parameters = array())
{

        $this->options = $options;

        parent::__construct($insertAt, $name, $label, $default,
$parameters);
    }


    protected function fetchElement() {

        $currentValue = $this->getValue();

        $html = Html::openTag('div', array(
            'class' => 'n2_field_select_icon'
        ));

        foreach ($this->options AS $value => $option) {

            $classes = array('n2_field_select_icon__option');
            if ($currentValue == $value) {
                $classes[] =
'n2_field_select_icon__option--selected';
            }

            $html .= Html::tag('div', array(
                'class'      => implode(' ',
$classes),
                'data-value' => $value
            ), Html::tag('div', array(
                    'class' =>
'n2_field_select_icon__option_icon'
                ), '<i class="' .
$option['icon'] . '"></i>') .
Html::tag('div', array(
                    'class' =>
'n2_field_select_icon__option_label'
                ), $option['label']) . Html::tag('div',
array(
                    'class' =>
'n2_field_select_icon__selected_marker'
                ), '<i class="ssi_16
ssi_16--check"></i>'));
        }

        $html .= Html::closeTag('div');

        $html .= parent::fetchElement();

        Js::addInline('new _N2.FormElementSelectIcon("' .
$this->fieldID . '", ' . json_encode(array()) .
');');

        return $html;
    }
}Element/Style.php000064400000004256151160515070007756 0ustar00<?php

namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Style\StyleManager;
use Nextend\Framework\Style\StyleParser;
use Nextend\Framework\View\Html;

class Style extends AbstractFieldHidden {

    protected $mode = '';

    protected $font = '';

    protected $font2 = '';

    protected $style2 = '';

    protected $preview = '';

    protected $css = '';

    protected function addScript() {

        StyleManager::enqueue($this->getForm());

        $preview =
preg_replace_callback('/url\(\'(.*?)\'\)/', array(
            $this,
            'fixPreviewImages'
        ), $this->preview);

        Js::addInline('new _N2.FormElementStyle("' .
$this->fieldID . '", {
            mode: "' . $this->mode . '",
            label: "' . $this->label . '",
            font: "' . $this->font . '",
            font2: "' . $this->font2 . '",
            style2: "' . $this->style2 . '",
            preview: ' . json_encode($preview) . '
        });');
    }

    protected function fetchElement() {

        $this->addScript();

        return Html::tag('div', array(
            'class' => 'n2_field_style'
        ), n2_('Style') . parent::fetchElement());
    }

    public function fixPreviewImages($matches) {
        return "url(" . ResourceTranslator::toUrl($matches[1]) .
")";
    }

    public function getValue() {

        return StyleParser::parse(parent::getValue());
    }

    /**
     * @param string $mode
     */
    public function setMode($mode) {
        $this->mode = $mode;
    }

    /**
     * @param string $font
     */
    public function setFont($font) {
        $this->font = $font;
    }

    /**
     * @param string $font2
     */
    public function setFont2($font2) {
        $this->font2 = $font2;
    }

    /**
     * @param string $style2
     */
    public function setStyle2($style2) {
        $this->style2 = $style2;
    }

    /**
     * @param string $preview
     */
    public function setPreview($preview) {
        $this->preview = $preview;
    }

    /**
     * @param string $css
     */
    public function setCss($css) {
        $this->css = $css;
    }
}Element/Tab.php000064400000003316151160515070007360 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Tab extends AbstractFieldHidden {

    protected $options = array();
    protected $relatedValueFields = array();

    protected function fetchElement() {

        if (empty($this->defaultValue) &&
!empty($this->options)) {
            $this->defaultValue = array_keys($this->options)[0];
        }

        $html = Html::openTag("div", array(
            "id"    => $this->fieldID . "_tab",
            "class" => "n2_field_tab",
            "style" => $this->style
        ));

        $html .= $this->renderOptions();

        $html .= Html::closeTag("div");

        $html .= parent::fetchElement();

        Js::addInline('new _N2.FormElementTab("' .
$this->fieldID . '", ' .
json_encode($this->relatedValueFields) . ');');

        return $html;
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {

        $this->options = $options;
    }

    /**
     * @param $relatedValueFields
     */
    public function setRelatedValueFields($relatedValueFields) {
        $this->relatedValueFields = $relatedValueFields;
    }

    public function renderOptions() {
        $html = '';
        foreach ($this->options AS $option => $label) {
            $class = 'n2_field_tab__option';
            if ($option == $this->defaultValue) {
                $class .= ' n2_field_tab__option--selected';
            }
            $html .= Html::openTag("div", array(
                "class"       => $class,
                "data-ssoption" => $option
            ));
            $html .= $label;
            $html .= Html::closeTag("div");
        }

        return $html;
    }
}Element/Text/Color.php000064400000001573151160515070010657
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Text;

class Color extends Text {

    protected $alpha = false;

    protected $class = 'n2_field_color ';

    protected function fetchElement() {

        if ($this->alpha) {
            $this->class .= 'n2_field_color--alpha ';
        }

        $html = parent::fetchElement();
        Js::addInline('new _N2.FormElementColor("' .
$this->fieldID . '", ' . intval($this->alpha) .
');');

        return $html;
    }

    protected function pre() {

        return '<div class="n2-field-color-preview
n2_checker_box"><div
class="n2-field-color-preview-inner"></div></div>';
    }

    protected function post() {
        return '';
    }

    /**
     * @param boolean $alpha
     */
    public function setAlpha($alpha) {
        $this->alpha = $alpha;
    }
}Element/Text/Disabled.php000064400000000276151160515070011307
0ustar00<?php

namespace Nextend\Framework\Form\Element\Text;

use Nextend\Framework\Form\Element\Text;

class Disabled extends Text {

    protected $attributes = array('disabled' =>
'disabled');
}Element/Text/Family.php000064400000001006151160515070011011
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Font\FontSettings;
use Nextend\Framework\Form\Element\Text;

class Family extends Text {

    protected $class = 'n2_field_autocomplete
n2_autocomplete_position_to';

    protected function addScript() {
        parent::addScript();

        $families = FontSettings::getPresetFamilies();
        Js::addInline('_N2.AutocompleteSimple("' .
$this->fieldID . '", ' . json_encode($families) .
');');
    }
}Element/Text/FieldImage.php000064400000002767151160515070011575
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Browse\BrowseManager;
use Nextend\Framework\Form\Element\AbstractChooserText;
use Nextend\Framework\Image\Image;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Sanitize;

class FieldImage extends AbstractChooserText {

    protected $attributes = array();

    protected $relatedAlt = '';

    protected $class = ' n2_field_text_image';

    protected function addScript() {

        $options = array();
        if (!empty($this->relatedAlt)) {
            $options['alt'] = $this->relatedAlt;
        }

        Js::addInline("new _N2.FormElementImage('" .
$this->fieldID . "', " . json_encode($options) . "
);");
    }

    protected function fetchElement() {

        BrowseManager::enqueue($this->getForm());

        $html = parent::fetchElement();

        Image::initLightbox();

        return $html;
    }

    protected function pre() {

        return '<div class="n2_field_text_image__preview"
style="' . $this->getImageStyle() .
'"></div>';
    }

    protected function getImageStyle() {
        $image = $this->getValue();
        if (empty($image) || $image[0] == '{') {
            return '';
        }

        return 'background-image:URL(' .
Sanitize::esc_attr(ResourceTranslator::toUrl($image)) . ');';
    }

    /**
     * @param string $relatedAlt
     */
    public function setRelatedAlt($relatedAlt) {
        $this->relatedAlt = $relatedAlt;
    }
}Element/Text/FieldImageResponsive.php000064400000001472151160515070013643
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Image\ImageManager;
use Nextend\Framework\View\Html;

class FieldImageResponsive extends FieldImage {

    protected function fetchElement() {
        ImageManager::enqueue($this->getForm());
    

        $html = parent::fetchElement();

        $html .= Html::tag('a', array(
            'id'         => $this->fieldID .
'_manage',
            'class'      => 'n2_field_button
n2_field_button--icon n2_field_text_image__button',
            'href'       => '#',
            'data-n2tip' => n2_('Select images for
devices')
        ), '<i class="ssi_16
ssi_16--desktopportrait"></i>');

        Js::addInline('new _N2.FormElementImageManager("' .
$this->fieldID . '", {});');
    

        return $html;
    }
}Element/Text/Folder.php000064400000002117151160515070011007
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Browse\BrowseManager;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Image\Image;
use Nextend\Framework\View\Html;

class Folder extends Text {

    protected $width = 300;

    protected function addScript() {

        BrowseManager::enqueue($this->getForm());

        Image::initLightbox();

        Js::addInline("new _N2.FormElementFolders('" .
$this->fieldID . "' );");
    }

    protected function post() {

        $html = Html::tag('a', array(
            'href'     => '#',
            'class'    => 'n2_field_text__clear',
            'tabindex' => -1
        ), Html::tag('i', array('class' =>
'ssi_16 ssi_16--circularremove'), ''));

        $html .= Html::tag('a', array(
            'href'       => '#',
            'class'      => 'n2_field_text__choose',
            'aria-label' => n2_('Choose')
        ), '<i class="ssi_16
ssi_16--plus"></i>');

        return $html;
    }

    public function setWidth($width) {
        $this->width = $width;
    }
}Element/Text/HiddenText.php000064400000000374151160515070011637
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Form\Element\Text;

class HiddenText extends Text {

    public $fieldType = 'hidden';

    public function getRowClass() {
        return 'n2_form_element--hidden';
    }
}Element/Text/Number.php000064400000005414151160515070011027
0ustar00<?php

namespace Nextend\Framework\Form\Element\Text;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\View\Html;

class Number extends Text {

    protected $class = 'n2_field_number ';

    protected $min = false;
    protected $max = false;
    protected $sublabel = '';

    protected $units = false;

    protected function fetchElement() {

        if ($this->min === false) {
            $this->min = '-Number.MAX_VALUE';
        }

        if ($this->max === false) {
            $this->max = 'Number.MAX_VALUE';
        }

        $this->addScript();

        $this->renderRelatedFields();

        $html = Html::openTag('div', array(
            'class' => 'n2_field_text ' .
$this->getClass(),
            'style' => ($this->fieldType ==
'hidden' ? 'display: none;' : '')
        ));

        if (!empty($this->sublabel)) {
            $html .= Html::tag('div', array(
                'class' =>
'n2_field_text__pre_label'
            ), $this->sublabel);
        }

        $html .= $this->pre();

        $html .= Html::tag('input', array(
            'type'         => $this->fieldType,
            'id'           => $this->fieldID,
            'name'         => $this->getFieldName(),
            'value'        => $this->getValue(),
            'style'        => $this->getStyle(),
            'autocomplete' => 'off'
        ), false, false);

        $html .= $this->post();

        if ($this->unit) {
            $html .= Html::tag('div', array(
                'class' => 'n2_field_number__unit'
            ), $this->unit);
        }
        $html .= "</div>";

        return $html;
    }

    protected function addScript() {
        Js::addInline('new _N2.FormElementNumber("' .
$this->fieldID . '", ' . $this->min . ', ' .
$this->max . ', ' . json_encode($this->units) .
');');
    }

    public function setMin($min) {
        $this->min = $min;
    }

    /**
     * @param int $max
     */
    public function setMax($max) {
        $this->max = $max;
    }

    /**
     * @param string $sublabel
     */
    public function setSublabel($sublabel) {
        $this->sublabel = $sublabel;
    }

    /**
     * @param bool|array $units
     */
    public function setUnits($units) {
        $this->units = $units;
    }

    public function setWide($wide) {
        switch ($wide) {
            case 2:
                $this->style .= 'width:20px;';
                break;
            case 3:
                $this->style .= 'width:26px;';
                break;
            case 4:
                $this->style .= 'width:32px;';
                break;
            case 5:
                $this->style .= 'width:44px;';
                break;
            case 6:
                $this->style .= 'width:60px;';
                break;
        }
    }
}Element/Text/NumberAutoComplete.php000064400000001051151160515070013342
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;

class NumberAutoComplete extends Number {

    protected $values = array();

    protected $class = 'n2_field_number n2_autocomplete_position_to
';

    protected function addScript() {
        parent::addScript();

        Js::addInline('_N2.AutocompleteSimple("' .
$this->fieldID . '", ' . json_encode($this->values) .
');');
    }

    /**
     * @param array $values
     */
    public function setValues($values) {
        $this->values = $values;
    }
}Element/Text/NumberSlider.php000064400000002053151160515070012166
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;

class NumberSlider extends Number {

    protected $step = 1;

    protected $sliderMax;

    protected function fetchElement() {
        $html = parent::fetchElement();

        Js::addInline('new _N2.FormElementNumberSlider("' .
$this->fieldID . '", ' . json_encode(array(
                'min'   => floatval($this->min),
                'max'   => floatval($this->sliderMax),
                'step'  => floatval($this->step),
                'units' => $this->units
            )) . ');');

        return $html;
    }

    /**
     * @param int $step
     */
    public function setStep($step) {
        $this->step = $step;
    }

    /**
     * @param int $sliderMax
     */
    public function setSliderMax($sliderMax) {
        $this->sliderMax = $sliderMax;
    }

    /**
     * @param int $max
     */
    public function setMax($max) {
        parent::setMax($max);

        if ($this->sliderMax === null) {
            $this->sliderMax = $max;
        }
    }
}Element/Text/TextAutoComplete.php000064400000001123151160515070013036
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Text;

class TextAutoComplete extends Text {

    protected $class = 'n2_field_autocomplete
n2_autocomplete_position_to';

    protected $values = array();

    protected function addScript() {
        parent::addScript();

        Js::addInline('_N2.AutocompleteSimple("' .
$this->fieldID . '", ' . json_encode($this->values) .
');');
    }

    /**
     * @param array $values
     */
    public function setValues($values) {
        $this->values = $values;
    }
}Element/Text/TextMultiAutoComplete.php000064400000001527151160515070014061
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\View\Html;

class TextMultiAutoComplete extends Text {

    protected $options = array();

    protected $class = 'n2_field_autocomplete ';

    protected function addScript() {
        Js::addInline('new _N2.FormElementAutocomplete("' .
$this->fieldID . '", ' . json_encode($this->options) .
');');
    }

    protected function post() {
        return Html::tag('a', array(
            'href'  => '#',
            'class' => 'n2_field_text__clear',
            'tabindex' => -1
        ), Html::tag('i', array('class' =>
'ssi_16 ssi_16--circularremove'), ''));
    }

    /**
     * @param array $options
     */
    public function setOptions($options) {
        $this->options = $options;
    }
}Element/Text/Url.php000064400000002263151160515070010340 0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Element\AbstractChooserText;
use Nextend\Framework\Localization\Localization;
use Nextend\Framework\Pattern\MVCHelperTrait;
use Nextend\Framework\Platform\Platform;

class Url extends AbstractChooserText {

    protected function addScript() {
        Js::addInline("new _N2.FormElementUrl('" .
$this->fieldID . "', " .
$this->getElementUrlParameters($this->getForm()) . " );");
    }

    /**
     * @param MVCHelperTrait $MVCHelper
     *
     * @return string
     */
    private function getElementUrlParameters($MVCHelper) {
        $params = array(
            'hasPosts' => Platform::hasPosts()
        );

        $params['url'] =
$MVCHelper->createAjaxUrl("content/searchlink");
        $params['labelButton']      = 'Joomla';
        $params['labelDescription'] = n2_(/** @lang text */
'Select article or menu item from your site.');
    

        return json_encode($params);
    }

    protected function post() {

        return parent::post();
    }

    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }

}Element/Text/Video.php000064400000000452151160515070010642
0ustar00<?php


namespace Nextend\Framework\Form\Element\Text;


use Nextend\Framework\Browse\BrowseManager;

class Video extends FieldImage {

    protected function fetchElement() {

        BrowseManager::enqueue($this->getForm());

        $html = parent::fetchElement();

        return $html;
    }
}Element/Text.php000064400000004473151160515070007603 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Form\TraitFieldset;
use Nextend\Framework\View\Html;

class Text extends AbstractField implements ContainerInterface {

    use TraitFieldset;

    protected $attributes = array();

    public $fieldType = 'text';

    protected $unit = false;

    protected function addScript() {
        Js::addInline('new _N2.FormElementText("' .
$this->fieldID . '");');
    }

    protected function fetchElement() {

        $this->addScript();

        if ($this->getValue() === '') {
            $this->class .= 'n2_field_text--empty ';
        }

        $html = Html::openTag('div', array(
            'class' => 'n2_field_text ' .
$this->getClass(),
            'style' => ($this->fieldType ==
'hidden' ? 'display: none;' : '')
        ));

        $html .= $this->pre();
        $html .= Html::tag('input', $this->attributes + array(
                'type'         => $this->fieldType,
                'id'           => $this->fieldID,
                'name'         => $this->getFieldName(),
                'value'        => $this->getValue(),
                'style'        => $this->getStyle(),
                'autocomplete' => 'off'
            ), false, false);

        $html .= $this->post();

        if (!empty($this->unit)) {
            $html .= Html::tag('div', array(
                'class' => 'n2_field_text__unit'
            ), $this->unit);
        }
        $html .= "</div>";

        return $html;
    }

    public function setUnit($unit) {
        $this->unit = $unit;
    }

    protected function pre() {
        return '';
    }

    protected function post() {

        if ($this->first) {
            $html = '';

            $element = $this->first;
            while ($element) {

                $html .= $this->decorateElement($element);

                $element = $element->getNext();
            }

            return '<div
class="n2_field_text__post">' . $html .
'</div>';
        }

        return '';
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        list($label, $fieldHTML) = $element->render();

        return $fieldHTML;
    }
}Element/Textarea/TextareaInline.php000064400000000467151160515070013347
0ustar00<?php


namespace Nextend\Framework\Form\Element\Textarea;


use Nextend\Framework\Form\Element\Textarea;

class TextareaInline extends Textarea {

    protected $width = 200;

    protected $height = 26;

    protected $classes = array(
        'n2_field_textarea',
        'n2_field_textarea--inline'
    );
}Element/Textarea.php000064400000003275151160515070010433 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;

class Textarea extends AbstractField {

    protected $width = 200;

    protected $height = 44;

    protected $minHeight = 44;

    protected $resize = 'vertical';

    protected $classes = array(
        'n2_field_textarea'
    );

    protected function fetchElement() {

        Js::addInline('new _N2.FormElementText("' .
$this->fieldID . '");');

        return Html::tag('div', array(
            'class' => implode(' ',
$this->classes),
            'style' => $this->style
        ), Html::tag('textarea', array(
            'id'           => $this->fieldID,
            'name'         => $this->getFieldName(),
            'autocomplete' => 'off',
            'style'        => 'width:' .
$this->width . 'px;height:' . $this->height .
'px;min-height:' . $this->minHeight . 'px;resize:' .
$this->resize . ';'
        ), Sanitize::esc_textarea($this->getValue())));
    }

    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }

    /**
     * @param int $height
     */
    public function setHeight($height) {
        $this->height = $height;
        if ($this->minHeight > $height) {
            $this->minHeight = $height;
        }
    }

    /**
     * @param int $minHeight
     */
    public function setMinHeight($minHeight) {
        $this->minHeight = $minHeight;
    }

    /**
     * @param string $resize
     */
    public function setResize($resize) {
        $this->resize = $resize;
    }

    public function setFieldStyle($style) {

    }
}Element/Token.php000064400000000304151160515070007724 0ustar00<?php


namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Form\Form;

class Token extends Hidden {

    protected function fetchElement() {

        return Form::tokenize();
    }
}Element/Unit.php000064400000002642151160515070007572 0ustar00<?php


namespace Nextend\Framework\Form\Element;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\View\Html;

class Unit extends AbstractFieldHidden {

    protected $style = '';

    protected $units = array();

    protected function fetchElement() {

        $values = array();

        $html = "<div class='n2_field_unit'
style='" . $this->style . "'>";

        $currentValue = $this->getValue();
        $currentLabel = '';

        $html .= Html::openTag('div', array(
            'class' => 'n2_field_unit__units'
        ));
        foreach ($this->units AS $unit) {
            $values[] = $unit;

            $html .= Html::tag('div', array(
                'class' => 'n2_field_unit__unit'
            ), $unit);

            if ($currentValue == $unit) {
                $currentLabel = $unit;
            }
        }

        $html .= "</div>";

        $html .= Html::tag('div', array(
            'class' => 'n2_field_unit__current_unit'
        ), $currentLabel);

        $html .= parent::fetchElement();

        $html .= "</div>";

        Js::addInline('new _N2.FormElementUnits("' .
$this->fieldID . '", ' . json_encode($values) .
');');

        return $html;
    }

    /**
     * @param string $style
     */
    public function setStyle($style) {
        $this->style = $style;
    }

    /**
     * @param array $units
     */
    public function setUnits($units) {
        $this->units = $units;
    }
}Element/Upload.php000064400000002016151160515070010072 0ustar00<?php

namespace Nextend\Framework\Form\Element;

use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\View\Html;

class Upload extends AbstractField {

    protected $class = 'n2-form-element-file ';

    protected function fetchElement() {

        $html = '';
        $html .= '<div
class="n2_field_chooser__label"></div>';
        $html .= Html::tag('a', array(
            'href'  => '#',
            'class' => 'n2_field_chooser__choose'
        ), '<i class="ssi_16
ssi_16--plus"></i>');

        $html .= Html::tag('input', array(
            'type'         => 'file',
            'id'           => $this->fieldID,
            'name'         => $this->getFieldName(),
            'value'        => $this->getValue(),
            'autocomplete' => 'off'
        ), false, false);

        Js::addInline('new _N2.FormElementUpload("' .
$this->fieldID . '");');

        return Html::tag('div', array(
            'class' => 'n2_field_chooser n2_field_upload
'
        ), $html);
    }
}Fieldset/FieldsetHidden.php000064400000001134151160515070011667
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset;

use Nextend\Framework\Form\AbstractFieldset;

class FieldsetHidden extends AbstractFieldset {

    public function __construct($insertAt) {

        parent::__construct($insertAt, '');
    }

    public function renderContainer() {

        if ($this->first) {
            echo '<div
class="n2_form_element--hidden">';

            $element = $this->first;
            while ($element) {
                echo $this->decorateElement($element);

                $element = $element->getNext();
            }

            echo '</div>';
        }
    }

}Fieldset/FieldsetRow.php000064400000003360151160515070011246
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\AbstractFieldset;
use Nextend\Framework\View\Html;

class FieldsetRow extends AbstractFieldset {

    public function __construct($insertAt, $name, $parameters = array()) {
        parent::__construct($insertAt, $name, false, $parameters);
    }

    public function renderContainer() {

        $classes = array('n2_form__table_row');
        if (!$this->isVisible) {
            $classes[] = 'n2_form__table_row--hidden';
        }

        echo Html::openTag('div', array(
            'class'      => implode(' ', $classes),
            'data-field' => 'table-row-' .
$this->name
        ));

        $element = $this->first;
        while ($element) {
            echo $this->decorateElement($element);

            $element = $element->getNext();
        }
        echo '</div>';
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        ob_start();

        $hasLabel = $element->hasLabel();

        $classes = array(
            'n2_field',
            $element->getLabelClass(),
            $element->getRowClass()
        );

        echo Html::openTag('div', array(
                'class'      => implode(' ',
array_filter($classes)),
                'data-field' => $element->getID()
            ) + $element->getRowAttributes());

        if ($hasLabel) {
            echo "<div class='n2_field__label'>";
            $element->displayLabel();
            echo "</div>";
        }

        echo "<div class='n2_field__element'>";
        $element->displayElement();
        echo "</div>";

        echo "</div>";

        return ob_get_clean();
    }
}Fieldset/FieldsetRowPlain.php000064400000001307151160515070012231
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset;


use Nextend\Framework\Form\AbstractField;

class FieldsetRowPlain extends FieldsetRow {

    public function renderContainer() {
        echo '<div class="n2_form__table_row_plain"
data-field="table-row-plain-' . $this->name .
'">';

        $element = $this->first;
        while ($element) {
            echo $this->decorateElement($element);

            $element = $element->getNext();
        }

        echo '</div>';
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        ob_start();

        $element->displayElement();

        return ob_get_clean();
    }
}Fieldset/FieldsetTableLabel.php000064400000001236151160515070012466
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset;


use Nextend\Framework\Form\AbstractFieldset;
use Nextend\Framework\View\Html;

class FieldsetTableLabel extends AbstractFieldset {

    public function renderContainer() {

        $element = $this->first;
        while ($element) {

            echo Html::openTag('div', array(
                    'class'      =>
'n2_form__table_label_field ' . $element->getRowClass(),
                    'data-field' => $element->getID()
                ) + $element->getRowAttributes());
            echo $this->decorateElement($element);
            echo "</div>";

            $element = $element->getNext();
        }
    }
}Fieldset/FieldsetVisualSet.php000064400000002256151160515070012421
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\AbstractFieldset;
use Nextend\Framework\View\Html;

class FieldsetVisualSet extends AbstractFieldset {

    public function renderContainer() {
        echo '<div class="n2_form__visual_set"
data-field="visual-set-' . $this->name .
'">';

        echo "<div
class='n2_form__visual_set_label'>" . $this->label .
'</div>';

        $element = $this->first;
        while ($element) {
            echo $this->decorateElement($element);

            $element = $element->getNext();
        }
        echo '</div>';
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        ob_start();

        $classes = array(
            'n2_field',
            $element->getRowClass()
        );

        echo Html::openTag('div', array(
                'class'      => implode(' ',
array_filter($classes)),
                'data-field' => $element->getID()
            ) + $element->getRowAttributes());

        $element->displayElement();

        echo "</div>";

        return ob_get_clean();
    }
}Fieldset/LayerWindow/FieldsetDesign.php000064400000003110151160515070014145
0ustar00<?php

namespace Nextend\Framework\Form\Fieldset\LayerWindow;

use Nextend\Framework\Form\Element\Button\ButtonIcon;
use Nextend\Framework\Form\Element\Select;

class FieldsetDesign extends FieldsetLayerWindowLabelFields {

    public function __construct($insertAt, $name, $label) {
        parent::__construct($insertAt, $name, $label);

        $this->addAttribute('data-fieldset-type',
'design');

        new ButtonIcon($this->fieldsetLabel, $name .
'-reset-to-normal', false, 'ssi_16 ssi_16--reset',
array(
            'hoverTip'      => n2_('Reset to normal
state'),
            'rowAttributes' => array(
                'data-design-feature' =>
'reset-to-normal'
            )
        ));
        new Select($this->fieldsetLabel, $name . '-element',
false, '', array(
            'rowAttributes' => array(
                'data-design-feature' => 'element'
            )
        ));
        new Select($this->fieldsetLabel, $name . '-state',
false, '', array(
            'rowAttributes' => array(
                'data-design-feature' => 'state'
            )
        ));
    }

    protected function renderTitle() {

        echo '<div
class="n2_fields_layer_window__label">' . $this->label
. '</div>';

        if ($this->fieldsetLabel->hasFields()) {
            echo '<div
class="n2_fields_layer_window__title_fields">';
            $this->fieldsetLabel->renderContainer();
            echo '</div>';
        }
    }

    /**
     * @param mixed $parentDesign
     */
    public function setParentDesign($parentDesign) {
        $this->addAttribute('data-parent-design',
$parentDesign);
    }
}Fieldset/LayerWindow/FieldsetInsideLabel.php000064400000001240151160515070015111
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset\LayerWindow;


use Nextend\Framework\Form\AbstractFieldset;
use Nextend\Framework\View\Html;

class FieldsetInsideLabel extends AbstractFieldset {

    public function renderContainer() {

        $element = $this->first;
        while ($element) {

            echo Html::openTag('div', array(
                    'class'      =>
'n2_form__table_label_field ' . $element->getRowClass(),
                    'data-field' => $element->getID()
                ) + $element->getRowAttributes());
            $element->displayElement();
            echo "</div>";

            $element = $element->getNext();
        }
    }
}Fieldset/LayerWindow/FieldsetLayerWindow.php000064400000004363151160515070015213
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset\LayerWindow;


use Nextend\Framework\Form\AbstractField;
use Nextend\Framework\Form\AbstractFieldset;
use Nextend\Framework\View\Html;

class FieldsetLayerWindow extends AbstractFieldset {

    protected $attributes = array();

    public function renderContainer() {

        echo Html::openTag('div', array(
                'class'      =>
'n2_fields_layer_window',
                'data-field' =>
'fieldset-layer-window-' . $this->name
            ) + $this->attributes);

        if (!empty($this->label)) {
            echo '<div
class="n2_fields_layer_window__title">';
            $this->renderTitle();
            echo '</div>';
        }

        echo '<div
class="n2_fields_layer_window__fields">';

        $element = $this->first;
        while ($element) {
            echo $this->decorateElement($element);

            $element = $element->getNext();
        }

        echo '</div>';
        echo '</div>';
    }

    protected function renderTitle() {

        echo '<div
class="n2_fields_layer_window__label">' . $this->label
. '</div>';
    }

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    public function decorateElement($element) {

        ob_start();

        $hasLabel = $element->hasLabel();

        $classes = array(
            'n2_field',
            $element->getLabelClass(),
            $element->getRowClass()
        );

        echo Html::openTag('div', array(
                'class'      => implode(' ',
array_filter($classes)),
                'data-field' => $element->getID()
            ) + $element->getRowAttributes());

        if ($hasLabel) {
            echo "<div class='n2_field__label'>";
            $element->displayLabel();
            echo "</div>";
        }

        echo "<div class='n2_field__element'>";
        $element->displayElement();
        echo "</div>";

        echo "</div>";

        return ob_get_clean();
    }

    /**
     * @param array $attributes
     */
    public function setAttributes($attributes) {
        $this->attributes = $attributes;
    }

    /**
     * @param string $name
     * @param string $value
     */
    public function addAttribute($name, $value) {
        $this->attributes[$name] = $value;
    }
}Fieldset/LayerWindow/FieldsetLayerWindowLabelFields.php000064400000002114151160515070017272
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset\LayerWindow;


use Nextend\Framework\Form\Container\ContainerAlternative;

class FieldsetLayerWindowLabelFields extends FieldsetLayerWindow {

    /**
     * @var FieldsetInsideLabel
     */
    protected $fieldsetLabel;

    public function __construct($insertAt, $name, $label, $parameters =
array()) {
        parent::__construct($insertAt, $name, $label, $parameters);

        $labelContainer      = new ContainerAlternative($this->parent,
$name . '-container-label');
        $this->fieldsetLabel = new FieldsetInsideLabel($labelContainer,
$name . '-label', false);
    }

    /**
     * @return FieldsetInsideLabel
     */
    public function getFieldsetLabel() {
        return $this->fieldsetLabel;
    }

    protected function renderTitle() {
        echo '<div
class="n2_fields_layer_window__label">' . $this->label
. '</div>';

        echo '<div
class="n2_fields_layer_window__title_fields">';
        if ($this->fieldsetLabel->hasFields()) {
            $this->fieldsetLabel->renderContainer();
        }
        echo '</div>';
    }
}Fieldset/LayerWindow/FieldsetLayerWindowStyleMode.php000064400000001602151160515070017032
0ustar00<?php


namespace Nextend\Framework\Form\Fieldset\LayerWindow;


use Nextend\Framework\Form\Element\Button\ButtonIcon;
use Nextend\Framework\Form\Element\Select;

class FieldsetLayerWindowStyleMode extends FieldsetLayerWindowLabelFields {

    public function __construct($insertAt, $name, $label, $modes,
$parameters = array()) {
        parent::__construct($insertAt, $name, $label, $parameters);

        $this->addAttribute('data-fieldset-type',
'style-mode');

        new ButtonIcon($this->fieldsetLabel, $name .
'-mode-reset-to-normal', false, 'ssi_16 ssi_16--reset',
array(
            'hoverTip'      => n2_('Reset to normal
state'),
            'rowAttributes' => array(
                'data-style-mode-feature' =>
'reset-to-normal'
            )
        ));

        new Select($this->fieldsetLabel, $name . '-mode',
false, '', array(
            'options' => $modes
        ));
    }
}FormTabbed.php000064400000003512151160515070007264 0ustar00<?php


namespace Nextend\Framework\Form;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Container\ContainerTab;
use
Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\BlockHeader;
use
Nextend\SmartSlider3\Application\Admin\Layout\Block\Core\Header\MenuItem;

class FormTabbed extends Form {

    protected $classes = array(
        'n2_form',
        'n2_form_tabbed'
    );

    protected $toggleMode = false;

    protected $sessionID = '';

    /**
     * @param $name
     * @param $label
     *
     * @return ContainerTab
     */
    public function createTab($name, $label) {

        return new ContainerTab($this->container, $name, $label);
    }

    /**
     * @param BlockHeader $blockHeader
     */
    public function addTabsToHeader($blockHeader) {
        $element = $this->container->getFirst();
        while ($element) {
            if ($element instanceof ContainerTab) {

                $tab = new MenuItem($element->getLabel());
                $tab->addClass('n2_form__tab_button');
                $tab->setAttribute('data-related-form',
$this->id);
                $tab->setAttribute('data-related-tab',
$element->getId());
                $blockHeader->addMenuItem($tab);
            }

            $element = $element->getNext();
        }
    }

    public function render() {
        parent::render();

        Js::addInline('new _N2.FormTabbed("' . $this->id
. '", ' . json_encode(array(
                'toggleMode' => $this->toggleMode,
                'sessionID'  => $this->sessionID
            )) . ');');
    }

    /**
     * @param bool $toggleMode
     */
    public function setToggleMode($toggleMode) {
        $this->toggleMode = $toggleMode;
    }

    /**
     * @param string $sessionID
     */
    public function setSessionID($sessionID) {
        $this->sessionID = $sessionID;
    }
}Insert/AbstractInsert.php000064400000001101151160515070011443
0ustar00<?php


namespace Nextend\Framework\Form\Insert;

use Nextend\Framework\Form\ContainedInterface;
use Nextend\Framework\Form\ContainerInterface;

abstract class AbstractInsert {

    /**
     * @var ContainedInterface
     */
    protected $at;

    /**
     * AbstractInsert constructor.
     *
     * @param ContainedInterface $at
     */
    public function __construct($at) {
        $this->at = $at;
    }

    /**
     * @param ContainedInterface $element
     *
     * @return ContainerInterface Returns the parent
     */
    public abstract function insert($element);
}Insert/InsertAfter.php000064400000000412151160515070010745
0ustar00<?php


namespace Nextend\Framework\Form\Insert;


class InsertAfter extends AbstractInsert {

    public function insert($element) {
        $parent = $this->at->getParent();
        $parent->insertElementAfter($element, $this->at);

        return $parent;
    }
}Insert/InsertBefore.php000064400000000414151160515070011110
0ustar00<?php


namespace Nextend\Framework\Form\Insert;


class InsertBefore extends AbstractInsert {

    public function insert($element) {
        $parent = $this->at->getParent();
        $parent->insertElementBefore($element, $this->at);

        return $parent;
    }
}Joomla/Element/Select/MenuItems.php000064400000001306151160515070013215
0ustar00<?php


namespace Nextend\Framework\Form\Joomla\Element\Select;


use JMenu;
use Nextend\Framework\Form\Element\Select;

class MenuItems extends Select {

    public function __construct($insertAt, $name = '', $label =
'', $default = '', $parameters = array()) {
        parent::__construct($insertAt, $name, $label, $default,
$parameters);

        $menu      = JMenu::getInstance('site');
        $menuItems = $menu->getItems($attributes = array(), $values =
array());

        $this->options['0'] = n2_('Default');

        if (count($menuItems)) {
            foreach ($menuItems AS $item) {
                $this->options[$item->id] = '[' .
$item->id . '] ' . $item->title;
            }
        }
    }
}Joomla/PlatformForm.php000064400000001054151160515070011107
0ustar00<?php

namespace Nextend\Framework\Form\Joomla;

use JSession;
use Nextend\Framework\Form\Base\PlatformFormBase;

class PlatformForm extends PlatformFormBase {

    public function tokenize() {
        return '<input type="hidden" name="' .
JSession::getFormToken() . '" value="1">';
    }

    public function tokenizeUrl() {
        $a                           = array();
        $a[JSession::getFormToken()] = 1;

        return $a;
    }

    public function checkToken() {
        return JSession::checkToken() ||
JSession::checkToken('get');
    }
}TraitContainer.php000064400000005070151160515070010206 0ustar00<?php


namespace Nextend\Framework\Form;


trait TraitContainer {

    /**
     * @var ContainedInterface
     */
    protected $first, $last;

    /**
     * @var ContainedInterface[]
     */
    protected $flattenElements = array();

    /**
     * @param ContainedInterface $element
     */
    public function addElement($element) {

        if (!$this->first) {
            $this->first = $element;
        }

        if ($this->last) {
            $this->last->setNext($element);
        }

        $this->last = $element;

        $name = $element->getName();
        if ($name) {
            $this->flattenElements[$name] = $element;
        }
    }

    /**
     * @param ContainedInterface $element
     * @param ContainedInterface $target
     */
    public function insertElementBefore($element, $target) {
        $previous = $target->getPrevious();
        if ($previous) {
            $previous->setNext($element);
        } else {
            $this->first = $element;
        }

        $element->setNext($target);

        $name = $element->getName();
        if ($name) {
            $this->flattenElements[$name] = $element;
        }
    }

    /**
     * @param AbstractField $element
     * @param AbstractField $target
     */
    public function insertElementAfter($element, $target) {

        $next = $target->getNext();
        $target->setNext($element);

        if ($next) {
            $element->setNext($next);
        } else {
            $this->last = $element;
        }

        $name = $element->getName();
        if ($name) {
            $this->flattenElements[$name] = $element;
        }
    }

    /**
     * @param AbstractField $element
     */
    public function removeElement($element) {
        $previous = $element->getPrevious();
        $next     = $element->getNext();

        if ($this->first === $element) {
            $this->first = $next;
        }

        if ($this->last === $element) {
            $this->last = $previous;
        }

        if ($previous) {
            $previous->setNext($next);
        } else {
            $next->setPrevious();
        }
    }

    /**
     * @param $path
     *
     * @return AbstractField
     */
    public function getElement($path) {
        $parts   = explode('/', $path, 2);
        $element = $this->flattenElements[$parts[0]];
        if (!empty($parts[1]) && $element instanceof
ContainerInterface) {
            $element = $element->getElement($parts[1]);
        }

        return $element;
    }

    public function getElementIdentifiers() {
        return array_keys($this->flattenElements);
    }
}TraitFieldset.php000064400000001603151160515070010021 0ustar00<?php

namespace Nextend\Framework\Form;

trait TraitFieldset {

    use TraitContainer;

    /**
     * @var AbstractField
     */
    protected $first, $last;

    /**
     * @var bool
     */
    protected $isVisible = true;

    public function hide() {
        $this->isVisible = false;
    }

    /**
     * @return ContainerInterface
     */
    public function getParent() {
        return $this->parent;
    }

    public function getPath() {
        return $this->getParent()
                    ->getPath() . '/' . $this->name;
    }

    public function renderContainer() {

    }

    abstract public function getControlName();

    /**
     * @return Form
     */
    abstract public function getForm();

    /**
     * @param AbstractField $element
     *
     * @return string
     */
    abstract public function decorateElement($element);

    abstract public function getName();
}