Your IP : 216.73.217.68


Current Path : /home/w/u/e/wuectly/www/03cbe/
Upload File :
Current File : /home/w/u/e/wuectly/www/03cbe/field.php.tar

home/wuectly/www/libraries/fof/form/field.php000060400000001647152455516040015314 0ustar00<?php
/**
 * @package     FrameworkOnFramework
 * @subpackage  form
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;

/**
 * Generic interface that a FOF form field class must implement
 *
 * @package  FrameworkOnFramework
 * @since    2.0
 */
interface FOFFormField
{
	/**
	 * Get the rendering of this field type for static display, e.g. in a single
	 * item view (typically a "read" task).
	 *
	 * @return  string  The field HTML
	 *
	 * @since 2.0
	 */
	public function getStatic();

	/**
	 * Get the rendering of this field type for a repeatable (grid) display,
	 * e.g. in a view listing many item (typically a "browse" task)
	 *
	 * @return  string  The field HTML
	 *
	 * @since 2.0
	 */
	public function getRepeatable();
}
home/wuectly/www/libraries/fof/form/header/field.php000060400000001640152455572130016537 0ustar00<?php
/**
 * @package    FrameworkOnFramework
 * @subpackage form
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 */
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;

/**
 * Generic field header, without any filters
 *
 * @package  FrameworkOnFramework
 * @since    2.0
 */
class FOFFormHeaderField extends FOFFormHeader
{
	/**
	 * Get the header
	 *
	 * @return  string  The header HTML
	 */
	protected function getHeader()
	{
		$sortable = ($this->element['sortable'] != 'false');

		$label = $this->getLabel();

		if ($sortable)
		{
			$view = $this->form->getView();

			return JHTML::_('grid.sort', $label, $this->name,
				$view->getLists()->order_Dir, $view->getLists()->order,
				$this->form->getModel()->task
			);
		}
		else
		{
			return JText::_($label);
		}
	}
}
home/wuectly/www/libraries/fof/model/field.php000060400000020264152456020300015433 0ustar00<?php
/**
 * @package     FrameworkOnFramework
 * @subpackage  model
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// Protect from unauthorized access
defined('FOF_INCLUDED') or die;

/**
 * FrameworkOnFramework model behavior class
 *
 * @package  FrameworkOnFramework
 * @since    2.1
 */
abstract class FOFModelField
{
	protected $_db = null;

	/**
	 * The column name of the table field
	 *
	 * @var string
	 */
	protected $name = '';

	/**
	 * The column type of the table field
	 *
	 * @var string
	 */
	protected $type = '';

	/**
	 * The alias of the table used for filtering
	 *
	 * @var string
	 */
	protected $table_alias = false;

	/**
	 * The null value for this type
	 *
	 * @var  mixed
	 */
	public $null_value = null;

	/**
	 * Constructor
	 *
	 * @param   FOFDatabaseDriver  $db           The database object
	 * @param   object           $field        The field informations as taken from the db
	 * @param   string           $table_alias  The table alias to use when filtering
	 */
	public function __construct($db, $field, $table_alias = false)
	{
		$this->_db = $db;

		$this->name = $field->name;
		$this->type = $field->type;
		$this->filterzero = $field->filterzero;
		$this->table_alias = $table_alias;
	}

	/**
	 * Is it a null or otherwise empty value?
	 *
	 * @param   mixed  $value  The value to test for emptiness
	 *
	 * @return  boolean
	 */
	public function isEmpty($value)
	{
		return (($value === $this->null_value) || empty($value))
			&& !($this->filterzero && $value === "0");
	}

	/**
	 * Returns the default search method for a field. This always returns 'exact'
	 * and you are supposed to override it in specialised classes. The possible
	 * values are exact, partial, between and outside, unless something
	 * different is returned by getSearchMethods().
	 *
	 * @see  self::getSearchMethods()
	 *
	 * @return  string
	 */
	public function getDefaultSearchMethod()
	{
		return 'exact';
	}

	/**
	 * Return the search methods available for this field class,
	 *
	 * @return  array
	 */
	public function getSearchMethods()
	{
		$ignore = array('isEmpty', 'getField', 'getFieldType', '__construct', 'getDefaultSearchMethod', 'getSearchMethods');

		$class = new ReflectionClass(__CLASS__);
		$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);

		$tmp = array();

		foreach ($methods as $method)
		{
			$tmp[] = $method->name;
		}

		$methods = $tmp;

		if ($methods = array_diff($methods, $ignore))
		{
			return $methods;
		}

