Spade

Mini Shell

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

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

js/admin-fields-modal.js000064400000002232151165235240011147 0ustar00/**
 * @copyright  Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license    GNU General Public License version 2 or later; see
LICENSE.txt
 */

Joomla = window.Joomla || {};

(function(Joomla) {
	Joomla.fieldIns = function(id, editor) {
		/** Use the API, if editor supports it **/
		if (window.parent.Joomla && window.parent.Joomla.editors
&& window.parent.Joomla.editors.instances &&
window.parent.Joomla.editors.instances.hasOwnProperty(editor)) {
			window.parent.Joomla.editors.instances[editor].replaceSelection("{field
" + id + "}")
		} else {
			window.parent.jInsertEditorText("{field " + id +
"}", editor);
		}

		window.parent.jModalClose();
	};

	Joomla.fieldgroupIns = function(id, editor) {
		/** Use the API, if editor supports it **/
		if (window.parent.Joomla && window.parent.Joomla.editors
&& window.parent.Joomla.editors.instances &&
window.parent.Joomla.editors.instances.hasOwnProperty(editor)) {
			window.parent.Joomla.editors.instances[editor].replaceSelection("{fieldgroup
" + id + "}")
		} else {
			window.parent.jInsertEditorText("{fieldgroup " + id +
"}", editor);
		}

		window.parent.jModalClose();
	};
})(Joomla);
js/admin-fields-modal.min.js000064400000001321151165235240011727
0ustar00Joomla=window.Joomla||{},function(a){a.fieldIns=function(a,b){window.parent.Joomla&&window.parent.Joomla.editors&&window.parent.Joomla.editors.instances&&window.parent.Joomla.editors.instances.hasOwnProperty(b)?window.parent.Joomla.editors.instances[b].replaceSelection("{field
"+a+"}"):window.parent.jInsertEditorText("{field
"+a+"}",b),window.parent.jModalClose()},a.fieldgroupIns=function(a,b){window.parent.Joomla&&window.parent.Joomla.editors&&window.parent.Joomla.editors.instances&&window.parent.Joomla.editors.instances.hasOwnProperty(b)?window.parent.Joomla.editors.instances[b].replaceSelection("{fieldgroup
"+a+"}"):window.parent.jInsertEditorText("{fieldgroup
"+a+"}",b),window.parent.jModalClose()}}(Joomla);controller.php000064400000002245151165264730007455
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Base controller class for Fields Component.
 *
 * @since  3.7.0
 */
class FieldsController extends JControllerLegacy
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *                          Recognized key values include
'name', 'default_task', 'model_path', and
	 *                          'view_path' (this list is not meant
to be comprehensive).
	 *
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		$this->input = JFactory::getApplication()->input;

		// Frontpage Editor Fields Button proxying:
		if ($this->input->get('view') === 'fields'
&& $this->input->get('layout') ===
'modal')
		{
			// Load the backend language file.
			$lang = JFactory::getLanguage();
			$lang->load('com_fields', JPATH_ADMINISTRATOR);

			$config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR;
		}

		parent::__construct($config);
	}
}
fields.php000064400000002006151165264730006533 0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR .
'/components/com_fields/helpers/fields.php');

$input   = JFactory::getApplication()->input;
$context =
JFactory::getApplication()->getUserStateFromRequest('com_fields.fields.context',
'context', 'com_content.article', 'CMD');
$parts   = FieldsHelper::extract($context);

if ($input->get('view') === 'fields' &&
$input->get('layout') === 'modal')
{
	if (!JFactory::getUser()->authorise('core.create', $parts[0])
		|| !JFactory::getUser()->authorise('core.edit', $parts[0]))
	{
		JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'),
'error');

		return;
	}
}

$controller = JControllerLegacy::getInstance('Fields');
$controller->execute($input->get('task'));
$controller->redirect();
layouts/field/render.php000064400000001423151165264730011331
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

if (!key_exists('field', $displayData))
{
	return;
}

$field = $displayData['field'];
$label = JText::_($field->label);
$value = $field->value;
$showLabel = $field->params->get('showlabel');
$labelClass = $field->params->get('label_render_class');

if ($value == '')
{
	return;
}

?>
<?php if ($showLabel == 1) : ?>
	<span class="field-label <?php echo $labelClass;
?>"><?php echo htmlentities($label, ENT_QUOTES | ENT_IGNORE,
'UTF-8'); ?>: </span>
<?php endif; ?>
<span class="field-value"><?php echo $value;
?></span>
layouts/fields/render.php000064400000003030151165264730011510
0ustar00<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Check if we have all the data
if (!key_exists('item', $displayData) ||
!key_exists('context', $displayData))
{
	return;
}

// Setting up for display
$item = $displayData['item'];

if (!$item)
{
	return;
}

$context = $displayData['context'];

if (!$context)
{
	return;
}

JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR .
'/components/com_fields/helpers/fields.php');

$parts     = explode('.', $context);
$component = $parts[0];
$fields    = null;

if (key_exists('fields', $displayData))
{
	$fields = $displayData['fields'];
}
else
{
	$fields = $item->jcfields ?: FieldsHelper::getFields($context, $item,
true);
}

if (empty($fields))
{
	return;
}

$output = array();

foreach ($fields as $field)
{
	// If the value is empty do nothing
	if (!isset($field->value) || trim($field->value) === '')
	{
		continue;
	}

	$class = $field->params->get('render_class');
	$layout = $field->params->get('layout',
'render');
	$content = FieldsHelper::render($context, 'field.' . $layout,
array('field' => $field));

	// If the content is empty do nothing
	if (trim($content) === '') 
	{
		continue;
	}

	$output[] = '<dd class="field-entry ' . $class .
'">' . $content . '</dd>';
}

if (empty($output))
{
	return;
}

?>
<dl class="fields-container">
	<?php echo implode("\n", $output); ?>
</dl>
models/forms/filter_fields.xml000064400000005403151165264730012526
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="group"
		addfieldpath="/administrator/components/com_fields/models/fields">
		<field
			name="context"
			type="fieldcontexts"
			onchange="this.form.submit();"
		/>
	</fieldset>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label=""
			hint="JSEARCH_FILTER"
			class="js-stools-search-string"
		/>

		<field
			name="state"
			type="status"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
		</field>

		<field
			name="group_id"
			type="fieldgroups"
			state="0,1,2"
			onchange="this.form.submit();"
			>
			<option
value="">COM_FIELDS_VIEW_FIELDS_SELECT_GROUP</option>
		</field>

		<field
			name="assigned_cat_ids"
			type="category"
			onchange="this.form.submit();"
			>
			<option
value="">COM_FIELDS_VIEW_FIELDS_SELECT_CATEGORY</option>
		</field>

		<field
			name="access"
			type="accesslevel"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_ACCESS</option>
		</field>

		<field
			name="language"
			type="contentlanguage"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_LANGUAGE</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			statuses="*,0,1,2,-2"
			onchange="this.form.submit();"
			default="a.ordering ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.ordering
ASC">JGRID_HEADING_ORDERING_ASC</option>
			<option value="a.ordering
DESC">JGRID_HEADING_ORDERING_DESC</option>
			<option value="a.state ASC">JSTATUS_ASC</option>
			<option value="a.state DESC">JSTATUS_DESC</option>
			<option value="a.title
ASC">JGLOBAL_TITLE_ASC</option>
			<option value="a.title
DESC">JGLOBAL_TITLE_DESC</option>
			<option value="a.type
ASC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_ASC</option>
			<option value="a.type
DESC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_DESC</option>
			<option value="g.title
ASC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_ASC</option>
			<option value="g.title
DESC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_DESC</option>
			<option value="a.access
ASC">JGRID_HEADING_ACCESS_ASC</option>
			<option value="a.access
DESC">JGRID_HEADING_ACCESS_DESC</option>
			<option value="a.language
ASC">JGRID_HEADING_LANGUAGE_ASC</option>
			<option value="a.language
DESC">JGRID_HEADING_LANGUAGE_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			label="COM_FIELDS_LIST_LIMIT"
			description="COM_FIELDS_LIST_LIMIT_DESC"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
controllers/field.php000064400000010423151165643610010716 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * The Field controller
 *
 * @since  3.7.0
 */
class FieldsControllerField extends JControllerForm
{
	private $internalContext;

	private $component;

	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string

	 * @since   3.7.0
	 */
	protected $text_prefix = 'COM_FIELDS_FIELD';

	/**
	 * Class constructor.
	 *
	 * @param   array  $config  A named array of configuration variables.
	 *
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);

		$this->internalContext =
JFactory::getApplication()->getUserStateFromRequest('com_fields.fields.context',
'context', 'com_content.article', 'CMD');
		$parts = FieldsHelper::extract($this->internalContext);
		$this->component = $parts ? $parts[0] : null;
	}

	/**
	 * Method override to check if you can add a new record.
	 *
	 * @param   array  $data  An array of input data.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	protected function allowAdd($data = array())
	{
		return JFactory::getUser()->authorise('core.create',
$this->component);
	}

	/**
	 * Method override to check if you can edit an existing record.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	protected function allowEdit($data = array(), $key = 'id')
	{
		$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
		$user = JFactory::getUser();

		// Zero record (id:0), return component edit permission by calling parent
controller method
		if (!$recordId)
		{
			return parent::allowEdit($data, $key);
		}

		// Check edit on the record asset (explicit or inherited)
		if ($user->authorise('core.edit', $this->component .
'.field.' . $recordId))
		{
			return true;
		}

		// Check edit own on the record asset (explicit or inherited)
		if ($user->authorise('core.edit.own', $this->component .
'.field.' . $recordId))
		{
			// Existing record already has an owner, get it
			$record = $this->getModel()->getItem($recordId);

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

			// Grant if current user is owner of the record
			return $user->id == $record->created_by;
		}

		return false;
	}

	/**
	 * Method to run batch operations.
	 *
	 * @param   object  $model  The model.
	 *
	 * @return  boolean   True if successful, false otherwise and internal
error is set.
	 *
	 * @since   3.7.0
	 */
	public function batch($model = null)
	{
		$this->checkToken();

		// Set the model
		$model = $this->getModel('Field');

		// Preset the redirect
		$this->setRedirect('index.php?option=com_fields&view=fields&context='
. $this->internalContext);

		return parent::batch($model);
	}

	/**
	 * Gets the URL arguments to append to an item redirect.
	 *
	 * @param   integer  $recordId  The primary key id for the item.
	 * @param   string   $urlVar    The name of the URL variable for the id.
	 *
	 * @return  string  The arguments to append to the redirect URL.
	 *
	 * @since   3.7.0
	 */
	protected function getRedirectToItemAppend($recordId = null, $urlVar =
'id')
	{
		return parent::getRedirectToItemAppend($recordId) .
'&context=' . $this->internalContext;
	}

	/**
	 * Gets the URL arguments to append to a list redirect.
	 *
	 * @return  string  The arguments to append to the redirect URL.
	 *
	 * @since   3.7.0
	 */
	protected function getRedirectToListAppend()
	{
		return parent::getRedirectToListAppend() . '&context=' .
$this->internalContext;
	}

	/**
	 * Function that allows child controller access to model data after the
data has been saved.
	 *
	 * @param   JModelLegacy  $model      The data model object.
	 * @param   array         $validData  The validated data.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function postSaveHook(JModelLegacy $model, $validData = array())
	{
		$item = $model->getItem();

		if (isset($item->params) && is_array($item->params))
		{
			$registry = new Registry;
			$registry->loadArray($item->params);
			$item->params = (string) $registry;
		}

		return;
	}
}
controllers/fields.php000064400000001761151165643610011106 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Fields list controller class.
 *
 * @since  3.7.0
 */
class FieldsControllerFields extends JControllerAdmin
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string
	 *
	 * @since   3.7.0
	 */
	protected $text_prefix = 'COM_FIELDS_FIELD';

	/**
	 * Proxy for getModel.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  The array of possible config values.
Optional.
	 *
	 * @return  FieldsModelField|boolean
	 *
	 * @since   3.7.0
	 */
	public function getModel($name = 'Field', $prefix =
'FieldsModel', $config = array('ignore_request' =>
true))
	{
		return parent::getModel($name, $prefix, $config);
	}
}
controllers/group.php000064400000006777151165643610011010 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * The Group controller
 *
 * @since  3.7.0
 */
class FieldsControllerGroup extends JControllerForm
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string

	 * @since   3.7.0
	 */
	protected $text_prefix = 'COM_FIELDS_GROUP';

	/**
	 * The component for which the group applies.
	 *
	 * @var    string
	 * @since   3.7.0
	 */
	private $component = '';

	/**
	 * Class constructor.
	 *
	 * @param   array  $config  A named array of configuration variables.
	 *
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);

		$parts =
FieldsHelper::extract($this->input->getCmd('context'));

		if ($parts)
		{
			$this->component = $parts[0];
		}
	}

	/**
	 * Method to run batch operations.
	 *
	 * @param   object  $model  The model.
	 *
	 * @return  boolean   True if successful, false otherwise and internal
error is set.
	 *
	 * @since   3.7.0
	 */
	public function batch($model = null)
	{
		$this->checkToken();

		// Set the model
		$model = $this->getModel('Group');

		// Preset the redirect
		$this->setRedirect('index.php?option=com_fields&view=groups');

		return parent::batch($model);
	}

	/**
	 * Method override to check if you can add a new record.
	 *
	 * @param   array  $data  An array of input data.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	protected function allowAdd($data = array())
	{
		return JFactory::getUser()->authorise('core.create',
$this->component);
	}

	/**
	 * Method override to check if you can edit an existing record.
	 *
	 * @param   array   $data  An array of input data.
	 * @param   string  $key   The name of the key for the primary key.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	protected function allowEdit($data = array(), $key =
'parent_id')
	{
		$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
		$user = JFactory::getUser();

		// Zero record (parent_id:0), return component edit permission by calling
parent controller method
		if (!$recordId)
		{
			return parent::allowEdit($data, $key);
		}

		// Check edit on the record asset (explicit or inherited)
		if ($user->authorise('core.edit', $this->component .
'.fieldgroup.' . $recordId))
		{
			return true;
		}

		// Check edit own on the record asset (explicit or inherited)
		if ($user->authorise('core.edit.own', $this->component .
'.fieldgroup.' . $recordId) ||
$user->authorise('core.edit.own', $this->component))
		{
			// Existing record already has an owner, get it
			$record = $this->getModel()->getItem($recordId);

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

			// Grant if current user is owner of the record
			return $user->id == $record->created_by;
		}

		return false;
	}

	/**
	 * Function that allows child controller access to model data after the
data has been saved.
	 *
	 * @param   JModelLegacy  $model      The data model object.
	 * @param   array         $validData  The validated data.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function postSaveHook(JModelLegacy $model, $validData = array())
	{
		$item = $model->getItem();

		if (isset($item->params) && is_array($item->params))
		{
			$registry = new Registry;
			$registry->loadArray($item->params);
			$item->params = (string) $registry;
		}

		return;
	}
}
controllers/groups.php000064400000002043151165643610011151 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Groups list controller class.
 *
 * @since  3.7.0
 */
class FieldsControllerGroups extends JControllerAdmin
{
	/**
	 * The prefix to use with controller messages.
	 *
	 * @var    string
	 *
	 * @since   3.7.0
	 */
	protected $text_prefix = 'COM_FIELDS_GROUP';

	/**
	 * Proxy for getModel.
	 *
	 * @param   string  $name    The model name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  The array of possible config values.
Optional.
	 *
	 * @return  JModelLegacy|boolean  Model object on success; otherwise false
on failure.
	 *
	 * @since   3.7.0
	 */
	public function getModel($name = 'Group', $prefix =
'FieldsModel', $config = array('ignore_request' =>
true))
	{
		return parent::getModel($name, $prefix, $config);
	}
}
fields.xml000064400000002331151165643610006543 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<extension type="component" version="3.7.0"
method="upgrade">
	<name>com_fields</name>
	<author>Joomla! Project</author>
	<creationDate>March 2016</creationDate>
	<copyright>(C) 2005 - 2020 Open Source Matters. All rights
reserved.</copyright>
	<license>GNU General Public License version 2 or later; see
LICENSE.txt</license>
	<authorEmail>admin@joomla.org</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>3.7.0</version>
	<description>COM_FIELDS_XML_DESCRIPTION</description>
	<files folder="site">
		<filename>controller.php</filename>
		<filename>fields.php</filename>
		<folder>controllers</folder>
		<folder>layouts</folder>
	</files>
	<administration>
		<files folder="admin">
			<filename>access.xml</filename>
			<filename>controller.php</filename>
			<filename>fields.php</filename>
			<folder>controllers</folder>
			<folder>helpers</folder>
			<folder>libraries</folder>
			<folder>models</folder>
			<folder>tables</folder>
			<folder>views</folder>
		</files>
		<languages folder="admin">
			<language
tag="en-GB">language/en-GB.com_fields.ini</language>
			<language
tag="en-GB">language/en-GB.com_fields.sys.ini</language>
		</languages>
	</administration>
