Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla4/ |
| [Home] [System Details] [Kill Me] |
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&view=history&layout=modal&tmpl=component&field='
. $this->id . '&item_id=' . $itemId .
'&type_id=' . $typeId . '&type_alias='
. $this->element['data-typeAlias'] . '&'
. 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
. '&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' => '↓',
'horizontal' => '→',
'diagonal1' => '↗',
'diagonal2' => '↘'
);
}
}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();
}