		return array();
	}

	/**
	 * Perform an exact match (equality matching)
	 *
	 * @param   mixed  $value  The value to compare to
	 *
	 * @return  string  The SQL where clause for this search
	 */
	public function exact($value)
	{
		if ($this->isEmpty($value))
		{
			return '';
		}

		if (is_array($value))
		{
			$db    = FOFPlatform::getInstance()->getDbo();
			$value = array_map(array($db, 'quote'), $value);

			return '(' . $this->getFieldName() . ' IN (' . implode(',', $value) . '))';
		}
		else
		{
			return $this->search($value, '=');
		}
	}

	/**
	 * Perform a partial match (usually: search in string)
	 *
	 * @param   mixed  $value  The value to compare to
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function partial($value);

	/**
	 * Perform a between limits match (usually: search for a value between
	 * two numbers or a date between two preset dates). When $include is true
	 * the condition tested is:
	 * $from <= VALUE <= $to
	 * When $include is false the condition tested is:
	 * $from < VALUE < $to
	 *
	 * @param   mixed    $from     The lowest value to compare to
	 * @param   mixed    $to       The higherst value to compare to
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function between($from, $to, $include = true);

	/**
	 * Perform an outside limits match (usually: search for a value outside an
	 * area or a date outside a preset period). When $include is true
	 * the condition tested is:
	 * (VALUE <= $from) || (VALUE >= $to)
	 * When $include is false the condition tested is:
	 * (VALUE < $from) || (VALUE > $to)
	 *
	 * @param   mixed    $from     The lowest value of the excluded range
	 * @param   mixed    $to       The higherst value of the excluded range
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function outside($from, $to, $include = false);

	/**
	 * Perform an interval search (usually: a date interval check)
	 *
	 * @param   string               $from      The value to search
	 * @param   string|array|object  $interval  The interval
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function interval($from, $interval);

	/**
	 * Perform a between limits match (usually: search for a value between
	 * two numbers or a date between two preset dates). When $include is true
	 * the condition tested is:
	 * $from <= VALUE <= $to
	 * When $include is false the condition tested is:
	 * $from < VALUE < $to
	 *
	 * @param   mixed    $from     The lowest value to compare to
	 * @param   mixed    $to       The higherst value to compare to
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function range($from, $to, $include = true);

	/**
	 * Perform an modulo search
	 *
	 * @param   integer|float  $value     The starting value of the search space
	 * @param   integer|float  $interval  The interval period of the search space
	 * @param   boolean        $include   Should I include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause
	 */
	abstract public function modulo($from, $interval, $include = true);

	/**
	 * Return the SQL where clause for a search
	 *
	 * @param   mixed   $value     The value to search for
	 * @param   string  $operator  The operator to use
	 *
	 * @return  string  The SQL where clause for this search
	 */
	public function search($value, $operator = '=')
	{
		if ($this->isEmpty($value))
		{
			return '';
		}

		return '(' . $this->getFieldName() . ' ' . $operator . ' ' . $this->_db->quote($value) . ')';
	}

	/**
	 * Get the field name with the given table alias
	 *
	 * @return  string 	The field name
	 */
	public function getFieldName()
	{
		$name = $this->_db->qn($this->name);

		if ($this->table_alias)
		{
			$name = $this->_db->qn($this->table_alias) . '.' . $name;
		}

		return $name;
	}

	/**
	 * Creates a field Object based on the field column type
	 *
	 * @param   object  $field   The field informations
	 * @param   array   $config  The field configuration (like the db object to use)
	 *
	 * @return  FOFModelField  The Field object
	 */
	public static function getField($field, $config = array())
	{
		$type = $field->type;

		$classType = self::getFieldType($type);

		$className = 'FOFModelField' . $classType;

		if (class_exists($className))
		{
			if (isset($config['dbo']))
			{
				$db = $config['dbo'];
			}
			else
			{
				$db = FOFPlatform::getInstance()->getDbo();
			}

			if (isset($config['table_alias']))
			{
				$table_alias = $config['table_alias'];
			}
			else
			{
				$table_alias = false;
			}

			$field = new $className($db, $field, $table_alias);

			return $field;
		}

		return false;
	}

	/**
	 * Get the classname based on the field Type
	 *
	 * @param   string  $type  The type of the field
	 *
	 * @return  string  the class suffix
	 */
	public static function getFieldType($type)
	{
		switch ($type)
		{
			case 'varchar':
			case 'text':
			case 'smalltext':
			case 'longtext':
			case 'char':
			case 'mediumtext':
			case 'character varying':
			case 'nvarchar':
			case 'nchar':
				$type = 'Text';
				break;

			case 'date':
			case 'datetime':
			case 'time':
			case 'year':
			case 'timestamp':
			case 'timestamp without time zone':
			case 'timestamp with time zone':
				$type = 'Date';
				break;

			case 'tinyint':
			case 'smallint':
				$type = 'Boolean';
				break;

			default:
				$type = 'Number';
				break;
		}

		return $type;
	}
}
home/wuectly/www/libraries/f0f/model/field.php000060400000020264152456133260015346 0ustar00<?php
/**
 * @package     FrameworkOnFramework
 * @subpackage  model
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// Protect from unauthorized access
defined('F0F_INCLUDED') or die;

/**
 * FrameworkOnFramework model behavior class
 *
 * @package  FrameworkOnFramework
 * @since    2.1
 */
abstract class F0FModelField
{
	protected $_db = null;

	/**
	 * The column name of the table field
	 *
	 * @var string
	 */
	protected $name = '';

	/**
	 * The column type of the table field
	 *
	 * @var string
	 */
	protected $type = '';

	/**
	 * The alias of the table used for filtering
	 *
	 * @var string
	 */
	protected $table_alias = false;

	/**
	 * The null value for this type
	 *
	 * @var  mixed
	 */
	public $null_value = null;

	/**
	 * Constructor
	 *
	 * @param   F0FDatabaseDriver  $db           The database object
	 * @param   object           $field        The field informations as taken from the db
	 * @param   string           $table_alias  The table alias to use when filtering
	 */
	public function __construct($db, $field, $table_alias = false)
	{
		$this->_db = $db;

		$this->name = $field->name;
		$this->type = $field->type;
		$this->filterzero = $field->filterzero;
		$this->table_alias = $table_alias;
	}

	/**
	 * Is it a null or otherwise empty value?
	 *
	 * @param   mixed  $value  The value to test for emptiness
	 *
	 * @return  boolean
	 */
	public function isEmpty($value)
	{
		return (($value === $this->null_value) || empty($value))
			&& !($this->filterzero && $value === "0");
	}

	/**
	 * Returns the default search method for a field. This always returns 'exact'
	 * and you are supposed to override it in specialised classes. The possible
	 * values are exact, partial, between and outside, unless something
	 * different is returned by getSearchMethods().
	 *
	 * @see  self::getSearchMethods()
	 *
	 * @return  string
	 */
	public function getDefaultSearchMethod()
	{
		return 'exact';
	}

	/**
	 * Return the search methods available for this field class,
	 *
	 * @return  array
	 */
	public function getSearchMethods()
	{
		$ignore = array('isEmpty', 'getField', 'getFieldType', '__construct', 'getDefaultSearchMethod', 'getSearchMethods');

		$class = new ReflectionClass(__CLASS__);
		$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);

		$tmp = array();

		foreach ($methods as $method)
		{
			$tmp[] = $method->name;
		}

		$methods = $tmp;

		if ($methods = array_diff($methods, $ignore))
		{
			return $methods;
		}