</extension>


helpers/fields.php000064400000047001151165643610010177 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JLoader::register('JFolder', JPATH_LIBRARIES .
'/joomla/filesystem/folder.php');

/**
 * FieldsHelper
 *
 * @since  3.7.0
 */
class FieldsHelper
{
	private static $fieldsCache = null;

	private static $fieldCache = null;

	/**
	 * Extracts the component and section from the context string which has to
	 * be in the format component.context.
	 *
	 * @param   string  $contextString  contextString
	 * @param   object  $item           optional item object
	 *
	 * @return  array|null
	 *
	 * @since   3.7.0
	 */
	public static function extract($contextString, $item = null)
	{
		$parts = explode('.', $contextString, 2);

		if (count($parts) < 2)
		{
			return null;
		}

		$component = $parts[0];
		$eName = str_replace('com_', '', $component);

		$path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' .
$component . '/helpers/' . $eName . '.php');

		if (file_exists($path))
		{
			$cName = ucfirst($eName) . 'Helper';

			JLoader::register($cName, $path);

			if (class_exists($cName) && is_callable(array($cName,
'validateSection')))
			{
				$section = call_user_func_array(array($cName,
'validateSection'), array($parts[1], $item));

				if ($section)
				{
					$parts[1] = $section;
				}
			}
		}

		return $parts;
	}

	/**
	 * Returns the fields for the given context.
	 * If the item is an object the returned fields do have an additional
field
	 * "value" which represents the value for the given item. If the
item has an
	 * assigned_cat_ids field, then additionally fields which belong to that
	 * category will be returned.
	 * Should the value being prepared to be shown in an HTML context then
	 * prepareValue must be set to true. No further escaping needs to be done.
	 * The values of the fields can be overridden by an associative array
where the keys
	 * have to be a name and its corresponding value.
	 *
	 * @param   string    $context           The context of the content passed
to the helper
	 * @param   stdClass  $item              item
	 * @param   int|bool  $prepareValue      (if int is display event): 1 -
AfterTitle, 2 - BeforeDisplay, 3 - AfterDisplay, 0 - OFF
	 * @param   array     $valuesToOverride  The values to override
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getFields($context, $item = null, $prepareValue =
false, array $valuesToOverride = null)
	{
		if (self::$fieldsCache === null)
		{
			// Load the model			
			JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_fields/models', 'FieldsModel');

			self::$fieldsCache = JModelLegacy::getInstance('Fields',
'FieldsModel', array(
				'ignore_request' => true)
			);

			self::$fieldsCache->setState('filter.state', 1);
			self::$fieldsCache->setState('list.limit', 0);
		}

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

		if (JLanguageMultilang::isEnabled() && isset($item->language)
&& $item->language != '*')
		{
			self::$fieldsCache->setState('filter.language',
array('*', $item->language));
		}

		self::$fieldsCache->setState('filter.context', $context);
		self::$fieldsCache->setState('filter.assigned_cat_ids',
array());

		/*
		 * If item has assigned_cat_ids parameter display only fields which
		 * belong to the category
		 */
		if ($item && (isset($item->catid) ||
isset($item->fieldscatid)))
		{
			$assignedCatIds = isset($item->catid) ? $item->catid :
$item->fieldscatid;

			if (!is_array($assignedCatIds))
			{
				$assignedCatIds = explode(',', $assignedCatIds);
			}

			// Fields without any category assigned should show as well
			$assignedCatIds[] = 0;

			self::$fieldsCache->setState('filter.assigned_cat_ids',
$assignedCatIds);
		}

		$fields = self::$fieldsCache->getItems();

		if ($fields === false)
		{
			return array();
		}

		if ($item && isset($item->id))
		{
			if (self::$fieldCache === null)
			{
				self::$fieldCache = JModelLegacy::getInstance('Field',
'FieldsModel', array('ignore_request' => true));
			}

			$fieldIds = array_map(
				function ($f)
				{
					return $f->id;
				},
				$fields
			);

			$fieldValues = self::$fieldCache->getFieldValues($fieldIds,
$item->id);

			$new = array();

			foreach ($fields as $key => $original)
			{
				/*
				 * Doing a clone, otherwise fields for different items will
				 * always reference to the same object
				 */
				$field = clone $original;

				if ($valuesToOverride && key_exists($field->name,
$valuesToOverride))
				{
					$field->value = $valuesToOverride[$field->name];
				}
				elseif ($valuesToOverride && key_exists($field->id,
$valuesToOverride))
				{
					$field->value = $valuesToOverride[$field->id];
				}
				elseif (key_exists($field->id, $fieldValues))
				{
					$field->value = $fieldValues[$field->id];
				}

				if (!isset($field->value) || $field->value === '')
				{
					$field->value = $field->default_value;
				}

				$field->rawvalue = $field->value;

				// If boolean prepare, if int, it is the event type: 1 - After Title, 2
- Before Display, 3 - After Display, 0 - Do not prepare
				if ($prepareValue && (is_bool($prepareValue) || $prepareValue
=== (int) $field->params->get('display', '2')))
				{
					JPluginHelper::importPlugin('fields');

					$dispatcher = JEventDispatcher::getInstance();

					// Event allow plugins to modify the output of the field before it is
prepared
					$dispatcher->trigger('onCustomFieldsBeforePrepareField',
array($context, $item, &$field));

					// Gathering the value for the field
					$value =
$dispatcher->trigger('onCustomFieldsPrepareField',
array($context, $item, &$field));

					if (is_array($value))
					{
						$value = implode(' ', $value);
					}

					// Event allow plugins to modify the output of the prepared field
					$dispatcher->trigger('onCustomFieldsAfterPrepareField',
array($context, $item, $field, &$value));

					// Assign the value
					$field->value = $value;
				}

				$new[$key] = $field;
			}

			$fields = $new;
		}

		return $fields;
	}

	/**
	 * Renders the layout file and data on the context and does a fall back to
	 * Fields afterwards.
	 *
	 * @param   string  $context      The context of the content passed to the
helper
	 * @param   string  $layoutFile   layoutFile
	 * @param   array   $displayData  displayData
	 *
	 * @return  NULL|string
	 *
	 * @since  3.7.0
	 */
	public static function render($context, $layoutFile, $displayData)
	{
		$value = '';

		/*
		 * Because the layout refreshes the paths before the render function is
		 * called, so there is no way to load the layout overrides in the order
		 * template -> context -> fields.
		 * If there is no override in the context then we need to call the
		 * layout from Fields.
		 */
		if ($parts = self::extract($context))
		{
			// Trying to render the layout on the component from the context
			$value = JLayoutHelper::render($layoutFile, $displayData, null,
array('component' => $parts[0], 'client' => 0));
		}

		if ($value == '')
		{
			// Trying to render the layout on Fields itself
			$value = JLayoutHelper::render($layoutFile, $displayData, null,
array('component' => 'com_fields','client'
=> 0));
		}

		return $value;
	}

	/**
	 * PrepareForm
	 *
	 * @param   string  $context  The context of the content passed to the
helper
	 * @param   JForm   $form     form
	 * @param   object  $data     data.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	public static function prepareForm($context, JForm $form, $data)
	{
		// Extracting the component and section
		$parts = self::extract($context);

		if (! $parts)
		{
			return true;
		}

		$context = $parts[0] . '.' . $parts[1];

		// When no fields available return here
		$fields = self::getFields($parts[0] . '.' . $parts[1], new
JObject);

		if (! $fields)
		{
			return true;
		}

		$component = $parts[0];
		$section   = $parts[1];

		$assignedCatids = isset($data->catid) ? $data->catid :
(isset($data->fieldscatid) ? $data->fieldscatid :
$form->getValue('catid'));

		// Account for case that a submitted form has a multi-value category id
field (e.g. a filtering form), just use the first category
		$assignedCatids = is_array($assignedCatids)
			? (int) reset($assignedCatids)
			: (int) $assignedCatids;

		if (!$assignedCatids && $formField =
$form->getField('catid'))
		{
			$assignedCatids = $formField->getAttribute('default',
null);

			// Choose the first category available
			$xml = new DOMDocument;
			$xml->loadHTML($formField->__get('input'));
			$options = $xml->getElementsByTagName('option');

			if (!$assignedCatids && $firstChoice = $options->item(0))
			{
				$assignedCatids = $firstChoice->getAttribute('value');
			}

			$data->fieldscatid = $assignedCatids;
		}

		/*
		 * If there is a catid field we need to reload the page when the catid
		 * is changed
		 */
		if ($form->getField('catid') && $parts[0] !=
'com_fields')
		{
			/*
			 * Setting the onchange event to reload the page when the category
			 * has changed
			*/
			$form->setFieldAttribute('catid', 'onchange',
'categoryHasChanged(this);');

			// Preload spindle-wheel when we need to submit form due to category
selector changed
			JFactory::getDocument()->addScriptDeclaration("
			function categoryHasChanged(element) {
				var cat = jQuery(element);
				if (cat.val() == '" . $assignedCatids . "')return;
				Joomla.loadingLayer('show');
				jQuery('input[name=task]').val('" . $section .
".reload');
				Joomla.submitform('" . $section . ".reload',
element.form);
			}
			jQuery( document ).ready(function() {
				Joomla.loadingLayer('load');
				var formControl = '#" . $form->getFormControl() .
"_catid';
				if (!jQuery(formControl).val() != '" . $assignedCatids .
"'){jQuery(formControl).val('" . $assignedCatids .
"');}
			});"
			);
		}

		// Getting the fields
		$fields = self::getFields($parts[0] . '.' . $parts[1], $data);

		if (!$fields)
		{
			return true;
		}

		$fieldTypes = self::getFieldTypes();

		// Creating the dom
		$xml = new DOMDocument('1.0', 'UTF-8');
		$fieldsNode = $xml->appendChild(new
DOMElement('form'))->appendChild(new
DOMElement('fields'));
		$fieldsNode->setAttribute('name', 'com_fields');

		// Organizing the fields according to their group
		$fieldsPerGroup = array(0 => array());

		foreach ($fields as $field)
		{
			if (!array_key_exists($field->type, $fieldTypes))
			{
				// Field type is not available
				continue;
			}

			if (!array_key_exists($field->group_id, $fieldsPerGroup))
			{
				$fieldsPerGroup[$field->group_id] = array();
			}

			if ($path = $fieldTypes[$field->type]['path'])
			{
				// Add the lookup path for the field
				JFormHelper::addFieldPath($path);
			}

			if ($path = $fieldTypes[$field->type]['rules'])
			{
				// Add the lookup path for the rule
				JFormHelper::addRulePath($path);
			}

			$fieldsPerGroup[$field->group_id][] = $field;
		}

		// On the front, sometimes the admin fields path is not included
		JTable::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_fields/tables');

		$model = JModelLegacy::getInstance('Groups',
'FieldsModel', array('ignore_request' => true));
		$model->setState('filter.context', $context);

		/**
		 * $model->getItems() would only return existing groups, but we also
		 * have the 'default' group with id 0 which is not in the
database,
		 * so we create it virtually here.
		 */
		$defaultGroup = new \stdClass;
		$defaultGroup->id = 0;
		$defaultGroup->title = '';
		$defaultGroup->description = '';
		$iterateGroups = array_merge(array($defaultGroup),
$model->getItems());

		// Looping through the groups
		foreach ($iterateGroups as $group)
		{
			if (empty($fieldsPerGroup[$group->id]))
			{
				continue;
			}

			// Defining the field set
			/** @var DOMElement $fieldset */
			$fieldset = $fieldsNode->appendChild(new
DOMElement('fieldset'));
			$fieldset->setAttribute('name', 'fields-' .
$group->id);
			$fieldset->setAttribute('addfieldpath',
'/administrator/components/' . $component .
'/models/fields');
			$fieldset->setAttribute('addrulepath',
'/administrator/components/' . $component .
'/models/rules');

			$label       = $group->title;
			$description = $group->description;

			if (!$label)
			{
				$key = strtoupper($component . '_FIELDS_' . $section .
'_LABEL');

				if (!JFactory::getLanguage()->hasKey($key))
				{
					$key = 'JGLOBAL_FIELDS';
				}

				$label = $key;
			}

			if (!$description)
			{
				$key = strtoupper($component . '_FIELDS_' . $section .
'_DESC');

				if (JFactory::getLanguage()->hasKey($key))
				{
					$description = $key;
				}
			}

			$fieldset->setAttribute('label', $label);
			$fieldset->setAttribute('description',
strip_tags($description));

			// Looping through the fields for that context
			foreach ($fieldsPerGroup[$group->id] as $field)
			{
				try
				{
					JFactory::getApplication()->triggerEvent('onCustomFieldsPrepareDom',
array($field, $fieldset, $form));

					/*
					 * If the field belongs to an assigned_cat_id but the assigned_cat_ids
in the data
					 * is not known, set the required flag to false on any circumstance.
					 */
					if (!$assignedCatids && !empty($field->assigned_cat_ids)
&& $form->getField($field->name))
					{
						$form->setFieldAttribute($field->name, 'required',
'false');
					}
				}
				catch (Exception $e)
				{
					JFactory::getApplication()->enqueueMessage($e->getMessage(),
'error');
				}
			}

			// When the field set is empty, then remove it
			if (!$fieldset->hasChildNodes())
			{
				$fieldsNode->removeChild($fieldset);
			}
		}

		// Loading the XML fields string into the form
		$form->load($xml->saveXML());

		$model = JModelLegacy::getInstance('Field',
'FieldsModel', array('ignore_request' => true));

		if ((!isset($data->id) || !$data->id) &&
JFactory::getApplication()->input->getCmd('controller') ==
'config.display.modules'
			&& JFactory::getApplication()->isClient('site'))
		{
			// Modules on front end editing don't have data and an id set
			$data->id =
JFactory::getApplication()->input->getInt('id');
		}

		// Looping through the fields again to set the value
		if (!isset($data->id) || !$data->id)
		{
			return true;
		}

		foreach ($fields as $field)
		{
			$value = $model->getFieldValue($field->id, $data->id);

			if ($value === null)
			{
				continue;
			}

			if (!is_array($value) && $value !== '')
			{
				// Function getField doesn't cache the fields, so we try to do it
only when necessary
				$formField = $form->getField($field->name,
'com_fields');

				if ($formField && $formField->forceMultiple)
				{
					$value = (array) $value;
				}
			}

			// Setting the value on the field
			$form->setValue($field->name, 'com_fields', $value);
		}

		return true;
	}

	/**
	 * Return a boolean if the actual logged in user can edit the given field
value.
	 *
	 * @param   stdClass  $field  The field
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	public static function canEditFieldValue($field)
	{
		$parts = self::extract($field->context);

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

	/**
	 * Return a boolean based on field (and field group) display / show_on
settings
	 *
	 * @param   stdClass  $field  The field
	 *
	 * @return  boolean
	 *
	 * @since   3.8.7
	 */
	public static function displayFieldOnForm($field)
	{
		$app = JFactory::getApplication();

		// Detect if the field should be shown at all
		if ($field->params->get('show_on') == 1 &&
$app->isClient('administrator'))
		{
			return false;
		}
		elseif ($field->params->get('show_on') == 2 &&
$app->isClient('site'))
		{
			return false;
		}

		if (!self::canEditFieldValue($field))
		{
			$fieldDisplayReadOnly =
$field->params->get('display_readonly', '2');

			if ($fieldDisplayReadOnly == '2')
			{
				// Inherit from field group display read-only setting
				$groupModel = JModelLegacy::getInstance('Group',
'FieldsModel', array('ignore_request' => true));
				$groupDisplayReadOnly =
$groupModel->getItem($field->group_id)->params->get('display_readonly',
'1');
				$fieldDisplayReadOnly = $groupDisplayReadOnly;
			}

			if ($fieldDisplayReadOnly == '0')
			{
				// Do not display field on form when field is read-only
				return false;
			}
		}

		// Display field on form
		return true;
	}

	/**
	 * Gets assigned categories titles for a field
	 *
	 * @param   stdClass[]  $fieldId  The field ID
	 *
	 * @return  array  Array with the assigned categories
	 *
	 * @since   3.7.0
	 */
	public static function getAssignedCategoriesTitles($fieldId)
	{
		$fieldId = (int) $fieldId;

		if (!$fieldId)
		{
			return array();
		}

		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);

		$query->select($db->quoteName('c.title'))
			->from($db->quoteName('#__fields_categories',
'a'))
			->join('INNER',
$db->quoteName('#__categories', 'c') . ' ON
a.category_id = c.id')
			->where('field_id = ' . $fieldId);

		$db->setQuery($query);

		return $db->loadColumn();
	}

	/**
	 * Gets the fields system plugin extension id.
	 *
	 * @return  integer  The fields system plugin extension id.
	 *
	 * @since   3.7.0
	 */
	public static function getFieldsPluginId()
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('extension_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('folder') . ' = ' .
$db->quote('system'))
			->where($db->quoteName('element') . ' = ' .
$db->quote('fields'));
		$db->setQuery($query);

		try
		{
			$result = (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
			$result = 0;
		}

		return $result;
	}

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $context  The context the fields are used for
	 * @param   string  $vName    The view currently active
	 *
	 * @return  void
	 *
	 * @since    3.7.0
	 */
	public static function addSubmenu($context, $vName)
	{
		$parts = self::extract($context);

		if (!$parts)
		{
			return;
		}

		$component = $parts[0];

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Try to find the component helper.
		$eName = str_replace('com_', '', $component);
		$file  = JPath::clean(JPATH_ADMINISTRATOR . '/components/' .
$component . '/helpers/' . $eName . '.php');

		if (!file_exists($file))
		{
			return;
		}

		require_once $file;

		$cName = ucfirst($eName) . 'Helper';

		if (class_exists($cName) && is_callable(array($cName,
'addSubmenu')))
		{
			$lang = JFactory::getLanguage();
			$lang->load($component, JPATH_ADMINISTRATOR)
			|| $lang->load($component, JPATH_ADMINISTRATOR .
'/components/' . $component);

			$cName::addSubmenu('fields.' . $vName);
		}
	}

	/**
	 * Loads the fields plugins and returns an array of field types from the
plugins.
	 *
	 * The returned array contains arrays with the following keys:
	 * - label: The label of the field
	 * - type:  The type of the field
	 * - path:  The path of the folder where the field can be found
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getFieldTypes()
	{
		JPluginHelper::importPlugin('fields');
		$eventData =
JEventDispatcher::getInstance()->trigger('onCustomFieldsGetTypes');

		$data = array();

		foreach ($eventData as $fields)
		{
			foreach ($fields as $fieldDescription)
			{
				if (!array_key_exists('path', $fieldDescription))
				{
					$fieldDescription['path'] = null;
				}

				if (!array_key_exists('rules', $fieldDescription))
				{
					$fieldDescription['rules'] = null;
				}

				$data[$fieldDescription['type']] = $fieldDescription;
			}
		}

		return $data;
	}

	/**
	 * Clears the internal cache for the custom fields.
	 *
	 * @return  void
	 *
	 * @since   3.8.0
	 */
	public static function clearFieldsCache()
	{
		self::$fieldCache  = null;
		self::$fieldsCache = null;
	}
}
libraries/fieldslistplugin.php000064400000003567151165643610012635
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JLoader::import('components.com_fields.libraries.fieldsplugin',
JPATH_ADMINISTRATOR);

