Файловый менеджер - Редактировать - /home/wuectly/www/03cbe/com_fields.tar
Назад
js/admin-fields-modal.js 0000604 00000002215 15245530513 0011143 0 ustar 00 /** * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @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.js 0000604 00000001321 15245530513 0011722 0 ustar 00 Joomla=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); layouts/fields/render.php 0000604 00000003040 15245561334 0011503 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // 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->name . ' ' . $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> layouts/field/render.php 0000604 00000001532 15245561334 0011324 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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'); $valueClass = $field->params->get('value_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 $valueClass; ?>"><?php echo $value; ?></span> controller.php 0000604 00000002230 15245561334 0007441 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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); } } models/forms/filter_fields.xml 0000604 00000005403 15245561334 0012520 0 ustar 00 <?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> fields.php 0000604 00000001771 15245561334 0006535 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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(); models/field.php 0000604 00000067254 15245570460 0007645 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; /** * Field Model * * @since 3.7.0 */ class FieldsModelField extends JModelAdmin { /** * @var null|string * * @since 3.7.0 */ public $typeAlias = null; /** * @var string * * @since 3.7.0 */ protected $text_prefix = 'COM_FIELDS'; /** * Batch copy/move command. If set to false, * the batch copy/move command is not supported * * @var string * @since 3.4 */ protected $batch_copymove = 'group_id'; /** * Allowed batch commands * * @var array */ protected $batch_commands = array( 'assetgroup_id' => 'batchAccess', 'language_id' => 'batchLanguage' ); /** * @var array * * @since 3.7.0 */ private $valueCache = array(); /** * Constructor. * * @param array $config An optional associative array of configuration settings. * * @see JModelLegacy * @since 3.7.0 */ public function __construct($config = array()) { parent::__construct($config); $this->typeAlias = JFactory::getApplication()->input->getCmd('context', 'com_content.article') . '.field'; } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success, False on error. * * @since 3.7.0 */ public function save($data) { $field = null; if (isset($data['id']) && $data['id']) { $field = $this->getItem($data['id']); } if (!isset($data['label']) && isset($data['params']['label'])) { $data['label'] = $data['params']['label']; unset($data['params']['label']); } // Alter the title for save as copy $input = JFactory::getApplication()->input; if ($input->get('task') == 'save2copy') { $origTable = clone $this->getTable(); $origTable->load($input->getInt('id')); if ($data['title'] == $origTable->title) { list($title, $name) = $this->generateNewTitle($data['group_id'], $data['name'], $data['title']); $data['title'] = $title; $data['label'] = $title; $data['name'] = $name; } else { if ($data['name'] == $origTable->name) { $data['name'] = ''; } } $data['state'] = 0; } // Load the fields plugins, perhaps they want to do something JPluginHelper::importPlugin('fields'); $message = $this->checkDefaultValue($data); if ($message !== true) { $this->setError($message); return false; } if (!parent::save($data)) { return false; } // Save the assigned categories into #__fields_categories $db = $this->getDbo(); $id = (int) $this->getState('field.id'); $cats = isset($data['assigned_cat_ids']) ? (array) $data['assigned_cat_ids'] : array(); $cats = ArrayHelper::toInteger($cats); $assignedCatIds = array(); foreach ($cats as $cat) { if ($cat) { $assignedCatIds[] = $cat; } } // First delete all assigned categories $query = $db->getQuery(true); $query->delete('#__fields_categories') ->where('field_id = ' . $id); $db->setQuery($query); $db->execute(); // Inset new assigned categories $tupel = new stdClass; $tupel->field_id = $id; foreach ($assignedCatIds as $catId) { $tupel->category_id = $catId; $db->insertObject('#__fields_categories', $tupel); } // If the options have changed delete the values if ($field && isset($data['fieldparams']['options']) && isset($field->fieldparams['options'])) { $oldParams = $this->getParams($field->fieldparams['options']); $newParams = $this->getParams($data['fieldparams']['options']); if (is_object($oldParams) && is_object($newParams) && $oldParams != $newParams) { $names = array(); foreach ($newParams as $param) { $names[] = $db->q($param['value']); } $query = $db->getQuery(true); $query->delete('#__fields_values')->where('field_id = ' . (int) $field->id); // If new values are set, delete only old values. Otherwise delete all values. if ($names) { $query->where('value NOT IN (' . implode(',', $names) . ')'); } $db->setQuery($query); $db->execute(); } } FieldsHelper::clearFieldsCache(); return true; } /** * Checks if the default value is valid for the given data. If a string is returned then * it can be assumed that the default value is invalid. * * @param array $data The data. * * @return true|string true if valid, a string containing the exception message when not. * * @since 3.7.0 */ private function checkDefaultValue($data) { // Empty default values are correct if (empty($data['default_value']) && $data['default_value'] !== '0') { return true; } $types = FieldsHelper::getFieldTypes(); // Check if type exists if (!key_exists($data['type'], $types)) { return true; } $path = $types[$data['type']]['rules']; // Add the path for the rules of the plugin when available if ($path) { // Add the lookup path for the rule JFormHelper::addRulePath($path); } // Create the fields object $obj = (object) $data; $obj->params = new Registry($obj->params); $obj->fieldparams = new Registry(!empty($obj->fieldparams) ? $obj->fieldparams : array()); // Prepare the dom $dom = new DOMDocument; $node = $dom->appendChild(new DOMElement('form')); // Trigger the event to create the field dom node JEventDispatcher::getInstance()->trigger('onCustomFieldsPrepareDom', array($obj, $node, new JForm($data['context']))); // Check if a node is created if (!$node->firstChild) { return true; } // Define the type either from the field or from the data $type = $node->firstChild->getAttribute('validate') ? : $data['type']; // Load the rule $rule = JFormHelper::loadRuleType($type); // When no rule exists, we allow the default value if (!$rule) { return true; } try { // Perform the check $result = $rule->test(simplexml_import_dom($node->firstChild), $data['default_value']); // Check if the test succeeded return $result === true ? : JText::_('COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE'); } catch (UnexpectedValueException $e) { return $e->getMessage(); } } /** * Converts the unknown params into an object. * * @param mixed $params The params. * * @return stdClass Object on success, false on failure. * * @since 3.7.0 */ private function getParams($params) { if (is_string($params)) { $params = json_decode($params); } if (is_array($params)) { $params = (object) $params; } return $params; } /** * Method to get a single record. * * @param integer $pk The id of the primary key. * * @return mixed Object on success, false on failure. * * @since 3.7.0 */ public function getItem($pk = null) { $result = parent::getItem($pk); if ($result) { // Prime required properties. if (empty($result->id)) { $result->context = JFactory::getApplication()->input->getCmd('context', $this->getState('field.context')); } if (property_exists($result, 'fieldparams') && $result->fieldparams !== null) { $registry = new Registry; $registry->loadString($result->fieldparams); $result->fieldparams = $registry->toArray(); } $db = $this->getDbo(); $query = $db->getQuery(true); $query->select('category_id') ->from('#__fields_categories') ->where('field_id = ' . (int) $result->id); $db->setQuery($query); $result->assigned_cat_ids = $db->loadColumn() ?: array(0); } return $result; } /** * Method to get a table object, load it if necessary. * * @param string $name The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $options Configuration array for model. Optional. * * @return JTable A JTable object * * @since 3.7.0 * @throws Exception */ public function getTable($name = 'Field', $prefix = 'FieldsTable', $options = array()) { if (strpos(JPATH_COMPONENT, 'com_fields') === false) { $this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables'); } // Default to text type $table = JTable::getInstance($name, $prefix, $options); $table->type = 'text'; return $table; } /** * Method to change the title & name. * * @param integer $categoryId The id of the category. * @param string $name The name. * @param string $title The title. * * @return array Contains the modified title and name. * * @since 3.7.0 */ protected function generateNewTitle($categoryId, $name, $title) { // Alter the title & name $table = $this->getTable(); while ($table->load(array('name' => $name))) { $title = StringHelper::increment($title); $name = StringHelper::increment($name, 'dash'); } return array( $title, $name, ); } /** * Method to delete one or more records. * * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.7.0 */ public function delete(&$pks) { $success = parent::delete($pks); if ($success) { $pks = (array) $pks; $pks = ArrayHelper::toInteger($pks); $pks = array_filter($pks); if (!empty($pks)) { // Delete Values $query = $this->getDbo()->getQuery(true); $query->delete($query->qn('#__fields_values')) ->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')'); $this->getDbo()->setQuery($query)->execute(); // Delete Assigned Categories $query = $this->getDbo()->getQuery(true); $query->delete($query->qn('#__fields_categories')) ->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')'); $this->getDbo()->setQuery($query)->execute(); } } return $success; } /** * Abstract method for getting the form from the model. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 3.7.0 */ public function getForm($data = array(), $loadData = true) { $context = $this->getState('field.context'); $jinput = JFactory::getApplication()->input; // A workaround to get the context into the model for save requests. if (empty($context) && isset($data['context'])) { $context = $data['context']; $parts = FieldsHelper::extract($context); $this->setState('field.context', $context); if ($parts) { $this->setState('field.component', $parts[0]); $this->setState('field.section', $parts[1]); } } if (isset($data['type'])) { // This is needed that the plugins can determine the type $this->setState('field.type', $data['type']); } // Load the fields plugin that they can add additional parameters to the form JPluginHelper::importPlugin('fields'); // Get the form. $form = $this->loadForm( 'com_fields.field.' . $context, 'field', array( 'control' => 'jform', 'load_data' => true, ) ); if (empty($form)) { return false; } // Modify the form based on Edit State access controls. if (empty($data['context'])) { $data['context'] = $context; } $fieldId = $jinput->get('id'); $assetKey = $this->state->get('field.component') . '.field.' . $fieldId; if (!JFactory::getUser()->authorise('core.edit.state', $assetKey)) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('state', 'disabled', 'true'); // Disable fields while saving. The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('state', 'filter', 'unset'); } return $form; } /** * Setting the value for the given field id, context and item id. * * @param string $fieldId The field ID. * @param string $itemId The ID of the item. * @param string $value The value. * * @return boolean * * @since 3.7.0 */ public function setFieldValue($fieldId, $itemId, $value) { $field = $this->getItem($fieldId); $params = $field->params; if (is_array($params)) { $params = new Registry($params); } // Don't save the value when the user is not authorized to change it if (!$field || !FieldsHelper::canEditFieldValue($field)) { return false; } $needsDelete = false; $needsInsert = false; $needsUpdate = false; $oldValue = $this->getFieldValue($fieldId, $itemId); $value = (array) $value; if ($oldValue === null) { // No records available, doing normal insert $needsInsert = true; } elseif (count($value) == 1 && count((array) $oldValue) == 1) { // Only a single row value update can be done when not empty $needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]); $needsDelete = !$needsUpdate; } else { // Multiple values, we need to purge the data and do a new // insert $needsDelete = true; $needsInsert = true; } if ($needsDelete) { // Deleting the existing record as it is a reset $query = $this->getDbo()->getQuery(true); $query->delete($query->qn('#__fields_values')) ->where($query->qn('field_id') . ' = ' . (int) $fieldId) ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); $this->getDbo()->setQuery($query)->execute(); } if ($needsInsert) { $newObj = new stdClass; $newObj->field_id = (int) $fieldId; $newObj->item_id = $itemId; foreach ($value as $v) { $newObj->value = $v; $this->getDbo()->insertObject('#__fields_values', $newObj); } } if ($needsUpdate) { $updateObj = new stdClass; $updateObj->field_id = (int) $fieldId; $updateObj->item_id = $itemId; $updateObj->value = reset($value); $this->getDbo()->updateObject('#__fields_values', $updateObj, array('field_id', 'item_id')); } $this->valueCache = array(); FieldsHelper::clearFieldsCache(); return true; } /** * Returning the value for the given field id, context and item id. * * @param string $fieldId The field ID. * @param string $itemId The ID of the item. * * @return NULL|string * * @since 3.7.0 */ public function getFieldValue($fieldId, $itemId) { $values = $this->getFieldValues(array($fieldId), $itemId); if (key_exists($fieldId, $values)) { return $values[$fieldId]; } return null; } /** * Returning the values for the given field ids, context and item id. * * @param array $fieldIds The field Ids. * @param string $itemId The ID of the item. * * @return NULL|array * * @since 3.7.0 */ public function getFieldValues(array $fieldIds, $itemId) { if (!$fieldIds) { return array(); } // Create a unique key for the cache $key = md5(serialize($fieldIds) . $itemId); // Fill the cache when it doesn't exist if (!key_exists($key, $this->valueCache)) { // Create the query $query = $this->getDbo()->getQuery(true); $query->select(array($query->qn('field_id'), $query->qn('value'))) ->from($query->qn('#__fields_values')) ->where($query->qn('field_id') . ' IN (' . implode(',', ArrayHelper::toInteger($fieldIds)) . ')') ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); // Fetch the row from the database $rows = $this->getDbo()->setQuery($query)->loadObjectList(); $data = array(); // Fill the data container from the database rows foreach ($rows as $row) { // If there are multiple values for a field, create an array if (key_exists($row->field_id, $data)) { // Transform it to an array if (!is_array($data[$row->field_id])) { $data[$row->field_id] = array($data[$row->field_id]); } // Set the value in the array $data[$row->field_id][] = $row->value; // Go to the next row, otherwise the value gets overwritten in the data container continue; } // Set the value $data[$row->field_id] = $row->value; } // Assign it to the internal cache $this->valueCache[$key] = $data; } // Return the value from the cache return $this->valueCache[$key]; } /** * Cleaning up the values for the given item on the context. * * @param string $context The context. * @param string $itemId The Item ID. * * @return void * * @since 3.7.0 */ public function cleanupValues($context, $itemId) { // Delete with inner join is not possible so we need to do a subquery $fieldsQuery = $this->getDbo()->getQuery(true); $fieldsQuery->select($fieldsQuery->qn('id')) ->from($fieldsQuery->qn('#__fields')) ->where($fieldsQuery->qn('context') . ' = ' . $fieldsQuery->q($context)); $query = $this->getDbo()->getQuery(true); $query->delete($query->qn('#__fields_values')) ->where($query->qn('field_id') . ' IN (' . $fieldsQuery . ')') ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); $this->getDbo()->setQuery($query)->execute(); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to delete the record. Defaults to the permission for the component. * * @since 3.7.0 */ protected function canDelete($record) { if (empty($record->id) || $record->state != -2) { return false; } $parts = FieldsHelper::extract($record->context); return JFactory::getUser()->authorise('core.delete', $parts[0] . '.field.' . (int) $record->id); } /** * Method to test whether a record can have its state changed. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the * component. * * @since 3.7.0 */ protected function canEditState($record) { $user = JFactory::getUser(); $parts = FieldsHelper::extract($record->context); // Check for existing field. if (!empty($record->id)) { return $user->authorise('core.edit.state', $parts[0] . '.field.' . (int) $record->id); } return $user->authorise('core.edit.state', $parts[0]); } /** * Stock method to auto-populate the model state. * * @return void * * @since 3.7.0 */ protected function populateState() { $app = JFactory::getApplication('administrator'); // Load the User state. $pk = $app->input->getInt('id'); $this->setState($this->getName() . '.id', $pk); $context = $app->input->get('context', 'com_content.article'); $this->setState('field.context', $context); $parts = FieldsHelper::extract($context); // Extract the component name $this->setState('field.component', $parts[0]); // Extract the optional section name $this->setState('field.section', (count($parts) > 1) ? $parts[1] : null); // Load the parameters. $params = JComponentHelper::getParams('com_fields'); $this->setState('params', $params); } /** * A protected method to get a set of ordering conditions. * * @param JTable $table A JTable object. * * @return array An array of conditions to add to ordering queries. * * @since 3.7.0 */ protected function getReorderConditions($table) { return 'context = ' . $this->_db->quote($table->context); } /** * Method to get the data that should be injected in the form. * * @return array The default data is an empty array. * * @since 3.7.0 */ protected function loadFormData() { // Check the session for previously entered form data. $app = JFactory::getApplication(); $data = $app->getUserState('com_fields.edit.field.data', array()); if (empty($data)) { $data = $this->getItem(); // Pre-select some filters (Status, Language, Access) in edit form // if those have been selected in Category Manager if (!$data->id) { // Check for which context the Category Manager is used and // get selected fields $filters = (array) $app->getUserState('com_fields.fields.filter'); $data->set('state', $app->input->getInt('state', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null))); $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); $data->set('group_id', $app->input->getString('group_id', (!empty($filters['group_id']) ? $filters['group_id'] : null))); $data->set( 'access', $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'))) ); // Set the type if available from the request $data->set('type', $app->input->getWord('type', $this->state->get('field.type', $data->get('type')))); } if ($data->label && !isset($data->params['label'])) { $data->params['label'] = $data->label; } } $this->preprocessData('com_fields.field', $data); return $data; } /** * Method to validate the form data. * * @param JForm $form The form to validate against. * @param array $data The data to validate. * @param string $group The name of the field group to validate. * * @return array|boolean Array of filtered data if valid, false otherwise. * * @see JFormRule * @see JFilterInput * @since 3.9.23 */ public function validate($form, $data, $group = null) { // Don't allow to change the users if not allowed to access com_users. if (!JFactory::getUser()->authorise('core.manage', 'com_users')) { if (isset($data['created_user_id'])) { unset($data['created_user_id']); } } if (!JFactory::getUser()->authorise('core.admin', 'com_fields')) { if (isset($data['rules'])) { unset($data['rules']); } } return parent::validate($form, $data, $group); } /** * Method to allow derived classes to preprocess the form. * * @param JForm $form A JForm object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @see JFormField * @since 3.7.0 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { $component = $this->state->get('field.component'); $section = $this->state->get('field.section'); $dataObject = $data; if (is_array($dataObject)) { $dataObject = (object) $dataObject; } if (isset($dataObject->type)) { $form->setFieldAttribute('type', 'component', $component); // Not allowed to change the type of an existing record if ($dataObject->id) { $form->setFieldAttribute('type', 'readonly', 'true'); } // Allow to override the default value label and description through the plugin $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_LABEL'; if (JFactory::getLanguage()->hasKey($key)) { $form->setFieldAttribute('default_value', 'label', $key); } $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_DESC'; if (JFactory::getLanguage()->hasKey($key)) { $form->setFieldAttribute('default_value', 'description', $key); } // Remove placeholder field on list fields if ($dataObject->type == 'list') { $form->removeField('hint', 'params'); } } // Setting the context for the category field $cat = JCategories::getInstance(str_replace('com_', '', $component) . '.' . $section); // If there is no category for the component and section, so check the component only if (!$cat) { $cat = JCategories::getInstance(str_replace('com_', '', $component)); } if ($cat && $cat->get('root')->hasChildren()) { $form->setFieldAttribute('assigned_cat_ids', 'extension', $cat->getExtension()); } else { $form->removeField('assigned_cat_ids'); } $form->setFieldAttribute('type', 'component', $component); $form->setFieldAttribute('group_id', 'context', $this->state->get('field.context')); $form->setFieldAttribute('rules', 'component', $component); // Looking first in the component models/forms folder $path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fields/' . $section . '.xml'); if (file_exists($path)) { $lang = JFactory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true); $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, true); if (!$form->loadFile($path, false)) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } } // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * Clean the cache * * @param string $group The cache group * @param integer $clientId The ID of the client * * @return void * * @since 3.7.0 */ protected function cleanCache($group = null, $clientId = 0) { $context = JFactory::getApplication()->input->get('context'); switch ($context) { case 'com_content': parent::cleanCache('com_content'); parent::cleanCache('mod_articles_archive'); parent::cleanCache('mod_articles_categories'); parent::cleanCache('mod_articles_category'); parent::cleanCache('mod_articles_latest'); parent::cleanCache('mod_articles_news'); parent::cleanCache('mod_articles_popular'); break; default: parent::cleanCache($context); break; } } /** * Batch copy fields to a new group. * * @param integer $value The new value matching a fields group. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return array|boolean new IDs if successful, false otherwise and internal error is set. * * @since 3.7.0 */ protected function batchCopy($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); $newIds = array(); $component = $this->state->get('filter.component'); $value = (int) $value; foreach ($pks as $pk) { if ($user->authorise('core.create', $component . '.fieldgroup.' . $value)) { $table->reset(); $table->load($pk); $table->group_id = $value; // Reset the ID because we are making a copy $table->id = 0; // Unpublish the new field $table->state = 0; if (!$table->store()) { $this->setError($table->getError()); return false; } // Get the new item ID $newId = $table->get('id'); // Add the new ID to the array $newIds[$pk] = $newId; } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); return false; } } // Clean the cache $this->cleanCache(); return $newIds; } /** * Batch move fields to a new group. * * @param integer $value The new value matching a fields group. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 3.7.0 */ protected function batchMove($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); $context = explode('.', JFactory::getApplication()->getUserState('com_fields.fields.context')); $value = (int) $value; foreach ($pks as $pk) { if ($user->authorise('core.edit', $context[0] . '.fieldgroup.' . $value)) { $table->reset(); $table->load($pk); $table->group_id = $value; if (!$table->store()) { $this->setError($table->getError()); return false; } } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; } } // Clean the cache $this->cleanCache(); return true; } } models/fields.php 0000604 00000025411 15245570460 0010015 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; use Joomla\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/fields/fieldlayout.php 0000604 00000011051 15245570460 0012331 0 ustar 00 <?php /** * @package Joomla.Administrator * @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 */ 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/type.php 0000604 00000004163 15245570460 0010777 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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/section.php 0000604 00000004032 15245570460 0011455 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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/fieldcontexts.php 0000604 00000002725 15245570460 0012673 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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.php 0000604 00000003105 15245570460 0012334 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\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/group.php 0000604 00000022410 15245570460 0007677 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; /** * 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) { // Don't allow to change the users if not allowed to access com_users. if (!JFactory::getUser()->authorise('core.manage', 'com_users')) { if (isset($data['created_by'])) { unset($data['created_by']); } } 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.php 0000604 00000014374 15245570460 0010074 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; use Joomla\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; } } models/forms/filter_groups.xml 0000604 00000003705 15245570460 0012574 0 ustar 00 <?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/field.xml 0000604 00000016726 15245570460 0011002 0 ustar 00 <?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" validate="CssIdentifierSubstring" 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" validate="CssIdentifierSubstring" 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" validate="CssIdentifierSubstring" size="40" /> <field name="value_render_class" type="textarea" label="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_LABEL" description="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_DESC" class="input-xxlarge" validate="CssIdentifierSubstring" 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" validate="CssIdentifierSubstring" 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/group.xml 0000604 00000005725 15245570460 0011050 0 ustar 00 <?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> helpers/fields.php 0000604 00000046764 15245570460 0010212 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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; } } tables/group.php 0000604 00000010704 15245570460 0007671 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; /** * 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); } } tables/field.php 0000604 00000014153 15245570460 0007622 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; /** * Fields Table * * @since 3.7.0 */ class FieldsTableField extends JTable { /** * Class constructor. * * @param JDatabaseDriver $db JDatabaseDriver object. * * @since 3.7.0 */ public function __construct($db = null) { parent::__construct('#__fields', 'id', $db); $this->setColumnAlias('published', 'state'); } /** * Method to bind an associative array or object to the JTable instance.This * method only binds properties that are publicly accessible and optionally * takes an array of properties to ignore when binding. * * @param mixed $src An associative array or object to bind to the JTable instance. * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. * * @return boolean True on success. * * @since 3.7.0 * @throws InvalidArgumentException */ public function bind($src, $ignore = '') { if (isset($src['params']) && is_array($src['params'])) { $registry = new Registry; $registry->loadArray($src['params']); $src['params'] = (string) $registry; } if (isset($src['fieldparams']) && is_array($src['fieldparams'])) { $registry = new Registry; $registry->loadArray($src['fieldparams']); $src['fieldparams'] = (string) $registry; } // Bind the rules. if (isset($src['rules']) && is_array($src['rules'])) { $rules = new JAccessRules($src['rules']); $this->setRules($rules); } return parent::bind($src, $ignore); } /** * Method to perform sanity checks on the JTable instance properties to ensure * they are safe to store in the database. Child classes should override this * method to make sure the data they are storing in the database is safe and * as expected before storage. * * @return boolean True if the instance is sane and able to be stored in the database. * * @link https://docs.joomla.org/Special:MyLanguage/JTable/check * @since 3.7.0 */ public function check() { // Check for valid name if (trim($this->title) == '') { $this->setError(JText::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD')); return false; } if (empty($this->name)) { $this->name = $this->title; } $this->name = JApplicationHelper::stringURLSafe($this->name, $this->language); if (trim(str_replace('-', '', $this->name)) == '') { $this->name = Joomla\String\StringHelper::increment($this->name, 'dash'); } $this->name = str_replace(',', '-', $this->name); // Verify that the name is unique $table = JTable::getInstance('Field', 'FieldsTable', array('dbo' => $this->_db)); if ($table->load(array('name' => $this->name)) && ($table->id != $this->id || $this->id == 0)) { $this->setError(JText::_('COM_FIELDS_ERROR_UNIQUE_NAME')); return false; } $this->name = str_replace(',', '-', $this->name); if (empty($this->type)) { $this->type = 'text'; } $date = JFactory::getDate(); $user = JFactory::getUser(); if ($this->id) { // Existing item $this->modified_time = $date->toSql(); $this->modified_by = $user->get('id'); } else { if (!(int) $this->created_time) { $this->created_time = $date->toSql(); } if (empty($this->created_user_id)) { $this->created_user_id = $user->get('id'); } } if (empty($this->group_id)) { $this->group_id = 0; } return true; } /** * Method to compute the default name of the asset. * The default name is in the form table_name.id * where id is the value of the primary key of the table. * * @return string * * @since 3.7.0 */ protected function _getAssetName() { $contextArray = explode('.', $this->context); return $contextArray[0] . '.field.' . (int) $this->id; } /** * Method to return the title to use for the asset table. In * tracking the assets a title is kept for each asset so that there is some * context available in a unified access manager. Usually this would just * return $this->title or $this->name or whatever is being used for the * primary name of the row. If this method is not overridden, the asset name is used. * * @return string The string to use as the title in the asset table. * * @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle * @since 3.7.0 */ protected function _getAssetTitle() { return $this->title; } /** * Method to get the parent asset under which to register this one. * By default, all assets are registered to the ROOT node with ID, * which will default to 1 if none exists. * The extended class can define a table and id to lookup. If the * asset does not exist it will be created. * * @param JTable $table A JTable object for the asset parent. * @param integer $id Id to look up * * @return integer * * @since 3.7.0 */ protected function _getAssetParentId(JTable $table = null, $id = null) { $contextArray = explode('.', $this->context); $component = $contextArray[0]; if ($this->group_id) { $assetId = $this->getAssetId($component . '.fieldgroup.' . (int) $this->group_id); if ($assetId) { return $assetId; } } else { $assetId = $this->getAssetId($component); if ($assetId) { return $assetId; } } return parent::_getAssetParentId($table, $id); } /** * Returns an asset id for the given name or false. * * @param string $name The asset name * * @return number|boolean * * @since 3.7.0 */ private function getAssetId($name) { $db = $this->getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('id')) ->from($db->quoteName('#__assets')) ->where($db->quoteName('name') . ' = ' . $db->quote($name)); // Get the asset id from the database. $db->setQuery($query); $assetId = null; if ($result = $db->loadResult()) { $assetId = (int) $result; if ($assetId) { return $assetId; } } return false; } } views/group/view.html.php 0000604 00000007101 15245570460 0011466 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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/group/tmpl/edit.php 0000604 00000005501 15245570460 0011454 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // 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/fields/view.html.php 0000604 00000011676 15245570460 0011614 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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/fields/tmpl/default.php 0000604 00000020764 15245570460 0012275 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // 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> </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/modal.php 0000604 00000011173 15245570460 0011737 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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/tmpl/default_batch_body.php 0000604 00000004433 15245570460 0014446 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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.php 0000604 00000001272 15245570460 0015005 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> <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/groups/tmpl/default_batch_footer.php 0000604 00000001272 15245570460 0015056 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> <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/tmpl/default_batch_body.php 0000604 00000001274 15245570460 0014517 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; 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.php 0000604 00000016201 15245570460 0012335 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // 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> </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/view.html.php 0000604 00000011561 15245570460 0011656 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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'), ); } } views/field/view.html.php 0000604 00000006501 15245570460 0011420 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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/field/tmpl/edit.php 0000604 00000007600 15245570460 0011405 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // 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> libraries/fieldsplugin.php 0000604 00000014444 15245570460 0011731 0 ustar 00 <?php /** * @package Joomla.Administrator * @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 */ 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'] . '‎'; } } 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; } } libraries/fieldslistplugin.php 0000604 00000003552 15245570460 0012623 0 ustar 00 <?php /** * @package Joomla.Administrator * @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 */ 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; } } fields.xml 0000604 00000002302 15245570460 0006535 0 ustar 00 <?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) 2016 Open Source Matters, Inc.</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> controllers/groups.php 0000604 00000002026 15245570460 0011146 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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); } } controllers/fields.php 0000604 00000001744 15245570460 0011103 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * 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.php 0000604 00000006762 15245570460 0010776 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; /** * 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/field.php 0000604 00000010413 15245570460 0010711 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_fields * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; /** * 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_user_id; } 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; } } groups/default.php 0000604 00000013347 15245617235 0010236 0 ustar 00 <?php /** * @package Joomla.Administrator * @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 */ 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> </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="adminlist" id="groupList"> <thead> <tr> <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="center"> <?php echo JHtml::_('grid.id', $i, $item->id); ?> </td> <td class="center"> <?php echo JHtml::_('jgrid.published', $item->state, $i, 'groups.', $canChange); ?> </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> group/edit.php 0000604 00000010067 15245617235 0007350 0 ustar 00 <?php /** * @package Joomla.Administrator * @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 */ defined('_JEXEC') or die; // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); JHtml::_('behavior.tabstate'); $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")); } }; '); ?> <div class="groups-edit"> <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"> <div class="col main-section"> <fieldset class="adminform"> <legend><?php echo JText::_('COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL'); ?></legend> <ul class="adminformlist"> <li> <?php echo $this->form->getLabel('title'); ?> <?php echo $this->form->getInput('title'); ?> </li> <li> <?php echo $this->form->getLabel('description'); ?> <?php echo $this->form->getInput('description'); ?> </li> <li> <?php echo $this->form->getLabel('published'); ?> <?php echo $this->form->getInput('published'); ?> </li> <li> <?php echo $this->form->getLabel('access'); ?> <?php echo $this->form->getInput('access'); ?> </li> <li> <?php echo $this->form->getLabel('language'); ?> <?php echo $this->form->getInput('language'); ?> </li> <li> <?php echo $this->form->getLabel('note'); ?> <?php echo $this->form->getInput('note'); ?> </li> </ul> <div class="clr"></div> </fieldset> </div> <div class="col options-section"> <?php echo JHtml::_('sliders.start', 'groups-sliders-' . $this->item->id, array('useCookie' => 1)); ?> <?php echo JHtml::_('sliders.panel', JText::_('JGLOBAL_FIELDSET_PUBLISHING'), 'publishing-details'); ?> <fieldset class="panelform"> <legend class="element-invisible"><?php echo JText::_('JGLOBAL_FIELDSET_PUBLISHING'); ?></legend> <ul class="adminformlist"> <li> <?php echo $this->form->getLabel('created_by'); ?> <?php echo $this->form->getInput('created_by'); ?> </li> <?php if ((int) $this->item->created) : ?> <li> <?php echo $this->form->getLabel('created'); ?> <?php echo $this->form->getInput('created'); ?> </li> <?php endif; ?> <?php if ($this->item->modified_by) : ?> <li> <?php echo $this->form->getLabel('modified_by'); ?> <?php echo $this->form->getInput('modified_by'); ?> </li> <li> <?php echo $this->form->getLabel('modified'); ?> <?php echo $this->form->getInput('modified'); ?> </li> <li> <?php echo $this->form->getLabel('id'); ?> <?php echo $this->form->getInput('id'); ?> </li> <?php endif; ?> </ul> </fieldset> <?php echo JHtml::_('sliders.end'); ?> <div class="clr"></div> <?php $this->set('ignore_fieldsets', array('fieldparams')); ?> </div> <div class="clr"></div> <?php if ($this->canDo->get('core.admin')) : ?> <div class="col rules-section"> <?php echo JHtml::_('sliders.start', 'permissions-sliders-' . $this->item->id, array('useCookie' => 1)); ?> <?php echo JHtml::_('sliders.panel', JText::_('JGLOBAL_ACTION_PERMISSIONS_LABEL'), 'access-rules'); ?> <fieldset class="panelform"> <legend class="element-invisible"><?php echo JText::_('JGLOBAL_ACTION_PERMISSIONS_LABEL'); ?></legend> <?php echo $this->form->getLabel('rules'); ?> <?php echo $this->form->getInput('rules'); ?> </fieldset> <?php echo JHtml::_('sliders.end'); ?> </div> <?php endif; ?> <?php echo $this->form->getInput('context'); ?> <input type="hidden" name="task" value="" /> <?php echo JHtml::_('form.token'); ?> </div> </form> <div class="clr"></div> </div>