		return array();
	}

	/**
	 * Perform an exact match (equality matching)
	 *
	 * @param   mixed  $value  The value to compare to
	 *
	 * @return  string  The SQL where clause for this search
	 */
	public function exact($value)
	{
		if ($this->isEmpty($value))
		{
			return '';
		}

		if (is_array($value))
		{
			$db    = F0FPlatform::getInstance()->getDbo();
			$value = array_map(array($db, 'quote'), $value);

			return '(' . $this->getFieldName() . ' IN (' . implode(',', $value) . '))';
		}
		else
		{
			return $this->search($value, '=');
		}
	}

	/**
	 * Perform a partial match (usually: search in string)
	 *
	 * @param   mixed  $value  The value to compare to
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function partial($value);

	/**
	 * Perform a between limits match (usually: search for a value between
	 * two numbers or a date between two preset dates). When $include is true
	 * the condition tested is:
	 * $from <= VALUE <= $to
	 * When $include is false the condition tested is:
	 * $from < VALUE < $to
	 *
	 * @param   mixed    $from     The lowest value to compare to
	 * @param   mixed    $to       The higherst value to compare to
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function between($from, $to, $include = true);

	/**
	 * Perform an outside limits match (usually: search for a value outside an
	 * area or a date outside a preset period). When $include is true
	 * the condition tested is:
	 * (VALUE <= $from) || (VALUE >= $to)
	 * When $include is false the condition tested is:
	 * (VALUE < $from) || (VALUE > $to)
	 *
	 * @param   mixed    $from     The lowest value of the excluded range
	 * @param   mixed    $to       The higherst value of the excluded range
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function outside($from, $to, $include = false);

	/**
	 * Perform an interval search (usually: a date interval check)
	 *
	 * @param   string               $from      The value to search
	 * @param   string|array|object  $interval  The interval
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function interval($from, $interval);

	/**
	 * Perform a between limits match (usually: search for a value between
	 * two numbers or a date between two preset dates). When $include is true
	 * the condition tested is:
	 * $from <= VALUE <= $to
	 * When $include is false the condition tested is:
	 * $from < VALUE < $to
	 *
	 * @param   mixed    $from     The lowest value to compare to
	 * @param   mixed    $to       The higherst value to compare to
	 * @param   boolean  $include  Should we include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause for this search
	 */
	abstract public function range($from, $to, $include = true);

	/**
	 * Perform an modulo search
	 *
	 * @param   integer|float  $value     The starting value of the search space
	 * @param   integer|float  $interval  The interval period of the search space
	 * @param   boolean        $include   Should I include the boundaries in the search?
	 *
	 * @return  string  The SQL where clause
	 */
	abstract public function modulo($from, $interval, $include = true);

	/**
	 * Return the SQL where clause for a search
	 *
	 * @param   mixed   $value     The value to search for
	 * @param   string  $operator  The operator to use
	 *
	 * @return  string  The SQL where clause for this search
	 */
	public function search($value, $operator = '=')
	{
		if ($this->isEmpty($value))
		{
			return '';
		}

		return '(' . $this->getFieldName() . ' ' . $operator . ' ' . $this->_db->quote($value) . ')';
	}

	/**
	 * Get the field name with the given table alias
	 *
	 * @return  string 	The field name
	 */
	public function getFieldName()
	{
		$name = $this->_db->qn($this->name);

		if ($this->table_alias)
		{
			$name = $this->_db->qn($this->table_alias) . '.' . $name;
		}

		return $name;
	}

	/**
	 * Creates a field Object based on the field column type
	 *
	 * @param   object  $field   The field informations
	 * @param   array   $config  The field configuration (like the db object to use)
	 *
	 * @return  F0FModelField  The Field object
	 */
	public static function getField($field, $config = array())
	{
		$type = $field->type;

		$classType = self::getFieldType($type);

		$className = 'F0FModelField' . $classType;

		if (class_exists($className))
		{
			if (isset($config['dbo']))
			{
				$db = $config['dbo'];
			}
			else
			{
				$db = F0FPlatform::getInstance()->getDbo();
			}

			if (isset($config['table_alias']))
			{
				$table_alias = $config['table_alias'];
			}
			else
			{
				$table_alias = false;
			}

			$field = new $className($db, $field, $table_alias);

			return $field;
		}

		return false;
	}

	/**
	 * Get the classname based on the field Type
	 *
	 * @param   string  $type  The type of the field
	 *
	 * @return  string  the class suffix
	 */
	public static function getFieldType($type)
	{
		switch ($type)
		{
			case 'varchar':
			case 'text':
			case 'smalltext':
			case 'longtext':
			case 'char':
			case 'mediumtext':
			case 'character varying':
			case 'nvarchar':
			case 'nchar':
				$type = 'Text';
				break;

			case 'date':
			case 'datetime':
			case 'time':
			case 'year':
			case 'timestamp':
			case 'timestamp without time zone':
			case 'timestamp with time zone':
				$type = 'Date';
				break;

			case 'tinyint':
			case 'smallint':
				$type = 'Boolean';
				break;

			default:
				$type = 'Number';
				break;
		}

		return $type;
	}
}
home/wuectly/www/libraries/regularlabs/helpers/field.php000060400000001070152456170730017535 0ustar00<?php
/**
 * @package         Regular Labs Library
 * @version         21.4.10972
 * 
 * @author          Peter van Westen <info@regularlabs.com>
 * @link            http://www.regularlabs.com
 * @copyright       Copyright © 2021 Regular Labs All Rights Reserved
 * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 */

/* @DEPRECATED */

defined('_JEXEC') or die;

if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php'))
{
	require_once JPATH_LIBRARIES . '/regularlabs/autoload.php';
}

class RLFormField
	extends \RegularLabs\Library\Field
{
}
home/wuectly/www/libraries/regularlabs/fields/field.php000060400000003262152456300760017344 0ustar00<?php
/**
 * @package         Regular Labs Library
 * @version         21.4.10972
 * 
 * @author          Peter van Westen <info@regularlabs.com>
 * @link            http://www.regularlabs.com
 * @copyright       Copyright © 2021 Regular Labs All Rights Reserved
 * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory as JFactory;
use Joomla\CMS\HTML\HTMLHelper as JHtml;
use Joomla\CMS\Language\Text as JText;

if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php'))
{
	return;
}

require_once JPATH_LIBRARIES . '/regularlabs/autoload.php';

class JFormFieldRL_Field extends \RegularLabs\Library\Field
{
	public $type = 'Field';

	protected function getInput()
	{
		$options = $this->getFields();

		return $this->selectListSimple($options, $this->name, $this->value, $this->id);
	}

	function getFields()
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT a.id, a.name, a.type, a.title')
			->from('#__fields AS a')
			->where('a.state = 1')
			->order('a.name');

		$db->setQuery($query);

		$fields = $db->loadObjectList();

		$options = [];

		$options[] = JHtml::_('select.option', '', '- ' . JText::_('RL_SELECT_FIELD') . ' -');

		foreach ($fields as &$field)
		{
			// Skip our own subfields type. We won't have subfields in subfields.
			if ($field->type == 'subfields' || $field->type == 'repeatable')
			{
				continue;
			}

			$options[] = JHtml::_('select.option', $field->name, ($field->title . ' (' . $field->type . ')'));
		}

		if ($this->get('show_custom'))
		{
			$options[] = JHtml::_('select.option', 'custom', '- ' . JText::_('RL_CUSTOM') . ' -');
		}

		return $options;
	}
}
home/wuectly/www/libraries/f0f/form/field.php000060400000001647152456530560015221 0ustar00<?php
/**
 * @package     FrameworkOnFramework
 * @subpackage  form
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// Protect from unauthorized access
defined('F0F_INCLUDED') or die;

/**
 * Generic interface that a F0F form field class must implement
 *
 * @package  FrameworkOnFramework
 * @since    2.0
 */
interface F0FFormField
{
	/**
	 * Get the rendering of this field type for static display, e.g. in a single
	 * item view (typically a "read" task).
	 *
	 * @return  string  The field HTML
	 *
	 * @since 2.0
	 */
	public function getStatic();