/**
 * Base plugin for all list based plugins
 *
 * @since  3.7.0
 */
class FieldsListPlugin extends FieldsPlugin
{
	/**
	 * Transforms the field into a DOM XML element and appends it as a child
on the given parent.
	 *
	 * @param   stdClass    $field   The field.
	 * @param   DOMElement  $parent  The field node parent.
	 * @param   JForm       $form    The form.
	 *
	 * @return  DOMElement
	 *
	 * @since   3.7.0
	 */
	public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm
$form)
	{
		$fieldNode = parent::onCustomFieldsPrepareDom($field, $parent, $form);

		if (!$fieldNode)
		{
			return $fieldNode;
		}

		$fieldNode->setAttribute('validate', 'options');

		foreach ($this->getOptionsFromField($field) as $value => $name)
		{
			$option = new DOMElement('option', htmlspecialchars($value,
ENT_COMPAT, 'UTF-8'));
			$option->textContent = htmlspecialchars(JText::_($name), ENT_COMPAT,
'UTF-8');

			$element = $fieldNode->appendChild($option);
			$element->setAttribute('value', $value);
		}

		return $fieldNode;
	}

	/**
	 * Returns an array of key values to put in a list from the given field.
	 *
	 * @param   stdClass  $field  The field.
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public function getOptionsFromField($field)
	{
		$data = array();

		// Fetch the options from the plugin
		$params = clone $this->params;
		$params->merge($field->fieldparams);

		foreach ($params->get('options', array()) as $option)
		{
			$op = (object) $option;
			$data[$op->value] = $op->name;
		}

		return $data;
	}
}
libraries/fieldsplugin.php000064400000014461151165643610011734
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Abstract Fields Plugin
 *
 * @since  3.7.0
 */
abstract class FieldsPlugin extends JPlugin
{
	protected $autoloadLanguage = true;

	/**
	 * Returns the custom fields types.
	 *
	 * @return  string[][]
	 *
	 * @since   3.7.0
	 */
	public function onCustomFieldsGetTypes()
	{
		// Cache filesystem access / checks
		static $types_cache = array();

		if (isset($types_cache[$this->_type . $this->_name]))
		{
			return $types_cache[$this->_type . $this->_name];
		}

		$types = array();

		// The root of the plugin
		$root = JPATH_PLUGINS . '/' . $this->_type . '/' .
$this->_name;

		foreach (JFolder::files($root . '/tmpl', '.php') as
$layout)
		{
			// Strip the extension
			$layout = str_replace('.php', '', $layout);

			// The data array
			$data = array();

			// The language key
			$key = strtoupper($layout);

			if ($key != strtoupper($this->_name))
			{
				$key = strtoupper($this->_name) . '_' . $layout;
			}

			// Needed attributes
			$data['type'] = $layout;

			if (JFactory::getLanguage()->hasKey('PLG_FIELDS_' . $key .
'_LABEL'))
			{
				$data['label'] = JText::sprintf('PLG_FIELDS_' .
$key . '_LABEL', strtolower($key));

				// Fix wrongly set parentheses in RTL languages
				if (JFactory::getLanguage()->isRTL())
				{
					$data['label'] = $data['label'] .
'&#x200E;';
				}
			}
			else
			{
				$data['label'] = $key;
			}

			$path = $root . '/fields';

			// Add the path when it exists
			if (file_exists($path))
			{
				$data['path'] = $path;
			}

			$path = $root . '/rules';

			// Add the path when it exists
			if (file_exists($path))
			{
				$data['rules'] = $path;
			}

			$types[] = $data;
		}

		// Add to cache and return the data
		$types_cache[$this->_type . $this->_name] = $types;

		return $types;
	}

	/**
	 * Prepares the field value.
	 *
	 * @param   string    $context  The context.
	 * @param   stdclass  $item     The item.
	 * @param   stdclass  $field    The field.
	 *
	 * @return  string
	 *
	 * @since   3.7.0
	 */
	public function onCustomFieldsPrepareField($context, $item, $field)
	{
		// Check if the field should be processed by us
		if (!$this->isTypeSupported($field->type))
		{
			return;
		}

		// Merge the params from the plugin and field which has precedence
		$fieldParams = clone $this->params;
		$fieldParams->merge($field->fieldparams);

		// Get the path for the layout file
		$path = JPluginHelper::getLayoutPath('fields', $field->type,
$field->type);

		if (!file_exists($path))
		{
			$path = JPluginHelper::getLayoutPath('fields',
$this->_name, $field->type);
		}

		// Render the layout
		ob_start();
		include $path;
		$output = ob_get_clean();

		// Return the output
		return $output;
	}

	/**
	 * Transforms the field into a DOM XML element and appends it as a child
on the given parent.
	 *
	 * @param   stdClass    $field   The field.
	 * @param   DOMElement  $parent  The field node parent.
	 * @param   JForm       $form    The form.
	 *
	 * @return  DOMElement
	 *
	 * @since   3.7.0
	 */
	public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm
$form)
	{
		// Check if the field should be processed by us
		if (!$this->isTypeSupported($field->type))
		{
			return null;
		}

		// Detect if the field is configured to be displayed on the form
		if (!FieldsHelper::displayFieldOnForm($field))
		{
			return null;
		}

		// Create the node
		$node = $parent->appendChild(new DOMElement('field'));

		// Set the attributes
		$node->setAttribute('name', $field->name);
		$node->setAttribute('type', $field->type);
		$node->setAttribute('label', $field->label);
		$node->setAttribute('labelclass',
$field->params->get('label_class'));
		$node->setAttribute('description', $field->description);
		$node->setAttribute('class',
$field->params->get('class'));
		$node->setAttribute('hint',
$field->params->get('hint'));
		$node->setAttribute('required', $field->required ?
'true' : 'false');

		if ($field->default_value !== '')
		{
			$defaultNode = $node->appendChild(new
DOMElement('default'));
			$defaultNode->appendChild(new
DOMCdataSection($field->default_value));
		}

		// Combine the two params
		$params = clone $this->params;
		$params->merge($field->fieldparams);

		// Set the specific field parameters
		foreach ($params->toArray() as $key => $param)
		{
			if (is_array($param))
			{
				// Multidimensional arrays (eg. list options) can't be transformed
properly
				$param = count($param) == count($param, COUNT_RECURSIVE) ?
implode(',', $param) : '';
			}

			if ($param === '' || (!is_string($param) &&
!is_numeric($param)))
			{
				continue;
			}

			$node->setAttribute($key, $param);
		}

		// Check if it is allowed to edit the field
		if (!FieldsHelper::canEditFieldValue($field))
		{
			$node->setAttribute('disabled', 'true');
		}

		// Return the node
		return $node;
	}

	/**
	 * The form event. Load additional parameters when available into the
field form.
	 * Only when the type of the form is of interest.
	 *
	 * @param   JForm     $form  The form
	 * @param   stdClass  $data  The data
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	public function onContentPrepareForm(JForm $form, $data)
	{
		// Check if the field form is calling us
		if (strpos($form->getName(), 'com_fields.field') !== 0)
		{
			return;
		}

		// Ensure it is an object
		$formData = (object) $data;

		// Gather the type
		$type = $form->getValue('type');

		if (!empty($formData->type))
		{
			$type = $formData->type;
		}

		// Not us
		if (!$this->isTypeSupported($type))
		{
			return;
		}

		$path = JPATH_PLUGINS . '/' . $this->_type . '/' .
$this->_name . '/params/' . $type . '.xml';

		// Check if params file exists
		if (!file_exists($path))
		{
			return;
		}

		// Load the specific plugin parameters
		$form->load(file_get_contents($path), true, '/form/*');
	}

	/**
	 * Returns true if the given type is supported by the plugin.
	 *
	 * @param   string  $type  The type
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	protected function isTypeSupported($type)
	{
		foreach ($this->onCustomFieldsGetTypes() as $typeSpecification)
		{
			if ($type == $typeSpecification['type'])
			{
				return true;
			}
		}

		return false;
	}
}
models/field.php000064400000066715151165643610007652 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @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)
	{
		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;
	}
}
models/fields/fieldcontexts.php000064400000002742151165643610012676
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JFormHelper::loadFieldClass('list');

/**
 * Fields Contexts
 *
 * @since  3.7.0
 */
class JFormFieldFieldcontexts extends JFormFieldList
{
	public $type = 'Fieldcontexts';

	/**
	 * Method to get the field input markup for a generic list.
	 * Use the multiple attribute to enable multiselect.
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   3.7.0
	 */
	protected function getInput()
	{
		return $this->getOptions() ? parent::getInput() : '';
	}

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.7.0
	 */
	protected function getOptions()
	{
		$parts = explode('.', $this->value);
		$eName = str_replace('com_', '', $parts[0]);
		$file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' .
$parts[0] . '/helpers/' . $eName . '.php');
		$contexts = array();

		if (!file_exists($file))
		{
			return array();
		}

		$prefix = ucfirst($eName);
		$cName = $prefix . 'Helper';

		JLoader::register($cName, $file);

		if (class_exists($cName) && is_callable(array($cName,
'getContexts')))
		{
			$contexts = $cName::getContexts();
		}

		if (!$contexts || !is_array($contexts) || count($contexts) == 1)
		{
			return array();
		}

		return $contexts;
	}
}
models/fields/fieldgroups.php000064400000003122151165643610012337
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

JFormHelper::loadFieldClass('list');

/**
 * Fields Groups
 *
 * @since  3.7.0
 */
class JFormFieldFieldgroups extends JFormFieldList
{
	public $type = 'Fieldgroups';

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.7.0
	 */
	protected function getOptions()
	{
		$context = (string) $this->element['context'];
		$states    = $this->element['state'] ?: '0,1';
		$states    = ArrayHelper::toInteger(explode(',', $states));

		$user       = JFactory::getUser();
		$viewlevels =
ArrayHelper::toInteger($user->getAuthorisedViewLevels());

		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('title AS text, id AS value, state');
		$query->from('#__fields_groups');
		$query->where('state IN (' . implode(',', $states)
. ')');
		$query->where('context = ' . $db->quote($context));
		$query->where('access IN (' . implode(',',
$viewlevels) . ')');
		$query->order('ordering asc, id asc');

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

		foreach ($options AS $option)
		{
			if ($option->state == 0)
			{
				$option->text = '[' . $option->text . ']';
			}

			if ($option->state == 2)
			{
				$option->text = '{' . $option->text . '}';
			}
		}

		return array_merge(parent::getOptions(), $options);
	}
}
models/fields/fieldlayout.php000064400000011066151165643610012343
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

jimport('joomla.filesystem.folder');

/**
 * Form Field to display a list of the layouts for a field from
 * the extension or template overrides.
 *
 * @since  3.9.0
 */
class JFormFieldFieldlayout extends JFormField
{
	/**
	 * The form field type.
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	protected $type = 'FieldLayout';

	/**
	 * Method to get the field input for a field layout field.
	 *
	 * @return  string   The field input.
	 *
	 * @since   3.9.0
	 */
	protected function getInput()
	{
		$extension = explode('.',
$this->form->getValue('context'));
		$extension = $extension[0];

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

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

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

			// Build the search paths for component layouts.
			$component_path = JPath::clean(JPATH_SITE . '/components/' .
$extension . '/layouts/field');

			// Prepare array of component layouts
			$component_layouts = array();

			// Prepare the grouped list
			$groups = array();

			// Add "Use Default"
			$groups[]['items'][] = JHtml::_('select.option',
'', JText::_('JOPTION_USE_DEFAULT'));

			// Add the layout options from the component path.
			if (is_dir($component_path) && ($component_layouts =
JFolder::files($component_path, '^[^_]*\.php$', false, true)))
			{
				// Create the group for the component
				$groups['_'] = array();
				$groups['_']['id'] = $this->id . '__';
				$groups['_']['text'] =
JText::sprintf('JOPTION_FROM_COMPONENT');
				$groups['_']['items'] = array();

				foreach ($component_layouts as $i => $file)
				{
					// Add an option to the component group
					$value = basename($file, '.php');
					$component_layouts[$i] = $value;

					if ($value === 'render')
					{
						continue;
					}

					$groups['_']['items'][] =
JHtml::_('select.option', $value, $value);
				}
			}

			// Loop on all templates
			if ($templates)
			{
				foreach ($templates as $template)
				{
					$files = array();
					$template_paths = array(
						JPath::clean(JPATH_SITE . '/templates/' .
$template->element . '/html/layouts/' . $extension .
'/field'),
						JPath::clean(JPATH_SITE . '/templates/' .
$template->element . '/html/layouts/com_fields/field'),
						JPath::clean(JPATH_SITE . '/templates/' .
$template->element . '/html/layouts/field'),
					);

					// Add the layout options from the template paths.
					foreach ($template_paths as $template_path)
					{
						if (is_dir($template_path))
						{
							$files = array_merge($files, JFolder::files($template_path,
'^[^_]*\.php$', false, true));
						}
					}

					foreach ($files as $i => $file)
					{
						$value = basename($file, '.php');

						// Remove the default "render.php" or layout files that
exist in the component folder
						if ($value === 'render' || in_array($value,
$component_layouts))
						{
							unset($files[$i]);
						}
					}

					if (count($files))
					{
						// Create the group for the template
						$groups[$template->name] = array();
						$groups[$template->name]['id'] = $this->id .
'_' . $template->element;
						$groups[$template->name]['text'] =
JText::sprintf('JOPTION_FROM_TEMPLATE', $template->name);
						$groups[$template->name]['items'] = array();

						foreach ($files as $file)
						{
							// Add an option to the template group
							$value = basename($file, '.php');
							$groups[$template->name]['items'][] =
JHtml::_('select.option', $value, $value);
						}
					}
				}
			}

			// Compute attributes for the grouped list
			$attr = $this->element['size'] ? ' size="' .
(int) $this->element['size'] . '"' :
'';
			$attr .= $this->element['class'] ? '
class="' . (string) $this->element['class'] .
'"' : '';

			// Prepare HTML code
			$html = array();

			// Compute the current selected values
			$selected = array($this->value);

			// Add a grouped list
			$html[] = JHtml::_(
				'select.groupedlist', $groups, $this->name,
				array('id' => $this->id, 'group.id' =>
'id', 'list.attr' => $attr, 'list.select'
=> $selected)
			);

			return implode($html);
		}

		return '';
	}
}
models/fields/section.php000064400000004047151165643610011467
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JFormHelper::loadFieldClass('list');

/**
 * Fields Section
 *
 * @since  3.7.0
 */
class JFormFieldSection extends JFormFieldList
{
	public $type = 'Section';