	/**
	 * Get the rendering of this field type for a repeatable (grid) display,
	 * e.g. in a view listing many item (typically a "browse" task)
	 *
	 * @return  string  The field HTML
	 *
	 * @since 2.0
	 */
	public function getRepeatable();
}
home/wuectly/www/administrator/components/com_fields/tables/field.php000060400000014153152456625330022246 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Fields Table
 *
 * @since  3.7.0
 */
class FieldsTableField extends JTable
{
	/**
	 * Class constructor.
	 *
	 * @param   JDatabaseDriver  $db  JDatabaseDriver object.
	 *
	 * @since   3.7.0
	 */
	public function __construct($db = null)
	{
		parent::__construct('#__fields', 'id', $db);

		$this->setColumnAlias('published', 'state');
	}

	/**
	 * Method to bind an associative array or object to the JTable instance.This
	 * method only binds properties that are publicly accessible and optionally
	 * takes an array of properties to ignore when binding.
	 *
	 * @param   mixed  $src     An associative array or object to bind to the JTable instance.
	 * @param   mixed  $ignore  An optional array or space separated list of properties to ignore while binding.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.7.0
	 * @throws  InvalidArgumentException
	 */
	public function bind($src, $ignore = '')
	{
		if (isset($src['params']) && is_array($src['params']))
		{
			$registry = new Registry;
			$registry->loadArray($src['params']);
			$src['params'] = (string) $registry;
		}

		if (isset($src['fieldparams']) && is_array($src['fieldparams']))
		{
			$registry = new Registry;
			$registry->loadArray($src['fieldparams']);
			$src['fieldparams'] = (string) $registry;
		}

		// Bind the rules.
		if (isset($src['rules']) && is_array($src['rules']))
		{
			$rules = new JAccessRules($src['rules']);
			$this->setRules($rules);
		}

		return parent::bind($src, $ignore);
	}

	/**
	 * Method to perform sanity checks on the JTable instance properties to ensure
	 * they are safe to store in the database.  Child classes should override this
	 * method to make sure the data they are storing in the database is safe and
	 * as expected before storage.
	 *
	 * @return  boolean  True if the instance is sane and able to be stored in the database.
	 *
	 * @link    https://docs.joomla.org/Special:MyLanguage/JTable/check
	 * @since   3.7.0
	 */
	public function check()
	{
		// Check for valid name
		if (trim($this->title) == '')
		{
			$this->setError(JText::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD'));

			return false;
		}

		if (empty($this->name))
		{
			$this->name = $this->title;
		}

		$this->name = JApplicationHelper::stringURLSafe($this->name, $this->language);

		if (trim(str_replace('-', '', $this->name)) == '')
		{
			$this->name = Joomla\String\StringHelper::increment($this->name, 'dash');
		}

		$this->name = str_replace(',', '-', $this->name);

		// Verify that the name is unique
		$table = JTable::getInstance('Field', 'FieldsTable', array('dbo' => $this->_db));

		if ($table->load(array('name' => $this->name)) && ($table->id != $this->id || $this->id == 0))
		{
			$this->setError(JText::_('COM_FIELDS_ERROR_UNIQUE_NAME'));

			return false;
		}

		$this->name = str_replace(',', '-', $this->name);

		if (empty($this->type))
		{
			$this->type = 'text';
		}

		$date = JFactory::getDate();
		$user = JFactory::getUser();

		if ($this->id)
		{
			// Existing item
			$this->modified_time = $date->toSql();
			$this->modified_by = $user->get('id');
		}
		else
		{
			if (!(int) $this->created_time)
			{
				$this->created_time = $date->toSql();
			}

			if (empty($this->created_user_id))
			{
				$this->created_user_id = $user->get('id');
			}
		}

		if (empty($this->group_id))
		{
			$this->group_id = 0;
		}

		return true;
	}

	/**
	 * Method to compute the default name of the asset.
	 * The default name is in the form table_name.id
	 * where id is the value of the primary key of the table.
	 *
	 * @return  string
	 *
	 * @since   3.7.0
	 */
	protected function _getAssetName()
	{
		$contextArray = explode('.', $this->context);

		return $contextArray[0] . '.field.' . (int) $this->id;
	}

	/**
	 * Method to return the title to use for the asset table.  In
	 * tracking the assets a title is kept for each asset so that there is some
	 * context available in a unified access manager.  Usually this would just
	 * return $this->title or $this->name or whatever is being used for the
	 * primary name of the row. If this method is not overridden, the asset name is used.
	 *
	 * @return  string  The string to use as the title in the asset table.
	 *
	 * @link    https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle
	 * @since   3.7.0
	 */
	protected function _getAssetTitle()
	{
		return $this->title;
	}

	/**
	 * Method to get the parent asset under which to register this one.
	 * By default, all assets are registered to the ROOT node with ID,
	 * which will default to 1 if none exists.
	 * The extended class can define a table and id to lookup.  If the
	 * asset does not exist it will be created.
	 *
	 * @param   JTable   $table  A JTable object for the asset parent.
	 * @param   integer  $id     Id to look up
	 *
	 * @return  integer
	 *
	 * @since   3.7.0
	 */
	protected function _getAssetParentId(JTable $table = null, $id = null)
	{
		$contextArray = explode('.', $this->context);
		$component = $contextArray[0];

		if ($this->group_id)
		{
			$assetId = $this->getAssetId($component . '.fieldgroup.' . (int) $this->group_id);

			if ($assetId)
			{
				return $assetId;
			}
		}
		else
		{
			$assetId = $this->getAssetId($component);

			if ($assetId)
			{
				return $assetId;
			}
		}

		return parent::_getAssetParentId($table, $id);
	}

	/**
	 * Returns an asset id for the given name or false.
	 *
	 * @param   string  $name  The asset name
	 *
	 * @return  number|boolean
	 *
	 * @since    3.7.0
	 */
	private function getAssetId($name)
	{
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('id'))
			->from($db->quoteName('#__assets'))
			->where($db->quoteName('name') . ' = ' . $db->quote($name));

		// Get the asset id from the database.
		$db->setQuery($query);

		$assetId = null;

		if ($result = $db->loadResult())
		{
			$assetId = (int) $result;

			if ($assetId)
			{
				return $assetId;
			}
		}

		return false;
	}
}
home/wuectly/www/administrator/components/com_fields/models/field.php000060400000067254152457411470022270 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;

/**
 * Field Model
 *
 * @since  3.7.0
 */
class FieldsModelField extends JModelAdmin
{
	/**
	 * @var null|string
	 *
	 * @since   3.7.0
	 */
	public $typeAlias = null;

	/**
	 * @var string
	 *
	 * @since   3.7.0
	 */
	protected $text_prefix = 'COM_FIELDS';