	/**
	 * 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
	 */
	public function setup(SimpleXMLElement $element, $value, $group = null)
	{
		$return = parent::setup($element, $value, $group);

		// Onchange must always be the change context function
		$this->onchange =
'fieldsChangeContext(jQuery(this).val());';

		return $return;
	}

	/**
	 * Method to get the field input markup for a generic list.
	 * Use the multiple attribute to enable multiselect.
	 *
	 * @return  string  The field input markup.
	 *
	 * @since   3.7.0
	 */
	protected function getInput()
	{
		// Add the change context function to the document
		JFactory::getDocument()->addScriptDeclaration(
			"function fieldsChangeContext(context)
				{
					var regex = new
RegExp(\"([?;&])context[^&;]*[;&]?\");
					var url = window.location.href;
					var query = url.replace(regex, \"$1\").replace(/&$/,
'');
    					window.location.href = (query.length > 2 ? query +
\"&\" : \"?\") + (context ? \"context=\"
+ context : '');
				}"
		);

		return parent::getInput();
	}
}
models/fields/type.php000064400000004200151165643610010773 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JFormHelper::loadFieldClass('list');

/**
 * Fields Type
 *
 * @since  3.7.0
 */
class JFormFieldType extends JFormFieldList
{
	public $type = 'Type';

	/**
	 * 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
	 */
	public function setup(SimpleXMLElement $element, $value, $group = null)
	{
		$return = parent::setup($element, $value, $group);

		$this->onchange = 'typeHasChanged(this);';

		return $return;
	}

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.7.0
	 */
	protected function getOptions()
	{
		$options = parent::getOptions();

		$fieldTypes = FieldsHelper::getFieldTypes();

		foreach ($fieldTypes as $fieldType)
		{
			$options[] = JHtml::_('select.option',
$fieldType['type'], $fieldType['label']);
		}

		// Sorting the fields based on the text which is displayed
		usort(
			$options,
			function ($a, $b)
			{
				return strcmp($a->text, $b->text);
			}
		);

		JFactory::getDocument()->addScriptDeclaration("
			jQuery( document ).ready(function() {
				Joomla.loadingLayer('load');
			});
			function typeHasChanged(element){
				Joomla.loadingLayer('show');
				var cat = jQuery(element);
				jQuery('input[name=task]').val('field.reload');
				element.form.submit();
			}
		"
		);

		return $options;
	}
}
models/fields.php000064400000025426151165643610010027 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

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

/**
 * Fields Model
 *
 * @since  3.7.0
 */
class FieldsModelFields extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JModelLegacy
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'title', 'a.title',
				'type', 'a.type',
				'name', 'a.name',
				'state', 'a.state',
				'access', 'a.access',
				'access_level',
				'language', 'a.language',
				'ordering', 'a.ordering',
				'checked_out', 'a.checked_out',
				'checked_out_time', 'a.checked_out_time',
				'created_time', 'a.created_time',
				'created_user_id', 'a.created_user_id',
				'group_title', 'g.title',
				'category_id', 'a.category_id',
				'group_id', 'a.group_id',
				'assigned_cat_ids'
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * This method should only be called once per instantiation and is
designed
	 * to be called on the first call to the getState() method unless the
model
	 * configuration flag to ignore the request is set.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function populateState($ordering = null, $direction = null)
	{
		// List state information.
		parent::populateState('a.ordering', 'asc');

		$context = $this->getUserStateFromRequest($this->context .
'.context', 'context', 'com_content.article',
'CMD');
		$this->setState('filter.context', $context);

		// Split context into component and optional section
		$parts = FieldsHelper::extract($context);

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

	/**
	 * Method to get a store id based on the model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  An identifier string to generate the store id.
	 *
	 * @return  string  A store id.
	 *
	 * @since   3.7.0
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' . $this->getState('filter.context');
		$id .= ':' .
serialize($this->getState('filter.assigned_cat_ids'));
		$id .= ':' . $this->getState('filter.state');
		$id .= ':' . $this->getState('filter.group_id');
		$id .= ':' .
serialize($this->getState('filter.language'));

		return parent::getStoreId($id);
	}

	/**
	 * Method to get a JDatabaseQuery object for retrieving the data set from
a database.
	 *
	 * @return  JDatabaseQuery   A JDatabaseQuery object to retrieve the data
set.
	 *
	 * @since   3.7.0
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db    = $this->getDbo();
		$query = $db->getQuery(true);
		$user  = JFactory::getUser();
		$app   = JFactory::getApplication();

		// Select the required fields from the table.
		$query->select(
			$this->getState(
				'list.select',
				'DISTINCT a.id, a.title, a.name, a.checked_out,
a.checked_out_time, a.note' .
				', a.state, a.access, a.created_time, a.created_user_id,
a.ordering, a.language' .
				', a.fieldparams, a.params, a.type, a.default_value, a.context,
a.group_id' .
				', a.label, a.description, a.required'
			)
		);
		$query->from('#__fields AS a');

		// Join over the language
		$query->select('l.title AS language_title, l.image AS
language_image')
			->join('LEFT', $db->quoteName('#__languages')
. ' AS l ON l.lang_code = a.language');

		// Join over the users for the checked out user.
		$query->select('uc.name AS
editor')->join('LEFT', '#__users AS uc ON
uc.id=a.checked_out');

		// Join over the asset groups.
		$query->select('ag.title AS
access_level')->join('LEFT', '#__viewlevels AS ag ON
ag.id = a.access');

		// Join over the users for the author.
		$query->select('ua.name AS
author_name')->join('LEFT', '#__users AS ua ON ua.id
= a.created_user_id');

		// Join over the field groups.
		$query->select('g.title AS group_title, g.access as group_access,
g.state AS group_state, g.note as group_note');
		$query->join('LEFT', '#__fields_groups AS g ON g.id =
a.group_id');

		// Filter by context
		if ($context = $this->getState('filter.context'))
		{
			$query->where('a.context = ' . $db->quote($context));
		}

		// Filter by access level.
		if ($access = $this->getState('filter.access'))
		{
			if (is_array($access))
			{
				$access = ArrayHelper::toInteger($access);
				$query->where('a.access in (' . implode(',',
$access) . ')');
			}
			else
			{
				$query->where('a.access = ' . (int) $access);
			}
		}

		if (($categories =
$this->getState('filter.assigned_cat_ids')) &&
$context)
		{
			$categories = (array) $categories;
			$categories = ArrayHelper::toInteger($categories);
			$parts = FieldsHelper::extract($context);

			if ($parts)
			{
				// Get the category
				$cat = JCategories::getInstance(str_replace('com_',
'', $parts[0]) . '.' . $parts[1]);

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

				if ($cat)
				{
					foreach ($categories as $assignedCatIds)
					{
						// Check if we have the actual category
						$parent = $cat->get($assignedCatIds);

						if ($parent)
						{
							$categories[] = (int) $parent->id;

							// Traverse the tree up to get all the fields which are attached to
a parent
							while ($parent->getParent() &&
$parent->getParent()->id != 'root')
							{
								$parent = $parent->getParent();
								$categories[] = (int) $parent->id;
							}
						}
					}
				}
			}

			$categories = array_unique($categories);

			// Join over the assigned categories
			$query->join('LEFT',
$db->quoteName('#__fields_categories') . ' AS fc ON
fc.field_id = a.id');

			if (in_array('0', $categories))
			{
				$query->where('(fc.category_id IS NULL OR fc.category_id IN
(' . implode(',', $categories) . '))');
			}
			else
			{
				$query->where('fc.category_id IN (' .
implode(',', $categories) . ')');
			}
		}

		// Implement View Level Access
		if (!$app->isClient('administrator') ||
!$user->authorise('core.admin'))
		{
			$groups = implode(',', $user->getAuthorisedViewLevels());
			$query->where('a.access IN (' . $groups . ') AND
(a.group_id = 0 OR g.access IN (' . $groups . '))');
		}

		// Filter by state
		$state = $this->getState('filter.state');

		// Include group state only when not on on back end list
		$includeGroupState = !$app->isClient('administrator') ||
			$app->input->get('option') != 'com_fields' ||
			$app->input->get('view') != 'fields';

		if (is_numeric($state))
		{
			$query->where('a.state = ' . (int) $state);

			if ($includeGroupState)
			{
				$query->where('(a.group_id = 0 OR g.state = ' . (int)
$state . ')');
			}
		}
		elseif (!$state)
		{
			$query->where('a.state IN (0, 1)');

			if ($includeGroupState)
			{
				$query->where('(a.group_id = 0 OR g.state IN (0, 1))');
			}
		}

		$groupId = $this->getState('filter.group_id');

		if (is_numeric($groupId))
		{
			$query->where('a.group_id = ' . (int) $groupId);
		}

		// Filter by search in title
		$search = $this->getState('filter.search');

		if (! empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			elseif (stripos($search, 'author:') === 0)
			{
				$search = $db->quote('%' . $db->escape(substr($search,
7), true) . '%');
				$query->where('(ua.name LIKE ' . $search . ' OR
ua.username LIKE ' . $search . ')');
			}
			else
			{
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));
				$query->where('(a.title LIKE ' . $search . ' OR
a.name LIKE ' . $search . ' OR a.note LIKE ' . $search .
')');
			}
		}

		// Filter on the language.
		if ($language = $this->getState('filter.language'))
		{
			$language = (array) $language;

			foreach ($language as $key => $l)
			{
				$language[$key] = $db->quote($l);
			}

			$query->where('a.language in (' . implode(',',
$language) . ')');
		}

		// Add the list ordering clause
		$listOrdering  = $this->state->get('list.ordering',
'a.ordering');
		$orderDirn     = $this->state->get('list.direction',
'ASC');

		$query->order($db->escape($listOrdering) . ' ' .
$db->escape($orderDirn));

		return $query;
	}

	/**
	 * Gets an array of objects from the results of database query.
	 *
	 * @param   string   $query       The query.
	 * @param   integer  $limitstart  Offset.
	 * @param   integer  $limit       The number of records.
	 *
	 * @return  array  An array of results.
	 *
	 * @since   3.7.0
	 * @throws  RuntimeException
	 */
	protected function _getList($query, $limitstart = 0, $limit = 0)
	{
		$result = parent::_getList($query, $limitstart, $limit);

		if (is_array($result))
		{
			foreach ($result as $field)
			{
				$field->fieldparams = new Registry($field->fieldparams);
				$field->params = new Registry($field->params);
			}
		}

		return $result;
	}

	/**
	 * Get the filter form
	 *
	 * @param   array    $data      data
	 * @param   boolean  $loadData  load current data
	 *
	 * @return  JForm|false  the JForm object or false
	 *
	 * @since   3.7.0
	 */
	public function getFilterForm($data = array(), $loadData = true)
	{
		$form = parent::getFilterForm($data, $loadData);

		if ($form)
		{
			$form->setValue('context', null,
$this->getState('filter.context'));
			$form->setFieldAttribute('group_id', 'context',
$this->getState('filter.context'), 'filter');
			$form->setFieldAttribute('assigned_cat_ids',
'extension',
$this->state->get('filter.component'), 'filter');
		}

		return $form;
	}

	/**
	 * Get the groups for the batch method
	 *
	 * @return  array  An array of groups
	 *
	 * @since   3.7.0
	 */
	public function getGroups()
	{
		$user       = JFactory::getUser();
		$viewlevels =
ArrayHelper::toInteger($user->getAuthorisedViewLevels());

		$db    = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('title AS text, id AS value, state');
		$query->from('#__fields_groups');
		$query->where('state IN (0,1)');
		$query->where('context = ' .
$db->quote($this->state->get('filter.context')));
		$query->where('access IN (' . implode(',',
$viewlevels) . ')');

		$db->setQuery($query);

		return $db->loadObjectList();
	}
}
models/forms/field.xml000064400000016071151165643610010777 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset
addfieldpath="/administrator/components/com_categories/models/fields"
>
		<field
			name="id"
			type="number"
			label="JGLOBAL_FIELD_ID_LABEL"
			description="JGLOBAL_FIELD_ID_DESC"
			default="0"
			class="readonly"
			readonly="true"
		/>

		<field
			name="asset_id"
			type="hidden"
			filter="unset"
		/>

		<field
			name="context"
			type="hidden"
		/>

		<field
			name="group_id"
			type="fieldgroups"
			label="COM_FIELDS_FIELD_GROUP_LABEL"
			description="COM_FIELDS_FIELD_GROUP_DESC"
			>
			<option value="0">JNONE</option>
		</field>

		<field
			name="assigned_cat_ids"
			type="category"
			label="JCATEGORY"
			description="JFIELD_FIELDS_CATEGORY_DESC"
			extension="com_content"
			multiple="true"
			>
			<option value="">JALL</option>
		</field>

		<field
			name="title"
			type="text"
			label="JGLOBAL_TITLE"
			description="JFIELD_TITLE_DESC"
			class="input-xxlarge input-large-text"
			size="40"
			required="true"
		/>

		<field
			name="name"
			type="text"
			label="JFIELD_NAME_LABEL"
			description="JFIELD_NAME_DESC"
			hint="JFIELD_NAME_PLACEHOLDER"
			size="45"
		/>

		<field
			name="type"
			type="type"
			label="COM_FIELDS_FIELD_TYPE_LABEL"
			description="COM_FIELDS_FIELD_TYPE_DESC"
			default="text"
			required="true"
		/>

		<field
			name="required"
			type="radio"
			label="COM_FIELDS_FIELD_REQUIRED_LABEL"
			description="COM_FIELDS_FIELD_REQUIRED_DESC"
			class="btn-group btn-group-yesno"
			default="0"
			>
			<option value="1">JYES</option>
			<option value="0">JNO</option>
		</field>

		<field
			name="default_value"
			type="textarea"
			label="COM_FIELDS_FIELD_DEFAULT_VALUE_LABEL"
			description="COM_FIELDS_FIELD_DEFAULT_VALUE_DESC"
			filter="raw"
		/>

		<field
			name="state"
			type="list"
			label="JSTATUS"
			description="JFIELD_PUBLISHED_DESC"
			class="chzn-color-state"
			default="1"
			size="1"
			>
			<option value="1">JPUBLISHED</option>
			<option value="0">JUNPUBLISHED</option>
			<option value="2">JARCHIVED</option>
			<option value="-2">JTRASHED</option>
		</field>

		<field
			name="buttonspacer"
			type="spacer"
			label="JGLOBAL_ACTION_PERMISSIONS_LABEL"
			description="JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION"
		/>

		<field
			name="checked_out"
			type="hidden"
			filter="unset"
		/>

		<field
			name="checked_out_time"
			type="hidden"
			filter="unset"
		/>

		<field
			name="created_user_id"
			type="user"
			label="JGLOBAL_FIELD_CREATED_BY_LABEL"
			description="JGLOBAL_FIELD_CREATED_BY_DESC"
		/>

		<field
			name="created_time"
			type="calendar"
			label="JGLOBAL_CREATED_DATE"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="modified_by"
			type="user"
			label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
			class="readonly"
			readonly="true"
			filter="unset"
		/>

		<field
			name="modified_time"
			type="calendar"
			label="JGLOBAL_FIELD_MODIFIED_LABEL"
			class="readonly"
			translateformat="true"
			showtime="true"
			size="22"
			readonly="true"
			filter="user_utc"
		/>

		<field
			name="language"
			type="contentlanguage"
			label="JFIELD_LANGUAGE_LABEL"
			description="COM_FIELDS_FIELD_LANGUAGE_DESC"
			>
			<option value="*">JALL</option>
		</field>

		<field
			name="note"
			type="text"
			label="COM_FIELDS_FIELD_NOTE_LABEL"
			description="COM_FIELDS_FIELD_NOTE_DESC"
			class="span12"
			size="40"
		/>

		<field
			name="label"
			type="text"
			label="COM_FIELDS_FIELD_LABEL_LABEL"
			description="COM_FIELDS_FIELD_LABEL_DESC"
			size="40"
			hint="JFIELD_ALIAS_PLACEHOLDER"
		/>

		<field
			name="description"
			type="textarea"
			label="JGLOBAL_DESCRIPTION"
			description="COM_FIELDS_FIELD_DESCRIPTION_DESC"
			size="40"
			filter="HTML"
		/>

		<field
			name="access"
			type="accesslevel"
			label="JFIELD_ACCESS_LABEL"
			description="JFIELD_ACCESS_DESC"
		/>

		<field
			name="rules"
			type="rules"
			label="JFIELD_RULES_LABEL"
			id="rules"
			translate_label="false"
			filter="rules"
			validate="rules"
			section="field"
		/>

		<field
			name="ordering"
			type="text"
			label="JFIELD_ORDERING_LABEL"
			description="JFIELD_ORDERING_DESC"
			class="inputbox"
		/>
	</fieldset>

	<fields name="params"
label="COM_FIELDS_FIELD_BASIC_LABEL">
		<fieldset name="basic">

			<field
				name="formoptions"
				type="note"
				label="COM_FIELDS_FIELD_FORMOPTIONS_HEADING"
			/>

			<field
				name="hint"
				type="text"
				label="COM_FIELDS_FIELD_PLACEHOLDER_LABEL"
				description="COM_FIELDS_FIELD_PLACEHOLDER_DESC"
				class="input-xxlarge"
				size="40"
			/>

			<field
				name="class"
				type="textarea"
				label="COM_FIELDS_FIELD_CLASS_LABEL"
				description="COM_FIELDS_FIELD_CLASS_DESC"
				class="input-xxlarge"
				size="40"
			/>

			<field
				name="label_class"
				type="textarea"
				label="COM_FIELDS_FIELD_LABEL_FORM_CLASS_LABEL"
				description="COM_FIELDS_FIELD_LABEL_FORM_CLASS_DESC"
				class="input-xxlarge"
				size="40"
			/>

			<field
				name="show_on"
				type="radio"
				label="COM_FIELDS_FIELD_EDITABLE_IN_LABEL"
				description="COM_FIELDS_FIELD_EDITABLE_IN_DESC"
				class="btn-group btn-group-yesno"
				default=""
				>
				<option
value="1">COM_FIELDS_FIELD_EDITABLE_IN_SITE</option>
				<option
value="2">COM_FIELDS_FIELD_EDITABLE_IN_ADMIN</option>
				<option
value="">COM_FIELDS_FIELD_EDITABLE_IN_BOTH</option>
			</field>

			<field
				name="renderoptions"
				type="note"
				label="COM_FIELDS_FIELD_RENDEROPTIONS_HEADING"
			/>

			<field
				name="render_class"
				type="textarea"
				label="COM_FIELDS_FIELD_RENDER_CLASS_LABEL"
				description="COM_FIELDS_FIELD_RENDER_CLASS_DESC"
				class="input-xxlarge"
				size="40"
			/>

			<field
				name="showlabel"
				type="radio"
				label="COM_FIELDS_FIELD_SHOWLABEL_LABEL"
				description="COM_FIELDS_FIELD_SHOWLABEL_DESC"
				class="btn-group btn-group-yesno"
				default="1"
				>
				<option value="1">JSHOW</option>
				<option value="0">JHIDE</option>
			</field>

			<field
				name="label_render_class"
				type="textarea"
				label="COM_FIELDS_FIELD_LABEL_RENDER_CLASS_LABEL"
				description="COM_FIELDS_FIELD_LABEL_RENDER_CLASS_DESC"
				class="input-xxlarge"
				size="40"
				showon="showlabel:1"
			/>

			<field
				name="display"
				type="list"
				label="COM_FIELDS_FIELD_DISPLAY_LABEL"
				description="COM_FIELDS_FIELD_DISPLAY_DESC"
				default="2"
				>
				<option
value="1">COM_FIELDS_FIELD_DISPLAY_AFTER_TITLE</option>
				<option
value="2">COM_FIELDS_FIELD_DISPLAY_BEFORE_DISPLAY</option>
				<option
value="3">COM_FIELDS_FIELD_DISPLAY_AFTER_DISPLAY</option>
				<option
value="0">COM_FIELDS_FIELD_DISPLAY_NO_DISPLAY</option>
			</field>

			<field
				name="layout"
				type="fieldlayout"
				label="COM_FIELDS_FIELD_LAYOUT_LABEL"
				description="COM_FIELDS_FIELD_LAYOUT_DESC"
			/>

			<field
				name="display_readonly"
				type="radio"
				label="JFIELD_DISPLAY_READONLY_LABEL"
				description="JFIELD_DISPLAY_READONLY_DESC"
				class="btn-group btn-group-yesno"
				default="2"
				>
				<option value="2">JGLOBAL_INHERIT</option>
				<option value="1">JYES</option>
				<option value="0">JNO</option>
			</field>
		</fieldset>
	</fields>
</form>
models/forms/filter_groups.xml000064400000003705151165643610012600
0ustar00<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset name="group">
		<field
			name="context"
			type="fieldcontexts"
			onchange="this.form.submit();"
		/>
	</fieldset>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			description="COM_FIELDS_GROUPS_FILTER_SEARCH_DESC"
			hint="JSEARCH_FILTER"
			class="js-stools-search-string"
		/>

		<field
			name="state"
			type="status"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
		</field>

		<field
			name="access"
			type="accesslevel"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_ACCESS</option>
		</field>

		<field
			name="language"
			type="contentlanguage"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_LANGUAGE</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			onchange="this.form.submit();"
			default="a.ordering ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.ordering
ASC">JGRID_HEADING_ORDERING_ASC</option>
			<option value="a.ordering
DESC">JGRID_HEADING_ORDERING_DESC</option>
			<option value="a.state ASC">JSTATUS_ASC</option>
			<option value="a.state DESC">JSTATUS_DESC</option>
			<option value="a.title
ASC">JGLOBAL_TITLE_ASC</option>
			<option value="a.title
DESC">JGLOBAL_TITLE_DESC</option>
			<option value="a.access
ASC">JGRID_HEADING_ACCESS_ASC</option>
			<option value="a.access
DESC">JGRID_HEADING_ACCESS_DESC</option>
			<option value="a.language
ASC">JGRID_HEADING_LANGUAGE_ASC</option>
			<option value="a.language
DESC">JGRID_HEADING_LANGUAGE_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			class="input-mini"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
models/forms/group.xml000064400000005725151165643610011054 0ustar00<?xml
version="1.0" encoding="utf-8"?>
<form>
	<fieldset>
		<field
			name="id"
			type="number"
			label="JGLOBAL_FIELD_ID_LABEL"
			description="JGLOBAL_FIELD_ID_DESC"
			default="0"
			class="readonly"
			readonly="true"
		/>

		<field
			name="asset_id"
			type="hidden"
			filter="unset"
		/>

		<field
			name="context"
			type="hidden"
			class="readonly"
			readonly="true"
		/>

		<field
			name="title"
			type="text"
			label="JGLOBAL_TITLE"
			description="JFIELD_TITLE_DESC"
			class="input-xxlarge input-large-text"
			size="40"
			required="true"
		/>

		<field
			name="state"
			type="list"
			label="JSTATUS"
			description="JFIELD_PUBLISHED_DESC"
			class="chzn-color-state"
			default="1"
			>
			<option value="1">JPUBLISHED</option>
			<option value="0">JUNPUBLISHED</option>
			<option value="2">JARCHIVED</option>
			<option value="-2">JTRASHED</option>
		</field>

		<field
			name="checked_out"
			type="hidden"
			filter="unset"
		/>

		<field
			name="checked_out_time"
			type="hidden"
			filter="unset"
		/>

		<field
			name="created"
			type="calendar"
			label="JGLOBAL_CREATED_DATE"
			translateformat="true"
			showtime="true"
			size="22"
			filter="user_utc"
		/>

		<field
			name="created_by"
			type="user"
			label="JGLOBAL_FIELD_CREATED_BY_LABEL"
			description="JGLOBAL_FIELD_CREATED_BY_DESC"
		/>

		<field
			name="modified"
			type="calendar"
			label="JGLOBAL_FIELD_MODIFIED_LABEL"
			translateformat="true"
			showtime="true"
			size="22"
			class="readonly"
			readonly="true"
			filter="user_utc"
		/>

		<field
			name="modified_by"
			type="user"
			label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
			class="readonly"
			readonly="true"
			filter="unset"
		/>

		<field
			name="language"
			type="contentlanguage"
			label="JFIELD_LANGUAGE_LABEL"
			description="COM_FIELDS_FIELD_LANGUAGE_DESC"
			>
			<option value="*">JALL</option>
		</field>

		<field
			name="note"
			type="text"
			label="COM_FIELDS_FIELD_NOTE_LABEL"
			description="COM_FIELDS_FIELD_NOTE_DESC"
			class="span12"
			size="40"
		/>

		<field
			name="description"
			type="textarea"
			label="JGLOBAL_DESCRIPTION"
			size="40"
			filter="HTML"
		/>

		<field
			name="access"
			type="accesslevel"
			label="JFIELD_ACCESS_LABEL"
			description="JFIELD_ACCESS_DESC"
		/>

		<field
			name="rules"
			type="rules"
			label="JFIELD_RULES_LABEL"
			id="rules"
			translate_label="false"
			filter="rules"
			validate="rules"
			section="fieldgroup"
		/>

		<field
			name="ordering"
			type="text"
			label="JFIELD_ORDERING_LABEL"
			description="JFIELD_ORDERING_DESC"
			class="inputbox"
		/>
	</fieldset>

	<fields name="params"
label="COM_FIELDS_FIELD_BASIC_LABEL">
		<fieldset name="basic">
			<field
				name="display_readonly"
				type="radio"
				label="JFIELD_DISPLAY_READONLY_LABEL"
				description="JFIELD_DISPLAY_READONLY_DESC"
				class="btn-group btn-group-yesno"
				default="1"
				>
				<option value="1">JYES</option>
				<option value="0">JNO</option>
			</field>
		</fieldset>
	</fields>
</form>
models/group.php000064400000022063151165643610007707 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;

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

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

	/**
	 * 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)
	{
		// Alter the title for save as copy
		$input = JFactory::getApplication()->input;

		// Save new group as unpublished
		if ($input->get('task') == 'save2copy')
		{
			$data['state'] = 0;
		}

		return parent::save($data);
	}

	/**
	 * 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 = 'Group', $prefix =
'FieldsTable', $options = array())
	{
		$this->addTablePath(JPATH_ADMINISTRATOR .
'/components/com_fields/tables');

		return JTable::getInstance($name, $prefix, $options);
	}

	/**
	 * 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('filter.context');
		$jinput = JFactory::getApplication()->input;

		if (empty($context) && isset($data['context']))
		{
			$context = $data['context'];
			$this->setState('filter.context', $context);
		}

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

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

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

		if (!JFactory::getUser()->authorise('core.edit.state',
$context . '.fieldgroup.' . $jinput->get('id')))
		{
			// 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;
	}

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

		return JFactory::getUser()->authorise('core.delete',
$record->context . '.fieldgroup.' . (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();

		// Check for existing fieldgroup.
		if (!empty($record->id))
		{
			return $user->authorise('core.edit.state',
$record->context . '.fieldgroup.' . (int) $record->id);
		}

		// Default to component settings.
		return $user->authorise('core.edit.state',
$record->context);
	}

	/**
	 * Auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function populateState()
	{
		parent::populateState();

		$context =
JFactory::getApplication()->getUserStateFromRequest('com_fields.groups.context',
'context', 'com_fields', 'CMD');
		$this->setState('filter.context', $context);
	}

	/**
	 * 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 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')
	{
		parent::preprocessForm($form, $data, $group);

		$parts =
FieldsHelper::extract($this->state->get('filter.context'));

		// Extract the component name
		$component = $parts[0];

		// Extract the optional section name
		$section = (count($parts) > 1) ? $parts[1] : null;

		if ($parts)
		{
			// Set the access control rules field component value.
			$form->setFieldAttribute('rules', 'component',
$component);
		}

		if ($section !== null)
		{
			// Looking first in the component models/forms folder
			$path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' .
$component . '/models/forms/fieldgroup/' . $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'));
				}
			}
		}
	}

	/**
	 * 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)
	{
		if (!JFactory::getUser()->authorise('core.admin',
'com_fields'))
		{
			if (isset($data['rules']))
			{
				unset($data['rules']);
			}
		}

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

	/**
	 * 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.group.data',
array());

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

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

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

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

		return $data;
	}

	/**
	 * 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)
	{
		if ($item = parent::getItem($pk))
		{
			// Prime required properties.
			if (empty($item->id))
			{
				$item->context = $this->getState('filter.context');
			}

			if (property_exists($item, 'params'))
			{
				$item->params = new Registry($item->params);
			}
		}

		return $item;
	}

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

		parent::cleanCache($context);
	}
}
models/groups.php000064400000014411151165643610010070 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

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

/**
 * Groups Model
 *
 * @since  3.7.0
 */
class FieldsModelGroups extends JModelList
{
	/**
	 * Context string for the model type.  This is used to handle uniqueness
	 * when dealing with the getStoreId() method and caching data structures.
	 *
	 * @var    string
	 * @since   3.7.0
	 */
	protected $context = 'com_fields.groups';

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration
settings.
	 *
	 * @see     JModelLegacy
	 * @since   3.7.0
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields']))
		{
			$config['filter_fields'] = array(
				'id', 'a.id',
				'title', 'a.title',
				'type', 'a.type',
				'state', 'a.state',
				'access', 'a.access',
				'access_level',
				'language', 'a.language',
				'ordering', 'a.ordering',
				'checked_out', 'a.checked_out',
				'checked_out_time', 'a.checked_out_time',
				'created', 'a.created',
				'created_by', 'a.created_by',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * This method should only be called once per instantiation and is
designed
	 * to be called on the first call to the getState() method unless the
model
	 * configuration flag to ignore the request is set.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string  $ordering   An optional ordering field.
	 * @param   string  $direction  An optional direction (asc|desc).
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function populateState($ordering = null, $direction = null)
	{
		// List state information.
		parent::populateState('a.ordering', 'asc');

		$context = $this->getUserStateFromRequest($this->context .
'.context', 'context', 'com_content',
'CMD');
		$this->setState('filter.context', $context);
	}

	/**
	 * Method to get a store id based on the model configuration state.
	 *
	 * This is necessary because the model is used by the component and
	 * different modules that might need different sets of data or different
	 * ordering requirements.
	 *
	 * @param   string  $id  An identifier string to generate the store id.
	 *
	 * @return  string  A store id.
	 *
	 * @since   3.7.0
	 */
	protected function getStoreId($id = '')
	{
		// Compile the store id.
		$id .= ':' . $this->getState('filter.search');
		$id .= ':' . $this->getState('filter.context');
		$id .= ':' . $this->getState('filter.state');
		$id .= ':' .
print_r($this->getState('filter.language'), true);

		return parent::getStoreId($id);
	}

	/**
	 * Method to get a JDatabaseQuery object for retrieving the data set from
a database.
	 *
	 * @return  JDatabaseQuery   A JDatabaseQuery object to retrieve the data
set.
	 *
	 * @since   3.7.0
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$user = JFactory::getUser();

		// Select the required fields from the table.
		$query->select($this->getState('list.select',
'a.*'));
		$query->from('#__fields_groups AS a');

		// Join over the language
		$query->select('l.title AS language_title, l.image AS
language_image')
			->join('LEFT', $db->quoteName('#__languages')
. ' AS l ON l.lang_code = a.language');

		// Join over the users for the checked out user.
		$query->select('uc.name AS
editor')->join('LEFT', '#__users AS uc ON
uc.id=a.checked_out');

		// Join over the asset groups.
		$query->select('ag.title AS
access_level')->join('LEFT', '#__viewlevels AS ag ON
ag.id = a.access');

		// Join over the users for the author.
		$query->select('ua.name AS
author_name')->join('LEFT', '#__users AS ua ON ua.id
= a.created_by');

		// Filter by context
		if ($context = $this->getState('filter.context',
'com_fields'))
		{
			$query->where('a.context = ' . $db->quote($context));
		}

		// Filter by access level.
		if ($access = $this->getState('filter.access'))
		{
			if (is_array($access))
			{
				$access = ArrayHelper::toInteger($access);
				$query->where('a.access in (' . implode(',',
$access) . ')');
			}
			else
			{
				$query->where('a.access = ' . (int) $access);
			}
		}

		// Implement View Level Access
		if (!$user->authorise('core.admin'))
		{
			$groups = implode(',', $user->getAuthorisedViewLevels());
			$query->where('a.access IN (' . $groups . ')');
		}

		// Filter by published state
		$state = $this->getState('filter.state');

		if (is_numeric($state))
		{
			$query->where('a.state = ' . (int) $state);
		}
		elseif (!$state)
		{
			$query->where('a.state IN (0, 1)');
		}

		// Filter by search in title
		$search = $this->getState('filter.search');

		if (!empty($search))
		{
			if (stripos($search, 'id:') === 0)
			{
				$query->where('a.id = ' . (int) substr($search, 3));
			}
			else
			{
				$search = $db->quote('%' . str_replace(' ',
'%', $db->escape(trim($search), true) . '%'));
				$query->where('a.title LIKE ' . $search);
			}
		}

		// Filter on the language.
		if ($language = $this->getState('filter.language'))
		{
			$language = (array) $language;

			foreach ($language as $key => $l)
			{
				$language[$key] = $db->quote($l);
			}

			$query->where('a.language in (' . implode(',',
$language) . ')');
		}

		// Add the list ordering clause
		$listOrdering = $this->getState('list.ordering',
'a.ordering');
		$listDirn = $db->escape($this->getState('list.direction',
'ASC'));

		$query->order($db->escape($listOrdering) . ' ' .
$listDirn);

		return $query;
	}

	/**
	 * Gets an array of objects from the results of database query.
	 *
	 * @param   string   $query       The query.
	 * @param   integer  $limitstart  Offset.
	 * @param   integer  $limit       The number of records.
	 *
	 * @return  array  An array of results.
	 *
	 * @since   3.8.7
	 * @throws  RuntimeException
	 */
	protected function _getList($query, $limitstart = 0, $limit = 0)
	{
		$result = parent::_getList($query, $limitstart, $limit);

		if (is_array($result))
		{
			foreach ($result as $group)
			{
				$group->params = new Registry($group->params);
			}
		}

		return $result;
	}
}
tables/field.php000064400000014170151165643610007625 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @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;
	}
}
tables/group.php000064400000010721151165643610007674 0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Groups Table
 *
 * @since  3.7.0
 */
class FieldsTableGroup extends JTable
{
	/**
	 * Class constructor.
	 *
	 * @param   JDatabaseDriver  $db  JDatabaseDriver object.
	 *
	 * @since   3.7.0
	 */
	public function __construct($db = null)
	{
		parent::__construct('#__fields_groups', '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;
		}

		// 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 a title.
		if (trim($this->title) == '')
		{
			$this->setError(JText::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP'));

			return false;
		}

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

		if ($this->id)
		{
			$this->modified = $date->toSql();
			$this->modified_by = $user->get('id');
		}
		else
		{
			if (!(int) $this->created)
			{
				$this->created = $date->toSql();
			}

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

		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()
	{
		$component = explode('.', $this->context);

		return $component[0] . '.fieldgroup.' . (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)
	{
		$component = explode('.', $this->context);
		$db = $this->getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('id'))
			->from($db->quoteName('#__assets'))
			->where($db->quoteName('name') . ' = ' .
$db->quote($component[0]));
		$db->setQuery($query);

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

		return parent::_getAssetParentId($table, $id);
	}
}
views/field/tmpl/edit.php000064400000007615151165643610011417
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('behavior.formvalidator');
JHtml::_('behavior.keepalive');
JHtml::_('behavior.tabstate');
JHtml::_('formbehavior.chosen', '#jform_catid', null,
array('disable_search_threshold' => 0 ));
JHtml::_('formbehavior.chosen', 'select');

$app = JFactory::getApplication();
$input = $app->input;

JFactory::getDocument()->addScriptDeclaration('
	Joomla.submitbutton = function(task)
	{
		if (task == "field.cancel" ||
document.formvalidator.isValid(document.getElementById("item-form")))
		{
			Joomla.submitform(task, document.getElementById("item-form"));
		}
	};
	jQuery(document).ready(function() {
		jQuery("#jform_title").data("dp-old-value",
jQuery("#jform_title").val());
		jQuery("#jform_title").change(function(data, handler) {
			if(jQuery("#jform_title").data("dp-old-value") ==
jQuery("#jform_label").val()) {
				jQuery("#jform_label").val(jQuery("#jform_title").val());
			}

			jQuery("#jform_title").data("dp-old-value",
jQuery("#jform_title").val());
		});
	});
');

?>

<form action="<?php echo
JRoute::_('index.php?option=com_fields&context=' .
$input->getCmd('context', 'com_content') .
'&layout=edit&id=' . (int) $this->item->id);
?>" method="post" name="adminForm"
id="item-form" class="form-validate">
	<?php echo JLayoutHelper::render('joomla.edit.title_alias',
$this); ?>
	<div class="form-horizontal">
		<?php echo JHtml::_('bootstrap.startTabSet',
'myTab', array('active' => 'general'));
?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'general',
JText::_('COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL', true)); ?>
		<div class="row-fluid">
			<div class="span9">
				<?php echo $this->form->renderField('type'); ?>
				<?php echo $this->form->renderField('name'); ?>
				<?php echo $this->form->renderField('label'); ?>
				<?php echo $this->form->renderField('description');
?>
				<?php echo $this->form->renderField('required');
?>
				<?php echo
$this->form->renderField('default_value'); ?>

				<?php foreach
($this->form->getFieldsets('fieldparams') as $name =>
$fieldSet) : ?>
					<?php foreach ($this->form->getFieldset($name) as $field) :
?>
						<?php echo $field->renderField(); ?>
					<?php endforeach; ?>
				<?php endforeach; ?>

			</div>
			<div class="span3">
				<?php $this->set('fields',
						array(
							array(
								'published',
								'state',
								'enabled',
							),
							'group_id',
							'assigned_cat_ids',
							'access',
							'language',
							'note',
						)
				); ?>
				<?php echo JLayoutHelper::render('joomla.edit.global',
$this); ?>
				<?php $this->set('fields', null); ?>
			</div>
		</div>
		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php $this->set('ignore_fieldsets',
array('fieldparams')); ?>
		<?php echo JLayoutHelper::render('joomla.edit.params',
$this); ?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'publishing', JText::_('JGLOBAL_FIELDSET_PUBLISHING',
true)); ?>
		<div class="row-fluid form-horizontal-desktop">
			<div class="span6">
				<?php echo
JLayoutHelper::render('joomla.edit.publishingdata', $this); ?>
			</div>
			<div class="span6">
			</div>
		</div>
		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php if ($this->canDo->get('core.admin')) : ?>
			<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'rules', JText::_('JGLOBAL_ACTION_PERMISSIONS_LABEL',
true)); ?>
			<?php echo $this->form->getInput('rules'); ?>
			<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php endif; ?>
		<?php echo JHtml::_('bootstrap.endTabSet'); ?>
		<?php echo $this->form->getInput('context'); ?>
		<input type="hidden" name="task"
value="" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/field/view.html.php000064400000006516151165643610011432
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Field View
 *
 * @since  3.7.0
 */
class FieldsViewField extends JViewLegacy
{
	/**
	 * @var  JForm
	 *
	 * @since   3.7.0
	 */
	protected $form;