	/**
	 * Batch copy/move command. If set to false,
	 * the batch copy/move command is not supported
	 *
	 * @var    string
	 * @since  3.4
	 */
	protected $batch_copymove = 'group_id';

	/**
	 * Allowed batch commands
	 *
	 * @var array
	 */
	protected $batch_commands = array(
		'assetgroup_id' => 'batchAccess',
		'language_id'   => 'batchLanguage'
	);

	/**
	 * @var array
	 *
	 * @since   3.7.0
	 */
	private $valueCache = array();

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration settings.
	 *
	 * @see     JModelLegacy
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);

		$this->typeAlias = JFactory::getApplication()->input->getCmd('context', 'com_content.article') . '.field';
	}

	/**
	 * Method to save the form data.
	 *
	 * @param   array  $data  The form data.
	 *
	 * @return  boolean  True on success, False on error.
	 *
	 * @since   3.7.0
	 */
	public function save($data)
	{
		$field = null;

		if (isset($data['id']) && $data['id'])
		{
			$field = $this->getItem($data['id']);
		}

		if (!isset($data['label']) && isset($data['params']['label']))
		{
			$data['label'] = $data['params']['label'];

			unset($data['params']['label']);
		}

		// Alter the title for save as copy
		$input = JFactory::getApplication()->input;

		if ($input->get('task') == 'save2copy')
		{
			$origTable = clone $this->getTable();
			$origTable->load($input->getInt('id'));

			if ($data['title'] == $origTable->title)
			{
				list($title, $name) = $this->generateNewTitle($data['group_id'], $data['name'], $data['title']);
				$data['title'] = $title;
				$data['label'] = $title;
				$data['name'] = $name;
			}
			else
			{
				if ($data['name'] == $origTable->name)
				{
					$data['name'] = '';
				}
			}

			$data['state'] = 0;
		}

		// Load the fields plugins, perhaps they want to do something
		JPluginHelper::importPlugin('fields');

		$message = $this->checkDefaultValue($data);

		if ($message !== true)
		{
			$this->setError($message);

			return false;
		}

		if (!parent::save($data))
		{
			return false;
		}

		// Save the assigned categories into #__fields_categories
		$db = $this->getDbo();
		$id = (int) $this->getState('field.id');
		$cats = isset($data['assigned_cat_ids']) ? (array) $data['assigned_cat_ids'] : array();
		$cats = ArrayHelper::toInteger($cats);

		$assignedCatIds = array();

		foreach ($cats as $cat)
		{
			if ($cat)
			{
				$assignedCatIds[] = $cat;
			}
		}

		// First delete all assigned categories
		$query = $db->getQuery(true);
		$query->delete('#__fields_categories')
			->where('field_id = ' . $id);
		$db->setQuery($query);
		$db->execute();

		// Inset new assigned categories
		$tupel = new stdClass;
		$tupel->field_id = $id;

		foreach ($assignedCatIds as $catId)
		{
			$tupel->category_id = $catId;
			$db->insertObject('#__fields_categories', $tupel);
		}

		// If the options have changed delete the values
		if ($field && isset($data['fieldparams']['options']) && isset($field->fieldparams['options']))
		{
			$oldParams = $this->getParams($field->fieldparams['options']);
			$newParams = $this->getParams($data['fieldparams']['options']);

			if (is_object($oldParams) && is_object($newParams) && $oldParams != $newParams)
			{
				$names = array();

				foreach ($newParams as $param)
				{
					$names[] = $db->q($param['value']);
				}

				$query = $db->getQuery(true);
				$query->delete('#__fields_values')->where('field_id = ' . (int) $field->id);

				// If new values are set, delete only old values. Otherwise delete all values.
				if ($names)
				{
					$query->where('value NOT IN (' . implode(',', $names) . ')');
				}

				$db->setQuery($query);
				$db->execute();
			}
		}

		FieldsHelper::clearFieldsCache();

		return true;
	}


	/**
	 * Checks if the default value is valid for the given data. If a string is returned then
	 * it can be assumed that the default value is invalid.
	 *
	 * @param   array  $data  The data.
	 *
	 * @return  true|string  true if valid, a string containing the exception message when not.
	 *
	 * @since   3.7.0
	 */
	private function checkDefaultValue($data)
	{
		// Empty default values are correct
		if (empty($data['default_value']) && $data['default_value'] !== '0')
		{
			return true;
		}

		$types = FieldsHelper::getFieldTypes();

		// Check if type exists
		if (!key_exists($data['type'], $types))
		{
			return true;
		}

		$path = $types[$data['type']]['rules'];

		// Add the path for the rules of the plugin when available
		if ($path)
		{
			// Add the lookup path for the rule
			JFormHelper::addRulePath($path);
		}

		// Create the fields object
		$obj              = (object) $data;
		$obj->params      = new Registry($obj->params);
		$obj->fieldparams = new Registry(!empty($obj->fieldparams) ? $obj->fieldparams : array());

		// Prepare the dom
		$dom  = new DOMDocument;
		$node = $dom->appendChild(new DOMElement('form'));

		// Trigger the event to create the field dom node
		JEventDispatcher::getInstance()->trigger('onCustomFieldsPrepareDom', array($obj, $node, new JForm($data['context'])));

		// Check if a node is created
		if (!$node->firstChild)
		{
			return true;
		}

		// Define the type either from the field or from the data
		$type = $node->firstChild->getAttribute('validate') ? : $data['type'];

		// Load the rule
		$rule = JFormHelper::loadRuleType($type);

		// When no rule exists, we allow the default value
		if (!$rule)
		{
			return true;
		}

		try
		{
			// Perform the check
			$result = $rule->test(simplexml_import_dom($node->firstChild), $data['default_value']);

			// Check if the test succeeded
			return $result === true ? : JText::_('COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE');
		}
		catch (UnexpectedValueException $e)
		{
			return $e->getMessage();
		}
	}

	/**
	 * Converts the unknown params into an object.
	 *
	 * @param   mixed  $params  The params.
	 *
	 * @return  stdClass  Object on success, false on failure.
	 *
	 * @since   3.7.0
	 */
	private function getParams($params)
	{
		if (is_string($params))
		{
			$params = json_decode($params);
		}

		if (is_array($params))
		{
			$params = (object) $params;
		}

		return $params;
	}

	/**
	 * Method to get a single record.
	 *
	 * @param   integer  $pk  The id of the primary key.
	 *
	 * @return  mixed    Object on success, false on failure.
	 *
	 * @since   3.7.0
	 */
	public function getItem($pk = null)
	{
		$result = parent::getItem($pk);

		if ($result)
		{
			// Prime required properties.
			if (empty($result->id))
			{
				$result->context = JFactory::getApplication()->input->getCmd('context', $this->getState('field.context'));
			}

			if (property_exists($result, 'fieldparams') && $result->fieldparams !== null)
			{
				$registry = new Registry;
				$registry->loadString($result->fieldparams);
				$result->fieldparams = $registry->toArray();
			}

			$db = $this->getDbo();
			$query = $db->getQuery(true);
			$query->select('category_id')
				->from('#__fields_categories')
				->where('field_id = ' . (int) $result->id);

			$db->setQuery($query);
			$result->assigned_cat_ids = $db->loadColumn() ?: array(0);
		}

		return $result;
	}

	/**
	 * Method to get a table object, load it if necessary.
	 *
	 * @param   string  $name     The table name. Optional.
	 * @param   string  $prefix   The class prefix. Optional.
	 * @param   array   $options  Configuration array for model. Optional.
	 *
	 * @return  JTable  A JTable object
	 *
	 * @since   3.7.0
	 * @throws  Exception
	 */
	public function getTable($name = 'Field', $prefix = 'FieldsTable', $options = array())
	{
		if (strpos(JPATH_COMPONENT, 'com_fields') === false)
		{
			$this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables');
		}

		// Default to text type
		$table       = JTable::getInstance($name, $prefix, $options);
		$table->type = 'text';

		return $table;
	}

	/**
	 * Method to change the title & name.
	 *
	 * @param   integer  $categoryId  The id of the category.
	 * @param   string   $name        The name.
	 * @param   string   $title       The title.
	 *
	 * @return  array  Contains the modified title and name.
	 *
	 * @since    3.7.0
	 */
	protected function generateNewTitle($categoryId, $name, $title)
	{
		// Alter the title & name
		$table = $this->getTable();

		while ($table->load(array('name' => $name)))
		{
			$title = StringHelper::increment($title);
			$name = StringHelper::increment($name, 'dash');
		}

		return array(
			$title,
			$name,
		);
	}

	/**
	 * Method to delete one or more records.
	 *
	 * @param   array  $pks  An array of record primary keys.
	 *
	 * @return  boolean  True if successful, false if an error occurs.
	 *
	 * @since   3.7.0
	 */
	public function delete(&$pks)
	{
		$success = parent::delete($pks);

		if ($success)
		{
			$pks = (array) $pks;
			$pks = ArrayHelper::toInteger($pks);
			$pks = array_filter($pks);

			if (!empty($pks))
			{
				// Delete Values
				$query = $this->getDbo()->getQuery(true);

				$query->delete($query->qn('#__fields_values'))
					->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')');

				$this->getDbo()->setQuery($query)->execute();

				// Delete Assigned Categories
				$query = $this->getDbo()->getQuery(true);

				$query->delete($query->qn('#__fields_categories'))
					->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')');

				$this->getDbo()->setQuery($query)->execute();
			}
		}

		return $success;
	}

	/**
	 * Abstract method for getting the form from the model.
	 *
	 * @param   array    $data      Data for the form.
	 * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
	 *
	 * @return  mixed  A JForm object on success, false on failure
	 *
	 * @since   3.7.0
	 */
	public function getForm($data = array(), $loadData = true)
	{
		$context = $this->getState('field.context');
		$jinput  = JFactory::getApplication()->input;

		// A workaround to get the context into the model for save requests.
		if (empty($context) && isset($data['context']))
		{
			$context = $data['context'];
			$parts   = FieldsHelper::extract($context);

			$this->setState('field.context', $context);

			if ($parts)
			{
				$this->setState('field.component', $parts[0]);
				$this->setState('field.section', $parts[1]);
			}
		}

		if (isset($data['type']))
		{
			// This is needed that the plugins can determine the type
			$this->setState('field.type', $data['type']);
		}

		// Load the fields plugin that they can add additional parameters to the form
		JPluginHelper::importPlugin('fields');

		// Get the form.
		$form = $this->loadForm(
			'com_fields.field.' . $context, 'field',
			array(
				'control'   => 'jform',
				'load_data' => true,
			)
		);

		if (empty($form))
		{
			return false;
		}

		// Modify the form based on Edit State access controls.
		if (empty($data['context']))
		{
			$data['context'] = $context;
		}

		$fieldId  = $jinput->get('id');
		$assetKey = $this->state->get('field.component') . '.field.' . $fieldId;

		if (!JFactory::getUser()->authorise('core.edit.state', $assetKey))
		{
			// Disable fields for display.
			$form->setFieldAttribute('ordering', 'disabled', 'true');
			$form->setFieldAttribute('state', 'disabled', 'true');

			// Disable fields while saving. The controller has already verified this is a record you can edit.
			$form->setFieldAttribute('ordering', 'filter', 'unset');
			$form->setFieldAttribute('state', 'filter', 'unset');
		}

		return $form;
	}

	/**
	 * Setting the value for the given field id, context and item id.
	 *
	 * @param   string  $fieldId  The field ID.
	 * @param   string  $itemId   The ID of the item.
	 * @param   string  $value    The value.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	public function setFieldValue($fieldId, $itemId, $value)
	{
		$field  = $this->getItem($fieldId);
		$params = $field->params;

		if (is_array($params))
		{
			$params = new Registry($params);
		}

		// Don't save the value when the user is not authorized to change it
		if (!$field || !FieldsHelper::canEditFieldValue($field))
		{
			return false;
		}

		$needsDelete = false;
		$needsInsert = false;
		$needsUpdate = false;

		$oldValue = $this->getFieldValue($fieldId, $itemId);
		$value    = (array) $value;

		if ($oldValue === null)
		{
			// No records available, doing normal insert
			$needsInsert = true;
		}
		elseif (count($value) == 1 && count((array) $oldValue) == 1)
		{
			// Only a single row value update can be done when not empty
			$needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]);
			$needsDelete = !$needsUpdate;
		}
		else
		{
			// Multiple values, we need to purge the data and do a new
			// insert
			$needsDelete = true;
			$needsInsert = true;
		}

		if ($needsDelete)
		{
			// Deleting the existing record as it is a reset
			$query = $this->getDbo()->getQuery(true);

			$query->delete($query->qn('#__fields_values'))
				->where($query->qn('field_id') . ' = ' . (int) $fieldId)
				->where($query->qn('item_id') . ' = ' . $query->q($itemId));

			$this->getDbo()->setQuery($query)->execute();
		}

		if ($needsInsert)
		{
			$newObj = new stdClass;

			$newObj->field_id = (int) $fieldId;
			$newObj->item_id  = $itemId;

			foreach ($value as $v)
			{
				$newObj->value = $v;

				$this->getDbo()->insertObject('#__fields_values', $newObj);
			}
		}

		if ($needsUpdate)
		{
			$updateObj = new stdClass;

			$updateObj->field_id = (int) $fieldId;
			$updateObj->item_id  = $itemId;
			$updateObj->value    = reset($value);

			$this->getDbo()->updateObject('#__fields_values', $updateObj, array('field_id', 'item_id'));
		}

		$this->valueCache = array();
		FieldsHelper::clearFieldsCache();

		return true;
	}

	/**
	 * Returning the value for the given field id, context and item id.
	 *
	 * @param   string  $fieldId  The field ID.
	 * @param   string  $itemId   The ID of the item.
	 *
	 * @return  NULL|string
	 *
	 * @since  3.7.0
	 */
	public function getFieldValue($fieldId, $itemId)
	{
		$values = $this->getFieldValues(array($fieldId), $itemId);

		if (key_exists($fieldId, $values))
		{
			return $values[$fieldId];
		}

		return null;
	}

	/**
	 * Returning the values for the given field ids, context and item id.
	 *
	 * @param   array   $fieldIds  The field Ids.
	 * @param   string  $itemId    The ID of the item.
	 *
	 * @return  NULL|array
	 *
	 * @since  3.7.0
	 */
	public function getFieldValues(array $fieldIds, $itemId)
	{
		if (!$fieldIds)
		{
			return array();
		}

		// Create a unique key for the cache
		$key = md5(serialize($fieldIds) . $itemId);

		// Fill the cache when it doesn't exist
		if (!key_exists($key, $this->valueCache))
		{
			// Create the query
			$query = $this->getDbo()->getQuery(true);

			$query->select(array($query->qn('field_id'), $query->qn('value')))
				->from($query->qn('#__fields_values'))
				->where($query->qn('field_id') . ' IN (' . implode(',', ArrayHelper::toInteger($fieldIds)) . ')')
				->where($query->qn('item_id') . ' = ' . $query->q($itemId));

			// Fetch the row from the database
			$rows = $this->getDbo()->setQuery($query)->loadObjectList();

			$data = array();

			// Fill the data container from the database rows
			foreach ($rows as $row)
			{
				// If there are multiple values for a field, create an array
				if (key_exists($row->field_id, $data))
				{
					// Transform it to an array
					if (!is_array($data[$row->field_id]))
					{
						$data[$row->field_id] = array($data[$row->field_id]);
					}

					// Set the value in the array
					$data[$row->field_id][] = $row->value;

					// Go to the next row, otherwise the value gets overwritten in the data container
					continue;
				}

				// Set the value
				$data[$row->field_id] = $row->value;
			}

			// Assign it to the internal cache
			$this->valueCache[$key] = $data;
		}

		// Return the value from the cache
		return $this->valueCache[$key];
	}

	/**
	 * Cleaning up the values for the given item on the context.
	 *
	 * @param   string  $context  The context.
	 * @param   string  $itemId   The Item ID.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	public function cleanupValues($context, $itemId)
	{
		// Delete with inner join is not possible so we need to do a subquery
		$fieldsQuery = $this->getDbo()->getQuery(true);
		$fieldsQuery->select($fieldsQuery->qn('id'))
			->from($fieldsQuery->qn('#__fields'))
			->where($fieldsQuery->qn('context') . ' = ' . $fieldsQuery->q($context));

		$query = $this->getDbo()->getQuery(true);

		$query->delete($query->qn('#__fields_values'))
			->where($query->qn('field_id') . ' IN (' . $fieldsQuery . ')')
			->where($query->qn('item_id') . ' = ' . $query->q($itemId));

		$this->getDbo()->setQuery($query)->execute();
	}

	/**
	 * Method to test whether a record can be deleted.
	 *
	 * @param   object  $record  A record object.
	 *
	 * @return  boolean  True if allowed to delete the record. Defaults to the permission for the component.
	 *
	 * @since   3.7.0
	 */
	protected function canDelete($record)
	{
		if (empty($record->id) || $record->state != -2)
		{
			return false;
		}

		$parts = FieldsHelper::extract($record->context);

		return JFactory::getUser()->authorise('core.delete', $parts[0] . '.field.' . (int) $record->id);
	}

	/**
	 * Method to test whether a record can have its state changed.
	 *
	 * @param   object  $record  A record object.
	 *
	 * @return  boolean  True if allowed to change the state of the record. Defaults to the permission for the
	 *                   component.
	 *
	 * @since   3.7.0
	 */
	protected function canEditState($record)
	{
		$user  = JFactory::getUser();
		$parts = FieldsHelper::extract($record->context);

		// Check for existing field.
		if (!empty($record->id))
		{
			return $user->authorise('core.edit.state', $parts[0] . '.field.' . (int) $record->id);
		}

		return $user->authorise('core.edit.state', $parts[0]);
	}

	/**
	 * Stock method to auto-populate the model state.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function populateState()
	{
		$app = JFactory::getApplication('administrator');

		// Load the User state.
		$pk = $app->input->getInt('id');
		$this->setState($this->getName() . '.id', $pk);

		$context = $app->input->get('context', 'com_content.article');
		$this->setState('field.context', $context);
		$parts = FieldsHelper::extract($context);

		// Extract the component name
		$this->setState('field.component', $parts[0]);

		// Extract the optional section name
		$this->setState('field.section', (count($parts) > 1) ? $parts[1] : null);

		// Load the parameters.
		$params = JComponentHelper::getParams('com_fields');
		$this->setState('params', $params);
	}

	/**
	 * A protected method to get a set of ordering conditions.
	 *
	 * @param   JTable  $table  A JTable object.
	 *
	 * @return  array  An array of conditions to add to ordering queries.
	 *
	 * @since   3.7.0
	 */
	protected function getReorderConditions($table)
	{
		return 'context = ' . $this->_db->quote($table->context);
	}

	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  array  The default data is an empty array.
	 *
	 * @since   3.7.0
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$app  = JFactory::getApplication();
		$data = $app->getUserState('com_fields.edit.field.data', array());

		if (empty($data))
		{
			$data = $this->getItem();

			// Pre-select some filters (Status, Language, Access) in edit form
			// if those have been selected in Category Manager
			if (!$data->id)
			{
				// Check for which context the Category Manager is used and
				// get selected fields
				$filters = (array) $app->getUserState('com_fields.fields.filter');

				$data->set('state', $app->input->getInt('state', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null)));
				$data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null)));
				$data->set('group_id', $app->input->getString('group_id', (!empty($filters['group_id']) ? $filters['group_id'] : null)));
				$data->set(
					'access',
					$app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access')))
				);

				// Set the type if available from the request
				$data->set('type', $app->input->getWord('type', $this->state->get('field.type', $data->get('type'))));
			}

			if ($data->label && !isset($data->params['label']))
			{
				$data->params['label'] = $data->label;
			}
		}

		$this->preprocessData('com_fields.field', $data);

		return $data;
	}

	/**
	 * Method to validate the form data.
	 *
	 * @param   JForm   $form   The form to validate against.
	 * @param   array   $data   The data to validate.
	 * @param   string  $group  The name of the field group to validate.
	 *
	 * @return  array|boolean  Array of filtered data if valid, false otherwise.
	 *
	 * @see     JFormRule
	 * @see     JFilterInput
	 * @since   3.9.23
	 */
	public function validate($form, $data, $group = null)
	{
		// Don't allow to change the users if not allowed to access com_users.
		if (!JFactory::getUser()->authorise('core.manage', 'com_users'))
		{
			if (isset($data['created_user_id']))
			{
				unset($data['created_user_id']);
			}
		}

		if (!JFactory::getUser()->authorise('core.admin', 'com_fields'))
		{
			if (isset($data['rules']))
			{
				unset($data['rules']);
			}
		}

		return parent::validate($form, $data, $group);
	}

	/**
	 * Method to allow derived classes to preprocess the form.
	 *
	 * @param   JForm   $form   A JForm object.
	 * @param   mixed   $data   The data expected for the form.
	 * @param   string  $group  The name of the plugin group to import (defaults to "content").
	 *
	 * @return  void
	 *
	 * @see     JFormField
	 * @since   3.7.0
	 * @throws  Exception if there is an error in the form event.
	 */
	protected function preprocessForm(JForm $form, $data, $group = 'content')
	{
		$component  = $this->state->get('field.component');
		$section    = $this->state->get('field.section');
		$dataObject = $data;

		if (is_array($dataObject))
		{
			$dataObject = (object) $dataObject;
		}

		if (isset($dataObject->type))
		{
			$form->setFieldAttribute('type', 'component', $component);

			// Not allowed to change the type of an existing record
			if ($dataObject->id)
			{
				$form->setFieldAttribute('type', 'readonly', 'true');
			}

			// Allow to override the default value label and description through the plugin
			$key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_LABEL';

			if (JFactory::getLanguage()->hasKey($key))
			{
				$form->setFieldAttribute('default_value', 'label', $key);
			}

			$key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_DESC';

			if (JFactory::getLanguage()->hasKey($key))
			{
				$form->setFieldAttribute('default_value', 'description', $key);
			}

			// Remove placeholder field on list fields
			if ($dataObject->type == 'list')
			{
				$form->removeField('hint', 'params');
			}
		}

		// Setting the context for the category field
		$cat = JCategories::getInstance(str_replace('com_', '', $component) . '.' . $section);

		// If there is no category for the component and section, so check the component only
		if (!$cat)
		{
			$cat = JCategories::getInstance(str_replace('com_', '', $component));
		}

		if ($cat && $cat->get('root')->hasChildren())
		{
			$form->setFieldAttribute('assigned_cat_ids', 'extension', $cat->getExtension());
		}
		else
		{
			$form->removeField('assigned_cat_ids');
		}

		$form->setFieldAttribute('type', 'component', $component);
		$form->setFieldAttribute('group_id', 'context', $this->state->get('field.context'));
		$form->setFieldAttribute('rules', 'component', $component);

		// Looking first in the component models/forms folder
		$path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fields/' . $section . '.xml');

		if (file_exists($path))
		{
			$lang = JFactory::getLanguage();
			$lang->load($component, JPATH_BASE, null, false, true);
			$lang->load($component, JPATH_BASE . '/components/' . $component, null, false, true);

			if (!$form->loadFile($path, false))
			{
				throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
			}
		}

		// Trigger the default form events.
		parent::preprocessForm($form, $data, $group);
	}

	/**
	 * Clean the cache
	 *
	 * @param   string   $group     The cache group
	 * @param   integer  $clientId  The ID of the client
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function cleanCache($group = null, $clientId = 0)
	{
		$context = JFactory::getApplication()->input->get('context');

		switch ($context)
		{
			case 'com_content':
				parent::cleanCache('com_content');
				parent::cleanCache('mod_articles_archive');
				parent::cleanCache('mod_articles_categories');
				parent::cleanCache('mod_articles_category');
				parent::cleanCache('mod_articles_latest');
				parent::cleanCache('mod_articles_news');
				parent::cleanCache('mod_articles_popular');
				break;
			default:
				parent::cleanCache($context);
				break;
		}
	}

	/**
	 * Batch copy fields to a new group.
	 *
	 * @param   integer  $value     The new value matching a fields group.
	 * @param   array    $pks       An array of row IDs.
	 * @param   array    $contexts  An array of item contexts.
	 *
	 * @return  array|boolean  new IDs if successful, false otherwise and internal error is set.
	 *
	 * @since   3.7.0
	 */
	protected function batchCopy($value, $pks, $contexts)
	{
		// Set the variables
		$user      = JFactory::getUser();
		$table     = $this->getTable();
		$newIds    = array();
		$component = $this->state->get('filter.component');
		$value     = (int) $value;

		foreach ($pks as $pk)
		{
			if ($user->authorise('core.create', $component . '.fieldgroup.' . $value))
			{
				$table->reset();
				$table->load($pk);

				$table->group_id = $value;

				// Reset the ID because we are making a copy
				$table->id = 0;

				// Unpublish the new field
				$table->state = 0;

				if (!$table->store())
				{
					$this->setError($table->getError());

					return false;
				}

				// Get the new item ID
				$newId = $table->get('id');

				// Add the new ID to the array
				$newIds[$pk] = $newId;
			}
			else
			{
				$this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE'));

				return false;
			}
		}

		// Clean the cache
		$this->cleanCache();

		return $newIds;
	}

	/**
	 * Batch move fields to a new group.
	 *
	 * @param   integer  $value     The new value matching a fields group.
	 * @param   array    $pks       An array of row IDs.
	 * @param   array    $contexts  An array of item contexts.
	 *
	 * @return  boolean  True if successful, false otherwise and internal error is set.
	 *
	 * @since   3.7.0
	 */
	protected function batchMove($value, $pks, $contexts)
	{
		// Set the variables
		$user      = JFactory::getUser();
		$table     = $this->getTable();
		$context   = explode('.', JFactory::getApplication()->getUserState('com_fields.fields.context'));
		$value     = (int) $value;

		foreach ($pks as $pk)
		{
			if ($user->authorise('core.edit', $context[0] . '.fieldgroup.' . $value))
			{
				$table->reset();
				$table->load($pk);

				$table->group_id = $value;

				if (!$table->store())
				{
					$this->setError($table->getError());

					return false;
				}
			}
			else
			{
				$this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT'));

				return false;
			}
		}

		// Clean the cache
		$this->cleanCache();

		return true;
	}
}