	/**
	 * @var  JObject
	 *
	 * @since   3.7.0
	 */
	protected $item;

	/**
	 * @var  JObject
	 *
	 * @since   3.7.0
	 */
	protected $state;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.7.0
	 */
	public function display($tpl = null)
	{
		$this->form  = $this->get('Form');
		$this->item  = $this->get('Item');
		$this->state = $this->get('State');

		$this->canDo =
JHelperContent::getActions($this->state->get('field.component'),
'field', $this->item->id);

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		JFactory::getApplication()->input->set('hidemainmenu',
true);

		$this->addToolbar();

		return parent::display($tpl);
	}

	/**
	 * Adds the toolbar.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function addToolbar()
	{
		$component = $this->state->get('field.component');
		$section   = $this->state->get('field.section');
		$userId    = JFactory::getUser()->get('id');
		$canDo     = $this->canDo;

		$isNew      = ($this->item->id == 0);
		$checkedOut = !($this->item->checked_out == 0 ||
$this->item->checked_out == $userId);

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Load component language file
		$lang = JFactory::getLanguage();
		$lang->load($component, JPATH_ADMINISTRATOR)
		|| $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR .
'/components/' . $component));

		$title = JText::sprintf('COM_FIELDS_VIEW_FIELD_' . ($isNew ?
'ADD' : 'EDIT') . '_TITLE',
JText::_(strtoupper($component)));

		// Prepare the toolbar.
		JToolbarHelper::title(
			$title,
			'puzzle field-' . ($isNew ? 'add' :
'edit') . ' ' . substr($component, 4) . ($section ?
"-$section" : '') . '-field-' .
			($isNew ? 'add' : 'edit')
		);

		// For new records, check the create permission.
		if ($isNew)
		{
			JToolbarHelper::apply('field.apply');
			JToolbarHelper::save('field.save');
			JToolbarHelper::save2new('field.save2new');
		}

		// If not checked out, can save the item.
		elseif (!$checkedOut && ($canDo->get('core.edit') ||
($canDo->get('core.edit.own') &&
$this->item->created_user_id == $userId)))
		{
			JToolbarHelper::apply('field.apply');
			JToolbarHelper::save('field.save');

			if ($canDo->get('core.create'))
			{
				JToolbarHelper::save2new('field.save2new');
			}
		}

		// If an existing item, can save to a copy.
		if (!$isNew && $canDo->get('core.create'))
		{
			JToolbarHelper::save2copy('field.save2copy');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('field.cancel');
		}
		else
		{
			JToolbarHelper::cancel('field.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS_EDIT');
	}
}
views/fields/tmpl/default.php000064400000021001151165643610012262
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$app       = JFactory::getApplication();
$user      = JFactory::getUser();
$userId    = $user->get('id');
$context   =
$this->escape($this->state->get('filter.context'));
$component = $this->state->get('filter.component');
$section   = $this->state->get('filter.section');
$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirn  =
$this->escape($this->state->get('list.direction'));
$ordering  = ($listOrder == 'a.ordering');
$saveOrder = ($listOrder == 'a.ordering' &&
strtolower($listDirn) == 'asc');

// The category object of the component
$category = JCategories::getInstance(str_replace('com_',
'', $component) . '.' . $section);

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

if ($saveOrder)
{
	$saveOrderingUrl =
'index.php?option=com_fields&task=fields.saveOrderAjax&tmpl=component';
	JHtml::_('sortablelist.sortable', 'fieldList',
'adminForm', strtolower($listDirn), $saveOrderingUrl, false,
true);
}
?>

<form action="<?php echo
JRoute::_('index.php?option=com_fields&view=fields');
?>" method="post" name="adminForm"
id="adminForm">
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
		<div id="filter-bar" class="js-stools-container-bar
pull-left">
			<div class="btn-group pull-left">
				<?php echo
$this->filterForm->getField('context')->input; ?>
			</div>&nbsp;
		</div>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="fieldList">
				<thead>
					<tr>
						<th width="1%" class="nowrap center
hidden-phone">
							<?php echo JHtml::_('searchtools.sort', '',
'a.ordering', $listDirn, $listOrder, null, 'asc',
'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
						</th>
						<th width="1%" class="center">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th width="1%" class="nowrap center">
							<?php echo JHtml::_('searchtools.sort',
'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
						</th>
						<th>
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder);
?>
						</th>
						<th>
							<?php echo JHtml::_('searchtools.sort',
'COM_FIELDS_FIELD_TYPE_LABEL', 'a.type', $listDirn,
$listOrder); ?>
						</th>
						<th>
							<?php echo JHtml::_('searchtools.sort',
'COM_FIELDS_FIELD_GROUP_LABEL', 'g.title', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ACCESS', 'a.access', $listDirn,
$listOrder); ?>
						</th>
						<th width="5%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn,
$listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="9">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
					<?php foreach ($this->items as $i => $item) : ?>
						<?php $ordering   = ($listOrder == 'a.ordering'); ?>
						<?php $canEdit    = $user->authorise('core.edit',
$component . '.field.' . $item->id); ?>
						<?php $canCheckin = $user->authorise('core.admin',
'com_checkin') || $item->checked_out == $userId ||
$item->checked_out == 0; ?>
						<?php $canEditOwn = $user->authorise('core.edit.own',
$component . '.field.' . $item->id) &&
$item->created_user_id == $userId; ?>
						<?php $canChange  =
$user->authorise('core.edit.state', $component .
'.field.' . $item->id) && $canCheckin; ?>
						<tr class="row<?php echo $i % 2; ?>"
item-id="<?php echo $item->id ?>">
							<td class="order nowrap center hidden-phone">
								<?php $iconClass = ''; ?>
								<?php if (!$canChange) : ?>
									<?php $iconClass = ' inactive'; ?>
								<?php elseif (!$saveOrder) : ?>
									<?php $iconClass = ' inactive tip-top hasTooltip"
title="' . JHtml::tooltipText('JORDERINGDISABLED');
?>
								<?php endif; ?>
								<span class="sortable-handler<?php echo $iconClass;
?>">
									<span class="icon-menu"
aria-hidden="true"></span>
								</span>
								<?php if ($canChange && $saveOrder) : ?>
									<input type="text" style="display:none"
name="order[]" size="5" value="<?php echo
$item->ordering; ?>" />
								<?php endif; ?>
							</td>
							<td class="center">
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							</td>
							<td class="center">
								<div class="btn-group">
									<?php echo JHtml::_('jgrid.published',
$item->state, $i, 'fields.', $canChange, 'cb');
?>
									<?php // Create dropdown items and render the dropdown list.
?>
									<?php if ($canChange) : ?>
										<?php JHtml::_('actionsdropdown.' . ((int)
$item->state === 2 ? 'un' : '') .
'archive', 'cb' . $i, 'fields'); ?>
										<?php JHtml::_('actionsdropdown.' . ((int)
$item->state === -2 ? 'un' : '') .
'trash', 'cb' . $i, 'fields'); ?>
										<?php echo JHtml::_('actionsdropdown.render',
$this->escape($item->title)); ?>
									<?php endif; ?>
								</div>
							</td>
							<td>
								<div class="pull-left break-word">
									<?php if ($item->checked_out) : ?>
										<?php echo JHtml::_('jgrid.checkedout', $i,
$item->editor, $item->checked_out_time, 'fields.',
$canCheckin); ?>
									<?php endif; ?>
									<?php if ($canEdit || $canEditOwn) : ?>
										<a href="<?php echo
JRoute::_('index.php?option=com_fields&task=field.edit&id='
. $item->id . '&context=' . $context); ?>">
											<?php echo $this->escape($item->title); ?></a>
									<?php else : ?>
										<?php echo $this->escape($item->title); ?>
									<?php endif; ?>
									<span class="small break-word">
										<?php if (empty($item->note)) : ?>
											<?php echo JText::sprintf('JGLOBAL_LIST_NAME',
$this->escape($item->name)); ?>
										<?php else : ?>
											<?php echo JText::sprintf('JGLOBAL_LIST_NAME_NOTE',
$this->escape($item->name), $this->escape($item->note)); ?>
										<?php endif; ?>
									</span>
									<div class="small">
										<?php if ($category) : ?>
											<?php echo JText::_('JCATEGORY') . ': ';
?>
											<?php $categories =
FieldsHelper::getAssignedCategoriesTitles($item->id); ?>
											<?php if ($categories) : ?>
												<?php echo implode(', ', $categories); ?>
											<?php else : ?>
												<?php echo JText::_('JALL'); ?>
											<?php endif; ?>
										<?php endif; ?>
									</div>
								</div>
							</td>
							<td class="small">
								<?php echo $this->escape($item->type); ?>
							</td>
							<td>
								<?php echo $this->escape($item->group_title); ?>
							</td>
							<td class="small hidden-phone">
								<?php echo $this->escape($item->access_level); ?>
							</td>
							<td class="small nowrap hidden-phone">
								<?php echo
JLayoutHelper::render('joomla.content.language', $item); ?>
							</td>
							<td class="center hidden-phone">
								<span><?php echo (int) $item->id; ?></span>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
			<?php //Load the batch processing form. ?>
			<?php if ($user->authorise('core.create', $component)
				&& $user->authorise('core.edit', $component)
				&& $user->authorise('core.edit.state',
$component)) : ?>
				<?php echo JHtml::_(
						'bootstrap.renderModal',
						'collapseModal',
						array(
							'title' =>
JText::_('COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS'),
							'footer' =>
$this->loadTemplate('batch_footer')
						),
						$this->loadTemplate('batch_body')
					); ?>
			<?php endif; ?>
		<?php endif; ?>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/fields/tmpl/default_batch_body.php000064400000004450151165643610014451
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JHtml::_('formbehavior.chosen', 'select');
JFactory::getDocument()->addScriptDeclaration(
	'
		jQuery(document).ready(function($){
			if ($("#batch-group-id").length){var batchSelector =
$("#batch-group-id");}
			if ($("#batch-copy-move").length) {
				$("#batch-copy-move").hide();
				batchSelector.on("change", function(){
					if (batchSelector.val() != 0 || batchSelector.val() != "") {
						$("#batch-copy-move").show();
					} else {
						$("#batch-copy-move").hide();
					}
				});
			}
		});
			'
);

$context   =
$this->escape($this->state->get('filter.context'));
?>

<div class="container-fluid">
	<div class="row-fluid">
		<div class="control-group span6">
			<div class="controls">
				<?php echo
JLayoutHelper::render('joomla.html.batch.language', array());
?>
			</div>
		</div>
		<div class="control-group span6">
			<div class="controls">
				<?php echo
JLayoutHelper::render('joomla.html.batch.access', array()); ?>
			</div>
		</div>
	</div>
	<div class="row-fluid">
		<div class="control-group span6">
			<div class="controls">
				<?php $options = array(
					JHtml::_('select.option', 'c',
JText::_('JLIB_HTML_BATCH_COPY')),
					JHtml::_('select.option', 'm',
JText::_('JLIB_HTML_BATCH_MOVE'))
				);
				?>
				<label id="batch-choose-action-lbl"
for="batch-choose-action"><?php echo
JText::_('COM_FIELDS_BATCH_GROUP_LABEL'); ?></label>
				<div id="batch-choose-action"
class="control-group">
					<select name="batch[group_id]" class="inputbox"
id="batch-group-id">
						<option value=""><?php echo
JText::_('JLIB_HTML_BATCH_NO_CATEGORY'); ?></option>
						<option value="nogroup"><?php echo
JText::_('COM_FIELDS_BATCH_GROUP_OPTION_NONE');
?></option>
						<?php echo JHtml::_('select.options',
$this->get('Groups'), 'value', 'text');
?>
					</select>
				</div>
				<div id="batch-copy-move" class="control-group
radio">
					<?php echo JText::_('JLIB_HTML_BATCH_MOVE_QUESTION');
?>
					<?php echo JHtml::_('select.radiolist', $options,
'batch[move_copy]', '', 'value',
'text', 'm'); ?>
				</div>
			</div>
		</div>
	</div>
</div>
views/fields/tmpl/default_batch_footer.php000064400000001307151165643610015010
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

?>
<button type="button" class="btn"
onclick="document.getElementById('batch-field-id').value='';document.getElementById('batch-access').value='';document.getElementById('batch-language-id').value=''"
data-dismiss="modal">
	<?php echo JText::_('JCANCEL'); ?>
</button>
<button type="submit" class="btn btn-success"
onclick="Joomla.submitbutton('field.batch');return
false;">
	<?php echo JText::_('JGLOBAL_BATCH_PROCESS'); ?>
</button>
views/fields/tmpl/modal.php000064400000011210151165643610011733
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

defined('_JEXEC') or die;

if (JFactory::getApplication()->isClient('site'))
{
	JSession::checkToken('get') or
die(JText::_('JINVALID_TOKEN'));
}

JHtml::_('behavior.core');
JHtml::_('bootstrap.tooltip', '.hasTooltip',
array('placement' => 'bottom'));
JHtml::_('bootstrap.popover', '.hasPopover',
array('placement' => 'bottom'));
JHtml::_('formbehavior.chosen', 'select');
JHtml::_('script', 'com_fields/admin-fields-modal.js',
array('version' => 'auto', 'relative'
=> true));

// Special case for the search field tooltip.
$searchFilterDesc =
$this->filterForm->getFieldAttribute('search',
'description', null, 'filter');
JHtml::_('bootstrap.tooltip', '#filter_search',
array('title' => JText::_($searchFilterDesc),
'placement' => 'bottom'));

$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirn  =
$this->escape($this->state->get('list.direction'));
$editor    =
JFactory::getApplication()->input->get('editor',
'', 'cmd');
?>
<div class="container-popup">

	<form action="<?php echo
JRoute::_('index.php?option=com_fields&view=fields&layout=modal&tmpl=component&editor='
. $editor . '&' . JSession::getFormToken() . '=1');
?>" method="post" name="adminForm"
id="adminForm">

		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="moduleList">
				<thead>
					<tr>
						<th width="1%" class="nowrap center">
							<?php echo JHtml::_('searchtools.sort',
'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
						</th>
						<th class="title">
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder);
?>
						</th>
						<th width="15%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'COM_FIELDS_FIELD_GROUP_LABEL', 'g.title', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'COM_FIELDS_FIELD_TYPE_LABEL', 'a.type', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ACCESS', 'a.access', $listDirn,
$listOrder); ?>
						</th>
						<th width="10%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn,
$listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="8">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
					<?php
					$iconStates = array(
						-2 => 'icon-trash',
						0  => 'icon-unpublish',
						1  => 'icon-publish',
						2  => 'icon-archive',
					);
					foreach ($this->items as $i => $item) :
					?>
					<tr class="row<?php echo $i % 2; ?>">
						<td class="center">
							<span class="<?php echo
$iconStates[$this->escape($item->state)]; ?>"
aria-hidden="true"></span>
						</td>
						<td class="has-context">
							<a class="btn btn-small btn-block btn-success"
href="#" onclick="Joomla.fieldIns('<?php echo
$this->escape($item->id); ?>', '<?php echo
$this->escape($editor); ?>');"><?php echo
$this->escape($item->title); ?></a>
						</td>
						<td class="small hidden-phone">
							<a class="btn btn-small btn-block btn-warning"
href="#" onclick="Joomla.fieldgroupIns('<?php echo
$this->escape($item->group_id); ?>', '<?php echo
$this->escape($editor); ?>');"><?php echo
$item->group_id ? $this->escape($item->group_title) :
JText::_('JNONE'); ?></a>
						</td>
						<td class="small hidden-phone">
							<?php echo $item->type; ?>
						</td>
						<td class="small hidden-phone">
							<?php echo $this->escape($item->access_level); ?>
						</td>
						<td class="small hidden-phone">
							<?php echo
JLayoutHelper::render('joomla.content.language', $item); ?>
						</td>
						<td class="hidden-phone">
							<?php echo (int) $item->id; ?>
						</td>
					</tr>
				<?php endforeach; ?>
				</tbody>
			</table>
		<?php endif; ?>

		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>

	</form>
</div>
views/fields/view.html.php000064400000011713151165643610011610
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Fields View
 *
 * @since  3.7.0
 */
class FieldsViewFields extends JViewLegacy
{
	/**
	 * @var  JForm
	 *
	 * @since  3.7.0
	 */
	public $filterForm;

	/**
	 * @var  array
	 *
	 * @since  3.7.0
	 */
	public $activeFilters;

	/**
	 * @var  array
	 *
	 * @since  3.7.0
	 */
	protected $items;

	/**
	 * @var  JPagination
	 *
	 * @since  3.7.0
	 */
	protected $pagination;

	/**
	 * @var  JObject
	 *
	 * @since  3.7.0
	 */
	protected $state;

	/**
	 * @var  string
	 *
	 * @since  3.7.0
	 */
	protected $sidebar;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.7.0
	 */
	public function display($tpl = null)
	{
		$this->state         = $this->get('State');
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Display a warning if the fields system plugin is disabled
		if (!JPluginHelper::isEnabled('system', 'fields'))
		{
			$link =
JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id='
. FieldsHelper::getFieldsPluginId());
			JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED',
$link), 'warning');
		}

		// Only add toolbar when not in modal window.
		if ($this->getLayout() !== 'modal')
		{
			$this->addToolbar();
			FieldsHelper::addSubmenu($this->state->get('filter.context'),
'fields');
			$this->sidebar = JHtmlSidebar::render();
		}

		return parent::display($tpl);
	}

	/**
	 * Adds the toolbar.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function addToolbar()
	{
		$fieldId   = $this->state->get('filter.field_id');
		$component = $this->state->get('filter.component');
		$section   = $this->state->get('filter.section');
		$canDo     = JHelperContent::getActions($component, 'field',
$fieldId);

		// Get the toolbar object instance
		$bar = JToolBar::getInstance('toolbar');

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Load extension language file
		$lang = JFactory::getLanguage();
		$lang->load($component, JPATH_ADMINISTRATOR)
		|| $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR .
'/components/' . $component));

		$title = JText::sprintf('COM_FIELDS_VIEW_FIELDS_TITLE',
JText::_(strtoupper($component)));

		// Prepare the toolbar.
		JToolbarHelper::title($title, 'puzzle fields ' .
substr($component, 4) . ($section ? "-$section" : '') .
'-fields');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('field.add');
		}

		if ($canDo->get('core.edit') ||
$canDo->get('core.edit.own'))
		{
			JToolbarHelper::editList('field.edit');
		}

		if ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::publish('fields.publish',
'JTOOLBAR_PUBLISH', true);
			JToolbarHelper::unpublish('fields.unpublish',
'JTOOLBAR_UNPUBLISH', true);
			JToolbarHelper::archiveList('fields.archive');
		}

		if (JFactory::getUser()->authorise('core.admin'))
		{
			JToolbarHelper::checkin('fields.checkin');
		}

		// Add a batch button
		if ($canDo->get('core.create') &&
$canDo->get('core.edit') &&
$canDo->get('core.edit.state'))
		{
			$title = JText::_('JTOOLBAR_BATCH');

			// Instantiate a new JLayoutFile instance and render the batch button
			$layout = new JLayoutFile('joomla.toolbar.batch');

			$dhtml = $layout->render(
				array(
					'title' => $title,
				)
			);

			$bar->appendButton('Custom', $dhtml, 'batch');
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences($component);
		}

		if ($this->state->get('filter.state') == -2 &&
$canDo->get('core.delete', $component))
		{
			JToolbarHelper::deleteList('', 'fields.delete',
'JTOOLBAR_EMPTY_TRASH');
		}
		elseif ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::trash('fields.trash');
		}

		JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS');
	}

	/**
	 * Returns the sort fields.
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	protected function getSortFields()
	{
		return array(
			'a.ordering' =>
JText::_('JGRID_HEADING_ORDERING'),
			'a.state'    => JText::_('JSTATUS'),
			'a.title'    => JText::_('JGLOBAL_TITLE'),
			'a.type'     =>
JText::_('COM_FIELDS_FIELD_TYPE_LABEL'),
			'a.access'   => JText::_('JGRID_HEADING_ACCESS'),
			'a.language' =>
JText::_('JGRID_HEADING_LANGUAGE'),
			'a.id'       => JText::_('JGRID_HEADING_ID'),
		);
	}
}
views/group/tmpl/edit.php000064400000005516151165643610011466
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('behavior.formvalidator');
JHtml::_('behavior.keepalive');
JHtml::_('behavior.tabstate');
JHtml::_('formbehavior.chosen', 'select');

$app = JFactory::getApplication();
$input = $app->input;

JFactory::getDocument()->addScriptDeclaration('
	Joomla.submitbutton = function(task)
	{
		if (task == "group.cancel" ||
document.formvalidator.isValid(document.getElementById("item-form")))
		{
			Joomla.submitform(task, document.getElementById("item-form"));
		}
	};
');
?>

<form action="<?php echo
JRoute::_('index.php?option=com_fields&layout=edit&id=' .
(int) $this->item->id); ?>" method="post"
name="adminForm" id="item-form"
class="form-validate">
	<?php echo JLayoutHelper::render('joomla.edit.title_alias',
$this); ?>
	<div class="form-horizontal">
		<?php echo JHtml::_('bootstrap.startTabSet',
'myTab', array('active' => 'general'));
?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'general',
JText::_('COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL', true)); ?>
		<div class="row-fluid">
			<div class="span9">
				<?php echo $this->form->renderField('label'); ?>
				<?php echo $this->form->renderField('description');
?>
			</div>
			<div class="span3">
				<?php $this->set('fields',
						array(
							array(
								'published',
								'state',
								'enabled',
							),
							'access',
							'language',
							'note',
						)
				); ?>
				<?php echo JLayoutHelper::render('joomla.edit.global',
$this); ?>
				<?php $this->set('fields', null); ?>
			</div>
		</div>
		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'publishing', JText::_('JGLOBAL_FIELDSET_PUBLISHING',
true)); ?>
		<div class="row-fluid form-horizontal-desktop">
			<div class="span6">
				<?php echo
JLayoutHelper::render('joomla.edit.publishingdata', $this); ?>
			</div>
			<div class="span6">
			</div>
		</div>
		<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php $this->set('ignore_fieldsets',
array('fieldparams')); ?>
		<?php echo JLayoutHelper::render('joomla.edit.params',
$this); ?>
		<?php if ($this->canDo->get('core.admin')) : ?>
			<?php echo JHtml::_('bootstrap.addTab', 'myTab',
'rules', JText::_('JGLOBAL_ACTION_PERMISSIONS_LABEL',
true)); ?>
			<?php echo $this->form->getInput('rules'); ?>
			<?php echo JHtml::_('bootstrap.endTab'); ?>
		<?php endif; ?>
		<?php echo JHtml::_('bootstrap.endTabSet'); ?>
		<?php echo $this->form->getInput('context'); ?>
		<input type="hidden" name="task"
value="" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/group/view.html.php000064400000007116151165643620011501
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Group View
 *
 * @since  3.7.0
 */
class FieldsViewGroup extends JViewLegacy
{
	/**
	 * @var  JForm
	 *
	 * @since  3.7.0
	 */
	protected $form;

	/**
	 * @var  JObject
	 *
	 * @since  3.7.0
	 */
	protected $item;

	/**
	 * @var  JObject
	 *
	 * @since  3.7.0
	 */
	protected $state;

	/**
	 * The actions the user is authorised to perform
	 *
	 * @var  JObject
	 *
	 * @since  3.7.0
	 */
	protected $canDo;


	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.7.0
	 */
	public function display($tpl = null)
	{
		$this->form  = $this->get('Form');
		$this->item  = $this->get('Item');
		$this->state = $this->get('State');

		$component = '';
		$parts     =
FieldsHelper::extract($this->state->get('filter.context'));

		if ($parts)
		{
			$component = $parts[0];
		}

		$this->canDo = JHelperContent::getActions($component,
'fieldgroup', $this->item->id);

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		JFactory::getApplication()->input->set('hidemainmenu',
true);

		$this->addToolbar();

		return parent::display($tpl);
	}

	/**
	 * Adds the toolbar.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function addToolbar()
	{
		$component = '';
		$parts     =
FieldsHelper::extract($this->state->get('filter.context'));

		if ($parts)
		{
			$component = $parts[0];
		}

		$userId    = JFactory::getUser()->get('id');
		$canDo     = $this->canDo;

		$isNew      = ($this->item->id == 0);
		$checkedOut = !($this->item->checked_out == 0 ||
$this->item->checked_out == $userId);

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Load component language file
		$lang = JFactory::getLanguage();
		$lang->load($component, JPATH_ADMINISTRATOR)
		|| $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR .
'/components/' . $component));

		$title = JText::sprintf('COM_FIELDS_VIEW_GROUP_' . ($isNew ?
'ADD' : 'EDIT') . '_TITLE',
JText::_(strtoupper($component)));

		// Prepare the toolbar.
		JToolbarHelper::title(
			$title,
			'puzzle field-' . ($isNew ? 'add' :
'edit') . ' ' . substr($component, 4) .
'-group-' .
			($isNew ? 'add' : 'edit')
		);

		// For new records, check the create permission.
		if ($isNew)
		{
			JToolbarHelper::apply('group.apply');
			JToolbarHelper::save('group.save');
			JToolbarHelper::save2new('group.save2new');
		}

		// If not checked out, can save the item.
		elseif (!$checkedOut && ($canDo->get('core.edit') ||
($canDo->get('core.edit.own') &&
$this->item->created_by == $userId)))
		{
			JToolbarHelper::apply('group.apply');
			JToolbarHelper::save('group.save');

			if ($canDo->get('core.create'))
			{
				JToolbarHelper::save2new('group.save2new');
			}
		}

		// If an existing item, can save to a copy.
		if (!$isNew && $canDo->get('core.create'))
		{
			JToolbarHelper::save2copy('group.save2copy');
		}

		if (empty($this->item->id))
		{
			JToolbarHelper::cancel('group.cancel');
		}
		else
		{
			JToolbarHelper::cancel('group.cancel',
'JTOOLBAR_CLOSE');
		}

		JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS_EDIT');
	}
}
views/groups/tmpl/default.php000064400000016216151165643620012350
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

// Include the component HTML helpers.
JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html');

JHtml::_('bootstrap.tooltip');
JHtml::_('behavior.multiselect');
JHtml::_('formbehavior.chosen', 'select');

$app       = JFactory::getApplication();
$user      = JFactory::getUser();
$userId    = $user->get('id');

$component = '';
$parts     =
FieldsHelper::extract($this->state->get('filter.context'));

if ($parts)
{
	$component = $this->escape($parts[0]);
}

$listOrder =
$this->escape($this->state->get('list.ordering'));
$listDirn  =
$this->escape($this->state->get('list.direction'));
$ordering  = ($listOrder == 'a.ordering');
$saveOrder = ($listOrder == 'a.ordering' &&
strtolower($listDirn) == 'asc');

if ($saveOrder)
{
	$saveOrderingUrl =
'index.php?option=com_fields&task=groups.saveOrderAjax&tmpl=component';
	JHtml::_('sortablelist.sortable', 'groupList',
'adminForm', strtolower($listDirn), $saveOrderingUrl, false,
true);
}
?>

<form action="<?php echo
JRoute::_('index.php?option=com_fields&view=groups');
?>" method="post" name="adminForm"
id="adminForm">
	<div id="j-sidebar-container" class="span2">
		<?php echo $this->sidebar; ?>
	</div>
	<div id="j-main-container" class="span10">
		<div id="filter-bar" class="js-stools-container-bar
pull-left">
			<div class="btn-group pull-left">
				<?php echo
$this->filterForm->getField('context')->input; ?>
			</div>&nbsp;
		</div>
		<?php echo
JLayoutHelper::render('joomla.searchtools.default',
array('view' => $this)); ?>
		<?php if (empty($this->items)) : ?>
			<div class="alert alert-no-items">
				<?php echo JText::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
			</div>
		<?php else : ?>
			<table class="table table-striped"
id="groupList">
				<thead>
					<tr>
						<th width="1%" class="nowrap center
hidden-phone">
							<?php echo JHtml::_('searchtools.sort', '',
'a.ordering', $listDirn, $listOrder, null, 'asc',
'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
						</th>
						<th width="1%" class="center">
							<?php echo JHtml::_('grid.checkall'); ?>
						</th>
						<th width="1%" class="nowrap center">
							<?php echo JHtml::_('searchtools.sort',
'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
						</th>
						<th>
							<?php echo JHtml::_('searchtools.sort',
'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder);
?>
						</th>
						<th width="10%" class="nowrap
hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ACCESS', 'a.access', $listDirn,
$listOrder); ?>
						</th>
						<th width="5%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn,
$listOrder); ?>
						</th>
						<th width="1%" class="nowrap hidden-phone">
							<?php echo JHtml::_('searchtools.sort',
'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder);
?>
						</th>
					</tr>
				</thead>
				<tfoot>
					<tr>
						<td colspan="9">
							<?php echo $this->pagination->getListFooter(); ?>
						</td>
					</tr>
				</tfoot>
				<tbody>
					<?php foreach ($this->items as $i => $item) : ?>
						<?php $ordering   = ($listOrder == 'a.ordering'); ?>
						<?php $canEdit    = $user->authorise('core.edit',
$component . '.fieldgroup.' . $item->id); ?>
						<?php $canCheckin = $user->authorise('core.admin',
'com_checkin') || $item->checked_out == $userId ||
$item->checked_out == 0; ?>
						<?php $canEditOwn = $user->authorise('core.edit.own',
$component . '.fieldgroup.' . $item->id) &&
$item->created_by == $userId; ?>
						<?php $canChange  =
$user->authorise('core.edit.state', $component .
'.fieldgroup.' . $item->id) && $canCheckin; ?>
						<tr class="row<?php echo $i % 2; ?>"
item-id="<?php echo $item->id ?>">
							<td class="order nowrap center hidden-phone">
								<?php $iconClass = ''; ?>
								<?php if (!$canChange) : ?>
									<?php $iconClass = ' inactive'; ?>
								<?php elseif (!$saveOrder) : ?>
									<?php $iconClass = ' inactive tip-top hasTooltip"
title="' . JHtml::tooltipText('JORDERINGDISABLED');
?>
								<?php endif; ?>
								<span class="sortable-handler<?php echo $iconClass;
?>">
									<span class="icon-menu"
aria-hidden="true"></span>
								</span>
								<?php if ($canChange && $saveOrder) : ?>
									<input type="text" style="display:none"
name="order[]" size="5" value="<?php echo
$item->ordering; ?>" />
								<?php endif; ?>
							</td>
							<td class="center">
								<?php echo JHtml::_('grid.id', $i, $item->id);
?>
							</td>
							<td class="center">
								<div class="btn-group">
									<?php echo JHtml::_('jgrid.published',
$item->state, $i, 'groups.', $canChange, 'cb');
?>
									<?php // Create dropdown items and render the dropdown list.
?>
									<?php if ($canChange) : ?>
										<?php JHtml::_('actionsdropdown.' . ((int)
$item->state === 2 ? 'un' : '') .
'archive', 'cb' . $i, 'groups'); ?>
										<?php JHtml::_('actionsdropdown.' . ((int)
$item->state === -2 ? 'un' : '') .
'trash', 'cb' . $i, 'groups'); ?>
										<?php echo JHtml::_('actionsdropdown.render',
$this->escape($item->title)); ?>
									<?php endif; ?>
								</div>
							</td>
							<td>
								<div class="pull-left break-word">
									<?php if ($item->checked_out) : ?>
										<?php echo JHtml::_('jgrid.checkedout', $i,
$item->editor, $item->checked_out_time, 'groups.',
$canCheckin); ?>
									<?php endif; ?>
									<?php if ($canEdit || $canEditOwn) : ?>
										<a href="<?php echo
JRoute::_('index.php?option=com_fields&task=group.edit&id='
. $item->id); ?>">
											<?php echo $this->escape($item->title); ?></a>
									<?php else : ?>
										<?php echo $this->escape($item->title); ?>
									<?php endif; ?>
									<span class="small break-word">
										<?php if ($item->note) : ?>
											<?php echo JText::sprintf('JGLOBAL_LIST_NOTE',
$this->escape($item->note)); ?>
										<?php endif; ?>
									</span>
								</div>
							</td>
							<td class="small hidden-phone">
								<?php echo $this->escape($item->access_level); ?>
							</td>
							<td class="small nowrap hidden-phone">
								<?php echo
JLayoutHelper::render('joomla.content.language', $item); ?>
							</td>
							<td class="center hidden-phone">
								<span><?php echo (int) $item->id; ?></span>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
			<?php //Load the batch processing form. ?>
			<?php if ($user->authorise('core.create', $component)
				&& $user->authorise('core.edit', $component)
				&& $user->authorise('core.edit.state',
$component)) : ?>
				<?php echo JHtml::_(
						'bootstrap.renderModal',
						'collapseModal',
						array(
							'title' =>
JText::_('COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS'),
							'footer' =>
$this->loadTemplate('batch_footer')
						),
						$this->loadTemplate('batch_body')
					); ?>
			<?php endif; ?>
		<?php endif; ?>
		<input type="hidden" name="task"
value="" />
		<input type="hidden" name="boxchecked"
value="0" />
		<?php echo JHtml::_('form.token'); ?>
	</div>
</form>
views/groups/tmpl/default_batch_body.php000064400000001311151165643620014514
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

JHtml::_('formbehavior.chosen', 'select');
?>

<div class="container-fluid">
	<div class="row-fluid">
		<div class="control-group span6">
			<div class="controls">
				<?php echo
JLayoutHelper::render('joomla.html.batch.language', array());
?>
			</div>
		</div>
		<div class="control-group span6">
			<div class="controls">
				<?php echo
JLayoutHelper::render('joomla.html.batch.access', array()); ?>
			</div>
		</div>
	</div>
</div>
views/groups/tmpl/default_batch_footer.php000064400000001307151165643620015062
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

?>
<button type="button" class="btn"
onclick="document.getElementById('batch-field-id').value='';document.getElementById('batch-access').value='';document.getElementById('batch-language-id').value=''"
data-dismiss="modal">
	<?php echo JText::_('JCANCEL'); ?>
</button>
<button type="submit" class="btn btn-success"
onclick="Joomla.submitbutton('group.batch');return
false;">
	<?php echo JText::_('JGLOBAL_BATCH_PROCESS'); ?>
</button>
views/groups/view.html.php000064400000011576151165643620011671
0ustar00<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
defined('_JEXEC') or die;

/**
 * Groups View
 *
 * @since  3.7.0
 */
class FieldsViewGroups extends JViewLegacy
{
	/**
	 * @var  JForm
	 *
	 * @since  3.7.0
	 */
	public $filterForm;

	/**
	 * @var  array
	 *
	 * @since  3.7.0
	 */
	public $activeFilters;

	/**
	 * @var  array
	 *
	 * @since  3.7.0
	 */
	protected $items;

	/**
	 * @var  JPagination
	 *
	 * @since  3.7.0
	 */
	protected $pagination;

	/**
	 * @var  JObject
	 *
	 * @since  3.7.0
	 */
	protected $state;

	/**
	 * @var  string
	 *
	 * @since  3.7.0
	 */
	protected $sidebar;

	/**
	 * Execute and display a template script.
	 *
	 * @param   string  $tpl  The name of the template file to parse;
automatically searches through the template paths.
	 *
	 * @return  mixed  A string if successful, otherwise an Error object.
	 *
	 * @see     JViewLegacy::loadTemplate()
	 * @since   3.7.0
	 */
	public function display($tpl = null)
	{
		$this->state         = $this->get('State');
		$this->items         = $this->get('Items');
		$this->pagination    = $this->get('Pagination');
		$this->filterForm    = $this->get('FilterForm');
		$this->activeFilters = $this->get('ActiveFilters');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Display a warning if the fields system plugin is disabled
		if (!JPluginHelper::isEnabled('system', 'fields'))
		{
			$link =
JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id='
. FieldsHelper::getFieldsPluginId());
			JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED',
$link), 'warning');
		}

		$this->addToolbar();

		FieldsHelper::addSubmenu($this->state->get('filter.context'),
'groups');
		$this->sidebar = JHtmlSidebar::render();

		return parent::display($tpl);
	}

	/**
	 * Adds the toolbar.
	 *
	 * @return  void
	 *
	 * @since   3.7.0
	 */
	protected function addToolbar()
	{
		$groupId   = $this->state->get('filter.group_id');
		$component = '';
		$parts     =
FieldsHelper::extract($this->state->get('filter.context'));

		if ($parts)
		{
			$component = $parts[0];
		}

		$canDo     = JHelperContent::getActions($component,
'fieldgroup', $groupId);

		// Get the toolbar object instance
		$bar = JToolbar::getInstance('toolbar');

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Load component language file
		$lang = JFactory::getLanguage();
		$lang->load($component, JPATH_ADMINISTRATOR)
		|| $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR .
'/components/' . $component));

		$title = JText::sprintf('COM_FIELDS_VIEW_GROUPS_TITLE',
JText::_(strtoupper($component)));

		// Prepare the toolbar.
		JToolbarHelper::title($title, 'puzzle fields ' .
substr($component, 4) . '-groups');

		if ($canDo->get('core.create'))
		{
			JToolbarHelper::addNew('group.add');
		}

		if ($canDo->get('core.edit') ||
$canDo->get('core.edit.own'))
		{
			JToolbarHelper::editList('group.edit');
		}

		if ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::publish('groups.publish',
'JTOOLBAR_PUBLISH', true);
			JToolbarHelper::unpublish('groups.unpublish',
'JTOOLBAR_UNPUBLISH', true);
			JToolbarHelper::archiveList('groups.archive');
		}

		if (JFactory::getUser()->authorise('core.admin'))
		{
			JToolbarHelper::checkin('groups.checkin');
		}

		// Add a batch button
		if ($canDo->get('core.create') &&
$canDo->get('core.edit') &&
$canDo->get('core.edit.state'))
		{
			$title = JText::_('JTOOLBAR_BATCH');

			// Instantiate a new JLayoutFile instance and render the batch button
			$layout = new JLayoutFile('joomla.toolbar.batch');

			$dhtml = $layout->render(
				array(
					'title' => $title,
				)
			);

			$bar->appendButton('Custom', $dhtml, 'batch');
		}

		if ($canDo->get('core.admin') ||
$canDo->get('core.options'))
		{
			JToolbarHelper::preferences($component);
		}

		if ($this->state->get('filter.state') == -2 &&
$canDo->get('core.delete', $component))
		{
			JToolbarHelper::deleteList('', 'groups.delete',
'JTOOLBAR_EMPTY_TRASH');
		}
		elseif ($canDo->get('core.edit.state'))
		{
			JToolbarHelper::trash('groups.trash');
		}

		JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS');
	}

	/**
	 * Returns the sort fields.
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	protected function getSortFields()
	{
		return array(
			'a.ordering'  =>
JText::_('JGRID_HEADING_ORDERING'),
			'a.state'     => JText::_('JSTATUS'),
			'a.title'     => JText::_('JGLOBAL_TITLE'),
			'a.access'    =>
JText::_('JGRID_HEADING_ACCESS'),
			'language'    =>
JText::_('JGRID_HEADING_LANGUAGE'),
			'a.context'   =>
JText::_('JGRID_HEADING_CONTEXT'),
			'a.id'        => JText::_('JGRID_HEADING_ID'),
		);
	}
}
forms/filter_fields.xml000064400000005665151165725250011254
0ustar00<?xml version="1.0" encoding="UTF-8"?>
<form>
	<fieldset
		name="group"
		addfieldprefix="Joomla\Component\Fields\Administrator\Field"
		>
		<field
			name="context"
			type="fieldcontexts"
			onchange="this.form.submit();"
		/>
	</fieldset>
	<fields name="filter">
		<field
			name="search"
			type="text"
			inputmode="search"
			label="COM_FIELDS_FIELDS_FILTER_SEARCH_LABEL"
			description="COM_FIELDS_FIELDS_FILTER_SEARCH_DESC"
			hint="JSEARCH_FILTER"
			class="js-stools-search-string"
		/>

		<field
			name="state"
			type="status"
			label="JSTATUS"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_PUBLISHED</option>
		</field>

		<field
			name="group_id"
			type="fieldgroups"
			state="0,1,2"
			onchange="this.form.submit();"
			>
			<option
value="">COM_FIELDS_VIEW_FIELDS_SELECT_GROUP</option>
		</field>

		<field
			name="assigned_cat_ids"
			type="category"
			label="JCATEGORY"
			onchange="this.form.submit();"
			>
			<option
value="">COM_FIELDS_VIEW_FIELDS_SELECT_CATEGORY</option>
		</field>

		<field
			name="access"
			type="accesslevel"
			label="JGRID_HEADING_ACCESS"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_ACCESS</option>
		</field>

		<field
			name="language"
			type="contentlanguage"
			label="JGRID_HEADING_LANGUAGE"
			onchange="this.form.submit();"
			>
			<option value="">JOPTION_SELECT_LANGUAGE</option>
		</field>
	</fields>

	<fields name="list">
		<field
			name="fullordering"
			type="list"
			label="JGLOBAL_SORT_BY"
			description="JGLOBAL_SORT_BY"
			statuses="*,0,1,2,-2"
			onchange="this.form.submit();"
			default="a.ordering ASC"
			validate="options"
			>
			<option value="">JGLOBAL_SORT_BY</option>
			<option value="a.ordering
ASC">JGRID_HEADING_ORDERING_ASC</option>
			<option value="a.ordering
DESC">JGRID_HEADING_ORDERING_DESC</option>
			<option value="a.state ASC">JSTATUS_ASC</option>
			<option value="a.state DESC">JSTATUS_DESC</option>
			<option value="a.title
ASC">JGLOBAL_TITLE_ASC</option>
			<option value="a.title
DESC">JGLOBAL_TITLE_DESC</option>
			<option value="a.type
ASC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_ASC</option>
			<option value="a.type
DESC">COM_FIELDS_VIEW_FIELDS_SORT_TYPE_DESC</option>
			<option value="g.title
ASC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_ASC</option>
			<option value="g.title
DESC">COM_FIELDS_VIEW_FIELDS_SORT_GROUP_DESC</option>
			<option value="a.access
ASC">JGRID_HEADING_ACCESS_ASC</option>
			<option value="a.access
DESC">JGRID_HEADING_ACCESS_DESC</option>
			<option value="a.language ASC"
requires="multilanguage">JGRID_HEADING_LANGUAGE_ASC</option>
			<option value="a.language DESC"
requires="multilanguage">JGRID_HEADING_LANGUAGE_DESC</option>
			<option value="a.id
ASC">JGRID_HEADING_ID_ASC</option>
			<option value="a.id
DESC">JGRID_HEADING_ID_DESC</option>
		</field>

		<field
			name="limit"
			type="limitbox"
			label="JGLOBAL_LIST_LIMIT"
			default="25"
			onchange="this.form.submit();"
		/>
	</fields>
</form>
src/Dispatcher/Dispatcher.php000064400000002654151165725250012240
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   (C) 2018 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Fields\Site\Dispatcher;

use Joomla\CMS\Access\Exception\NotAllowed;
use Joomla\CMS\Dispatcher\ComponentDispatcher;
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * ComponentDispatcher class for com_fields
 *
 * @since  4.0.0
 */
class Dispatcher extends ComponentDispatcher
{
    /**
     * Method to check component access permission
     *
     * @return  void
     *
     * @since   4.0.0
     */
    protected function checkAccess()
    {
        parent::checkAccess();

        if ($this->input->get('view') !==
'fields' || $this->input->get('layout') !==
'modal') {
            return;
        }

        $context =
$this->app->getUserStateFromRequest('com_fields.fields.context',
'context', 'com_content.article', 'CMD');
        $parts   = FieldsHelper::extract($context);

        if (
           
!$this->app->getIdentity()->authorise('core.create',
$parts[0])
            ||
!$this->app->getIdentity()->authorise('core.edit',
$parts[0])
        ) {
            throw new
NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'));
        }
    }
}
src/Controller/DisplayController.php000064400000003405151165725250013653
0ustar00<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_fields
 *
 * @copyright   (C) 2017 Open Source Matters, Inc.
<https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */

namespace Joomla\Component\Fields\Site\Controller;

use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Base controller class for Fields Component.
 *
 * @since  3.7.0
 */
class DisplayController extends \Joomla\CMS\MVC\Controller\BaseController
{
    /**
     * @param   array                         $config   An optional
associative array of configuration settings.
     *                                                  Recognized key
values include 'name', 'default_task',
'model_path', and
     *                                                 
'view_path' (this list is not meant to be comprehensive).
     * @param   MVCFactoryInterface|null      $factory  The factory.
     * @param   CMSApplication|null           $app      The Application for
the dispatcher
     * @param   \Joomla\CMS\Input\Input|null  $input    The request's
input object
     *
     * @since   3.7.0
     */
    public function __construct($config = [], MVCFactoryInterface $factory
= null, $app = null, $input = null)
    {
        // Frontpage Editor Fields Button proxying.
        if ($input->get('view') === 'fields'
&& $input->get('layout') === 'modal') {
            // Load the backend language file.
            $app->getLanguage()->load('com_fields',
JPATH_ADMINISTRATOR);

            $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR;
        }

        parent::__construct($config, $factory, $app, $input);
    }
}