Файловый менеджер - Редактировать - /home/wuectly/www/03cbe/com_categories.tar
Назад
controllers/categories.php 0000604 00000007617 15245557240 0011770 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * The Categories List Controller * * @since 1.6 */ class CategoriesControllerCategories extends JControllerAdmin { /** * 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 The model. * * @since 1.6 */ public function getModel($name = 'Category', $prefix = 'CategoriesModel', $config = array('ignore_request' => true)) { return parent::getModel($name, $prefix, $config); } /** * Rebuild the nested set tree. * * @return boolean False on failure or error, true on success. * * @since 1.6 */ public function rebuild() { $this->checkToken(); $extension = $this->input->get('extension'); $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $extension, false)); /** @var CategoriesModelCategory $model */ $model = $this->getModel(); if ($model->rebuild()) { // Rebuild succeeded. $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_SUCCESS')); return true; } // Rebuild failed. $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_FAILURE')); return false; } /** * Save the manual order inputs from the categories list page. * * @return boolean True on success * * @since 1.6 * @see JControllerAdmin::saveorder() * @deprecated 4.0 */ public function saveorder() { $this->checkToken(); try { JLog::add(sprintf('%s() is deprecated. Function will be removed in 4.0.', __METHOD__), JLog::WARNING, 'deprecated'); } catch (RuntimeException $exception) { // Informational log only } // Get the arrays from the Request $order = $this->input->post->get('order', null, 'array'); $originalOrder = explode(',', $this->input->getString('original_order_values')); // Make sure something has changed if (!($order === $originalOrder)) { parent::saveorder(); } else { // Nothing to reorder $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); return true; } } /** * Deletes and returns correctly. * * @return void * * @since 3.1.2 */ public function delete() { $this->checkToken(); // Get items to remove from the request. $cid = (array) $this->input->get('cid', array(), 'int'); $extension = $this->input->getCmd('extension', null); // Remove zero values resulting from input filter $cid = array_filter($cid); if (empty($cid)) { JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); } else { // Get the model. /** @var CategoriesModelCategory $model */ $model = $this->getModel(); // Remove the items. if ($model->delete($cid)) { $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&extension=' . $extension, false)); } /** * Check in of one or more records. * * Overrides JControllerAdmin::checkin to redirect to URL with extension. * * @return boolean True on success * * @since 3.6.0 */ public function checkin() { // Process parent checkin method. $result = parent::checkin(); // Override the redirect Uri. $redirectUri = 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&extension=' . $this->input->get('extension', '', 'CMD'); $this->setRedirect(JRoute::_($redirectUri, false), $this->message, $this->messageType); return $result; } } controllers/ajax.json.php 0000604 00000004615 15245557240 0011531 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @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; use Joomla\CMS\Language\LanguageHelper; /** * The categories controller for ajax requests * * @since 3.9.0 */ class CategoriesControllerAjax extends JControllerLegacy { /** * Method to fetch associations of a category * * The method assumes that the following http parameters are passed in an Ajax Get request: * token: the form token * assocId: the id of the category whose associations are to be returned * excludeLang: the association for this language is to be excluded * * @return null * * @since 3.9.0 */ public function fetchAssociations() { if (!JSession::checkToken('get')) { echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); } else { $input = JFactory::getApplication()->input; $extension = $input->get('extension'); $assocId = $input->getInt('assocId', 0); if ($assocId == 0) { echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); return; } $excludeLang = $input->get('excludeLang', '', 'STRING'); $associations = JLanguageAssociations::getAssociations($extension, '#__categories', 'com_categories.item', (int) $assocId, 'id', 'alias', ''); unset($associations[$excludeLang]); // Add the title to each of the associated records JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); $categoryTable = JTable::getInstance('Category', 'JTable'); foreach ($associations as $lang => $association) { $categoryTable->load($association->id); $associations[$lang]->title = $categoryTable->title; } $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); if (count($associations) == 0) { $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); } elseif ($countContentLanguages > count($associations) + 2) { $tags = implode(', ', array_keys($associations)); $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); } else { $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); } echo new JResponseJson($associations, $message); } } } controllers/category.php 0000604 00000013160 15245557240 0011446 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 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 Category Controller * * @since 1.6 */ class CategoriesControllerCategory extends JControllerForm { /** * The extension for which the categories apply. * * @var string * @since 1.6 */ protected $extension; /** * Constructor. * * @param array $config An optional associative array of configuration settings. * * @since 1.6 * @see JControllerLegacy */ public function __construct($config = array()) { parent::__construct($config); // Guess the JText message prefix. Defaults to the option. if (empty($this->extension)) { $this->extension = $this->input->get('extension', 'com_content'); } } /** * Method to check if you can add a new record. * * @param array $data An array of input data. * * @return boolean * * @since 1.6 */ protected function allowAdd($data = array()) { $user = JFactory::getUser(); return ($user->authorise('core.create', $this->extension) || count($user->getAuthorisedCategories($this->extension, 'core.create'))); } /** * Method to check if you can edit a 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 = 'parent_id') { $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $user = JFactory::getUser(); // Check "edit" permission on record asset (explicit or inherited) if ($user->authorise('core.edit', $this->extension . '.category.' . $recordId)) { return true; } // Check "edit own" permission on record asset (explicit or inherited) if ($user->authorise('core.edit.own', $this->extension . '.category.' . $recordId)) { // Need to do a lookup from the model to get the owner $record = $this->getModel()->getItem($recordId); if (empty($record)) { return false; } $ownerId = $record->created_user_id; // If the owner matches 'me' then do the test. if ($ownerId == $user->id) { return true; } } return false; } /** * Override parent save method to store form data with right key as expected by edit category page * * @param string $key The name of the primary key of the URL variable. * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). * * @return boolean True if successful, false otherwise. * * @since 3.10.3 */ public function save($key = null, $urlVar = null) { $result = parent::save($key, $urlVar); $oldKey = $this->option . '.edit.category.data'; $newKey = $this->option . '.edit.category.' . substr($this->extension, 4) . '.data'; $app = JFactory::getApplication(); $app->setUserState($newKey, $app->getUserState($oldKey)); return $result; } /** * Override cancel method to clear form data for a failed edit action * * @param string $key The name of the primary key of the URL variable. * * @return boolean True if access level checks pass, false otherwise. * * @since 3.10.3 */ public function cancel($key = null) { $result = parent::cancel($key); $newKey = $this->option . '.edit.category.' . substr($this->extension, 4) . '.data'; JFactory::getApplication()->setUserState($newKey, null); return $result; } /** * Method to run batch operations. * * @param object $model The model. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 1.6 */ public function batch($model = null) { $this->checkToken(); // Set the model /** @var CategoriesModelCategory $model */ $model = $this->getModel('Category'); // Preset the redirect $this->setRedirect('index.php?option=com_categories&view=categories&extension=' . $this->extension); 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 1.6 */ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') { $append = parent::getRedirectToItemAppend($recordId); $append .= '&extension=' . $this->extension; return $append; } /** * Gets the URL arguments to append to a list redirect. * * @return string The arguments to append to the redirect URL. * * @since 1.6 */ protected function getRedirectToListAppend() { $append = parent::getRedirectToListAppend(); $append .= '&extension=' . $this->extension; return $append; } /** * 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.1 */ protected function postSaveHook(JModelLegacy $model, $validData = array()) { $item = $model->getItem(); if (isset($item->params) && is_array($item->params)) { $registry = new Registry($item->params); $item->params = (string) $registry; } if (isset($item->metadata) && is_array($item->metadata)) { $registry = new Registry($item->metadata); $item->metadata = (string) $registry; } } } views/category/tmpl/edit_metadata.php 0000604 00000000507 15245557240 0013777 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; echo JLayoutHelper::render('joomla.edit.metadata', $this); views/category/tmpl/edit.php 0000604 00000010212 15245557240 0012131 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 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::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); $app = JFactory::getApplication(); $input = $app->input; $assoc = JLanguageAssociations::isEnabled(); // Are associations implemented for this extension? $extensionassoc = array_key_exists('item_associations', $this->form->getFieldsets()); JFactory::getDocument()->addScriptDeclaration(' Joomla.submitbutton = function(task) { if (task == "category.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) { jQuery("#permissions-sliders select").attr("disabled", "disabled"); ' . $this->form->getField('description')->save() . ' Joomla.submitform(task, document.getElementById("item-form")); // @deprecated 4.0 The following js is not needed since 3.7.0. if (task !== "category.apply") { window.parent.jQuery("#categoryEdit' . $this->item->id . 'Modal").modal("hide"); } } }; '); // Fieldsets to not automatically render by /layouts/joomla/edit/params.php $this->ignore_fieldsets = array('jmetadata', 'item_associations'); // In case of modal $isModal = $input->get('layout') == 'modal' ? true : false; $layout = $isModal ? 'modal' : 'edit'; $tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; ?> <form action="<?php echo JRoute::_('index.php?option=com_categories&extension=' . $input->getCmd('extension', 'com_content') . '&layout=' . $layout . $tmpl . '&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::_('JCATEGORY')); ?> <div class="row-fluid"> <div class="span9"> <?php echo $this->form->getLabel('description'); ?> <?php echo $this->form->getInput('description'); ?> </div> <div class="span3"> <?php echo JLayoutHelper::render('joomla.edit.global', $this); ?> </div> </div> <?php echo JHtml::_('bootstrap.endTab'); ?> <?php echo JLayoutHelper::render('joomla.edit.params', $this); ?> <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'publishing', JText::_('COM_CATEGORIES_FIELDSET_PUBLISHING')); ?> <div class="row-fluid form-horizontal-desktop"> <div class="span6"> <?php echo JLayoutHelper::render('joomla.edit.publishingdata', $this); ?> </div> <div class="span6"> <?php echo JLayoutHelper::render('joomla.edit.metadata', $this); ?> </div> </div> <?php echo JHtml::_('bootstrap.endTab'); ?> <?php if ( ! $isModal && $assoc && $extensionassoc) : ?> <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'associations', JText::_('JGLOBAL_FIELDSET_ASSOCIATIONS')); ?> <?php echo $this->loadTemplate('associations'); ?> <?php echo JHtml::_('bootstrap.endTab'); ?> <?php elseif ($isModal && $assoc && $extensionassoc) : ?> <div class="hidden"><?php echo $this->loadTemplate('associations'); ?></div> <?php endif; ?> <?php if ($this->canDo->get('core.admin')) : ?> <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'rules', JText::_('COM_CATEGORIES_FIELDSET_RULES')); ?> <?php echo $this->form->getInput('rules'); ?> <?php echo JHtml::_('bootstrap.endTab'); ?> <?php endif; ?> <?php echo JHtml::_('bootstrap.endTabSet'); ?> <?php echo $this->form->getInput('extension'); ?> <input type="hidden" name="task" value="" /> <input type="hidden" name="forcedLanguage" value="<?php echo $input->get('forcedLanguage', '', 'cmd'); ?>" /> <?php echo JHtml::_('form.token'); ?> </div> </form> views/category/tmpl/edit.xml 0000604 00000001154 15245557240 0012147 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <metadata> <layout title="COM_CATEGORIES_CATEGORY_VIEW_EDIT_TITLE"> <message> <![CDATA[COM_CATEGORIES_CATEGORY_VIEW_EDIT_DESC]]> </message> </layout> <fieldset name="request"> <fields name="request"> <field name="extension" type="componentscategory" label="COM_CATEGORIES_CHOOSE_COMPONENT_LABEL" description="COM_CATEGORIES_CHOOSE_COMPONENT_DESC" required="true" > <option value="">COM_MENUS_OPTION_SELECT_COMPONENT</option> </field> <field name="id" type="hidden" default="0" /> </fields> </fieldset> </metadata> views/category/tmpl/modal_metadata.php 0000604 00000000507 15245557240 0014146 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; echo JLayoutHelper::render('joomla.edit.metadata', $this); views/category/tmpl/modal.php 0000604 00000002551 15245557240 0012307 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 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::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); // @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0. $function = JFactory::getApplication()->input->getCmd('function', 'jEditCategory_' . (int) $this->item->id); // Function to update input title when changed JFactory::getDocument()->addScriptDeclaration(' function jEditCategoryModal() { if (window.parent && document.formvalidator.isValid(document.getElementById("item-form"))) { return window.parent.' . $this->escape($function) . '(document.getElementById("jform_title").value); } } '); ?> <button id="applyBtn" type="button" class="hidden" onclick="Joomla.submitbutton('category.apply'); jEditCategoryModal();"></button> <button id="saveBtn" type="button" class="hidden" onclick="Joomla.submitbutton('category.save'); jEditCategoryModal();"></button> <button id="closeBtn" type="button" class="hidden" onclick="Joomla.submitbutton('category.cancel');"></button> <div class="container-popup"> <?php $this->setLayout('edit'); ?> <?php echo $this->loadTemplate(); ?> </div> views/category/tmpl/modal_extrafields.php 0000604 00000000413 15245557240 0014674 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; views/category/tmpl/modal_associations.php 0000604 00000000513 15245557240 0015062 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; echo JLayoutHelper::render('joomla.edit.associations', $this); views/category/tmpl/edit_associations.php 0000604 00000000513 15245557240 0014713 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; echo JLayoutHelper::render('joomla.edit.associations', $this); views/category/tmpl/modal_options.php 0000604 00000002732 15245557240 0014063 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; echo JHtml::_('bootstrap.startAccordion', 'categoryOptions', array('active' => 'collapse0')); $fieldSets = $this->form->getFieldsets('params'); $i = 0; ?> <?php foreach ($fieldSets as $name => $fieldSet) : ?> <?php $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . ($i++)); if (isset($fieldSet->description) && trim($fieldSet->description)) { echo '<p class="tip">' . $this->escape(JText::_($fieldSet->description)) . '</p>'; } ?> <?php foreach ($this->form->getFieldset($name) as $field) : ?> <div class="control-group"> <div class="control-label"> <?php echo $field->label; ?> </div> <div class="controls"> <?php echo $field->input; ?> </div> </div> <?php endforeach; ?> <?php if ($name == 'basic') : ?> <div class="control-group"> <div class="control-label"> <?php echo $this->form->getLabel('note'); ?> </div> <div class="controls"> <?php echo $this->form->getInput('note'); ?> </div> </div> <?php endif; ?> <?php echo JHtml::_('bootstrap.endSlide'); ?> <?php endforeach; ?> <?php echo JHtml::_('bootstrap.endAccordion'); ?> views/category/view.html.php 0000604 00000017026 15245557240 0012157 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * HTML View class for the Categories component * * @since 1.6 */ class CategoriesViewCategory extends JViewLegacy { /** * The JForm object * * @var JForm */ protected $form; /** * The active item * * @var object */ protected $item; /** * The model state * * @var object */ protected $state; /** * Flag if an association exists * * @var boolean */ protected $assoc; /** * The actions the user is authorised to perform * * @var JObject */ protected $canDo; /** * Display the view. * * @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. */ public function display($tpl = null) { $this->form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); $section = $this->state->get('category.section') ? $this->state->get('category.section') . '.' : ''; $this->canDo = JHelperContent::getActions($this->state->get('category.component'), $section . 'category', $this->item->id); $this->assoc = $this->get('Assoc'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } // Check for tag type $this->checkTags = JHelperTags::getTypes('objectList', array($this->state->get('category.extension') . '.category'), true); JFactory::getApplication()->input->set('hidemainmenu', true); // If we are forcing a language in modal (used for associations). if ($this->getLayout() === 'modal' && $forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'cmd')) { // Set the language field to the forcedLanguage and disable changing it. $this->form->setValue('language', null, $forcedLanguage); $this->form->setFieldAttribute('language', 'readonly', 'true'); // Only allow to select categories with All language or with the forced language. $this->form->setFieldAttribute('parent_id', 'language', '*,' . $forcedLanguage); // Only allow to select tags with All language or with the forced language. $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); } $this->addToolbar(); return parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $extension = JFactory::getApplication()->input->get('extension'); $user = JFactory::getUser(); $userId = $user->id; $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); // Check to see if the type exists $ucmType = new JUcmType; $this->typeId = $ucmType->getTypeId($extension . '.category'); // Avoid nonsense situation. if ($extension == 'com_categories') { return; } // The extension can be in the form com_foo.section $parts = explode('.', $extension); $component = $parts[0]; $section = (count($parts) > 1) ? $parts[1] : null; $componentParams = JComponentHelper::getParams($component); // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = JFactory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); // Load the category helper. JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); // Get the results for each action. $canDo = $this->canDo; // If a component categories title string is present, let's use it. if ($lang->hasKey($component_title_key = $component . ($section ? "_$section" : '') . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE')) { $title = JText::_($component_title_key); } // Else if the component section string exits, let's use it elseif ($lang->hasKey($component_section_key = $component . ($section ? "_$section" : ''))) { $title = JText::sprintf('COM_CATEGORIES_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', $this->escape(JText::_($component_section_key)) ); } // Else use the base title else { $title = JText::_('COM_CATEGORIES_CATEGORY_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); } // Load specific css component JHtml::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); // Prepare the toolbar. JToolbarHelper::title( $title, 'folder category-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-category-' . ($isNew ? 'add' : 'edit') ); // For new records, check the create permission. if ($isNew && (count($user->getAuthorisedCategories($component, 'core.create')) > 0)) { JToolbarHelper::apply('category.apply'); JToolbarHelper::save('category.save'); JToolbarHelper::save2new('category.save2new'); JToolbarHelper::cancel('category.cancel'); } // If not checked out, can save the item. else { // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId); // Can't save the record if it's checked out and editable if (!$checkedOut && $itemEditable) { JToolbarHelper::apply('category.apply'); JToolbarHelper::save('category.save'); if ($canDo->get('core.create')) { JToolbarHelper::save2new('category.save2new'); } } // If an existing item, can save to a copy. if ($canDo->get('core.create')) { JToolbarHelper::save2copy('category.save2copy'); } if (JComponentHelper::isEnabled('com_contenthistory') && $componentParams->get('save_history', 0) && $itemEditable) { $typeAlias = $extension . '.category'; JToolbarHelper::versions($typeAlias, $this->item->id); } if (JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) { JToolbarHelper::custom('category.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); } JToolbarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); // Compute the ref_key $ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_HELP_KEY'; // Check if thr computed ref_key does exist in the component if (!$lang->hasKey($ref_key)) { $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT'); } /* * Get help for the category/section view for the component by * -remotely searching in a language defined dedicated URL: *component*_HELP_URL * -locally searching in a component help file if helpURL param exists in the component and is set to '' * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' */ if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) { $debug = $lang->setDebug(false); $url = JText::_($lang_help_url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($ref_key, $componentParams->exists('helpURL'), $url, $component); } } views/categories/tmpl/default.xml 0000604 00000001065 15245557240 0013157 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <metadata> <layout title="COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_TITLE"> <message> <![CDATA[COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_DESC]]> </message> </layout> <fieldset name="request"> <fields name="request"> <field name="extension" type="componentscategory" label="COM_CATEGORIES_CHOOSE_COMPONENT_LABEL" description="COM_CATEGORIES_CHOOSE_COMPONENT_DESC" required="true" > <option value="">COM_MENUS_OPTION_SELECT_COMPONENT</option> </field> </fields> </fieldset> </metadata> views/categories/tmpl/default.php 0000604 00000032073 15245557240 0013151 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 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\String\Inflector; // 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'); $extension = $this->escape($this->state->get('filter.extension')); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); $parts = explode('.', $extension, 2); $component = $parts[0]; $section = null; $columns = 7; if (count($parts) > 1) { $section = $parts[1]; $inflector = Inflector::getInstance(); if (!$inflector->isPlural($section)) { $section = $inflector->toPlural($section); } } if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_categories&task=categories.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); } ?> <form action="<?php echo JRoute::_('index.php?option=com_categories&view=categories'); ?>" 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"> <?php // Search tools bar 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="categoryList"> <thead> <tr> <th width="1%" class="nowrap center hidden-phone"> <?php echo JHtml::_('searchtools.sort', '', 'a.lft', $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.published', $listDirn, $listOrder); ?> </th> <th class="nowrap"> <?php echo JHtml::_('searchtools.sort', 'JGLOBAL_TITLE', 'a.title', $listDirn, $listOrder); ?> </th> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_published')) : $columns++; ?> <th width="1%" class="nowrap center hidden-phone hidden-tablet"> <span class="icon-publish hasTooltip" aria-hidden="true" title="<?php echo JText::_('COM_CATEGORY_COUNT_PUBLISHED_ITEMS'); ?>"><span class="element-invisible"><?php echo JText::_('COM_CATEGORY_COUNT_PUBLISHED_ITEMS'); ?></span></span> </th> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_unpublished')) : $columns++; ?> <th width="1%" class="nowrap center hidden-phone hidden-tablet"> <span class="icon-unpublish hasTooltip" aria-hidden="true" title="<?php echo JText::_('COM_CATEGORY_COUNT_UNPUBLISHED_ITEMS'); ?>"><span class="element-invisible"><?php echo JText::_('COM_CATEGORY_COUNT_UNPUBLISHED_ITEMS'); ?></span></span> </th> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_archived')) : $columns++; ?> <th width="1%" class="nowrap center hidden-phone hidden-tablet"> <span class="icon-archive hasTooltip" aria-hidden="true" title="<?php echo JText::_('COM_CATEGORY_COUNT_ARCHIVED_ITEMS'); ?>"><span class="element-invisible"><?php echo JText::_('COM_CATEGORY_COUNT_ARCHIVED_ITEMS'); ?></span></span> </th> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_trashed')) : $columns++; ?> <th width="1%" class="nowrap center hidden-phone hidden-tablet"> <span class="icon-trash hasTooltip" aria-hidden="true" title="<?php echo JText::_('COM_CATEGORY_COUNT_TRASHED_ITEMS'); ?>"><span class="element-invisible"><?php echo JText::_('COM_CATEGORY_COUNT_TRASHED_ITEMS'); ?></span></span> </th> <?php endif; ?> <th width="10%" class="nowrap hidden-phone"> <?php echo JHtml::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'access_level', $listDirn, $listOrder); ?> </th> <?php if ($this->assoc) : $columns++; ?> <th width="5%" class="nowrap hidden-phone hidden-tablet"> <?php echo JHtml::_('searchtools.sort', 'COM_CATEGORY_HEADING_ASSOCIATION', 'association', $listDirn, $listOrder); ?> </th> <?php endif; ?> <th width="10%" class="nowrap hidden-phone"> <?php echo JHtml::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'language_title', $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="<?php echo $columns; ?>"> <?php echo $this->pagination->getListFooter(); ?> </td> </tr> </tfoot> <tbody> <?php foreach ($this->items as $i => $item) : ?> <?php $canEdit = $user->authorise('core.edit', $extension . '.category.' . $item->id); $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; $canEditOwn = $user->authorise('core.edit.own', $extension . '.category.' . $item->id) && $item->created_user_id == $userId; $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; // Get the parents of item for sorting if ($item->level > 1) { $parentsStr = ''; $_currentParentId = $item->parent_id; $parentsStr = ' ' . $_currentParentId; for ($i2 = 0; $i2 < $item->level; $i2++) { foreach ($this->ordering as $k => $v) { $v = implode('-', $v); $v = '-' . $v . '-'; if (strpos($v, '-' . $_currentParentId . '-') !== false) { $parentsStr .= ' ' . $k; $_currentParentId = $k; break; } } } } else { $parentsStr = ''; } ?> <tr class="row<?php echo $i % 2; ?>" sortable-group-id="<?php echo $item->parent_id; ?>" item-id="<?php echo $item->id ?>" parents="<?php echo $parentsStr ?>" level="<?php echo $item->level ?>"> <td class="order nowrap center hidden-phone"> <?php $iconClass = ''; if (!$canChange) { $iconClass = ' inactive'; } elseif (!$saveOrder) { $iconClass = ' inactive tip-top hasTooltip" title="' . JHtml::_('tooltipText', 'JORDERINGDISABLED'); } ?> <span class="sortable-handler<?php echo $iconClass ?>"> <span class="icon-menu"></span> </span> <?php if ($canChange && $saveOrder) : ?> <input type="text" style="display:none" name="order[]" size="5" value="<?php echo $item->lft; ?>" /> <?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->published, $i, 'categories.', $canChange); ?> <?php if ($canChange) { // Create dropdown items JHtml::_('actionsdropdown.' . ((int) $item->published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'categories'); JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'categories'); // Render dropdown list echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); } ?> </div> </td> <td> <?php echo JLayoutHelper::render('joomla.html.treeprefix', array('level' => $item->level)); ?> <?php if ($item->checked_out) : ?> <?php echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'categories.', $canCheckin); ?> <?php endif; ?> <?php if ($canEdit || $canEditOwn) : ?> <a class="hasTooltip" href="<?php echo JRoute::_('index.php?option=com_categories&task=category.edit&id=' . $item->id . '&extension=' . $extension); ?>" title="<?php echo JText::_('JACTION_EDIT'); ?>"> <?php echo $this->escape($item->title); ?></a> <?php else : ?> <?php echo $this->escape($item->title); ?> <?php endif; ?> <span class="small" title="<?php echo $this->escape($item->path); ?>"> <?php if (empty($item->note)) : ?> <?php echo JText::sprintf('JGLOBAL_LIST_ALIAS', $this->escape($item->alias)); ?> <?php else : ?> <?php echo JText::sprintf('JGLOBAL_LIST_ALIAS_NOTE', $this->escape($item->alias), $this->escape($item->note)); ?> <?php endif; ?> </span> </td> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_published')) : ?> <td class="center btns hidden-phone hidden-tablet"> <a class="badge <?php if ($item->count_published > 0) echo 'badge-success'; ?>" title="<?php echo JText::_('COM_CATEGORY_COUNT_PUBLISHED_ITEMS'); ?>" href="<?php echo JRoute::_('index.php?option=' . $component . ($section ? '&view=' . $section : '') . '&filter[category_id]=' . (int) $item->id . '&filter[published]=1' . '&filter[level]=1'); ?>"> <?php echo $item->count_published; ?></a> </td> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> <td class="center btns hidden-phone hidden-tablet"> <a class="badge <?php if ($item->count_unpublished > 0) echo 'badge-important'; ?>" title="<?php echo JText::_('COM_CATEGORY_COUNT_UNPUBLISHED_ITEMS'); ?>" href="<?php echo JRoute::_('index.php?option=' . $component . ($section ? '&view=' . $section : '') . '&filter[category_id]=' . (int) $item->id . '&filter[published]=0' . '&filter[level]=1'); ?>"> <?php echo $item->count_unpublished; ?></a> </td> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_archived')) : ?> <td class="center btns hidden-phone hidden-tablet"> <a class="badge <?php if ($item->count_archived > 0) echo 'badge-info'; ?>" title="<?php echo JText::_('COM_CATEGORY_COUNT_ARCHIVED_ITEMS'); ?>" href="<?php echo JRoute::_('index.php?option=' . $component . ($section ? '&view=' . $section : '') . '&filter[category_id]=' . (int) $item->id . '&filter[published]=2' . '&filter[level]=1'); ?>"> <?php echo $item->count_archived; ?></a> </td> <?php endif; ?> <?php if (isset($this->items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> <td class="center btns hidden-phone hidden-tablet"> <a class="badge <?php if ($item->count_trashed > 0) echo 'badge-inverse'; ?>" title="<?php echo JText::_('COM_CATEGORY_COUNT_TRASHED_ITEMS'); ?>" href="<?php echo JRoute::_('index.php?option=' . $component . ($section ? '&view=' . $section : '') . '&filter[category_id]=' . (int) $item->id . '&filter[published]=-2' . '&filter[level]=1'); ?>"> <?php echo $item->count_trashed; ?></a> </td> <?php endif; ?> <td class="small hidden-phone"> <?php echo $this->escape($item->access_level); ?> </td> <?php if ($this->assoc) : ?> <td class="hidden-phone hidden-tablet"> <?php if ($item->association) : ?> <?php echo JHtml::_('CategoriesAdministrator.association', $item->id, $extension); ?> <?php endif; ?> </td> <?php endif; ?> <td class="small nowrap hidden-phone"> <?php echo JLayoutHelper::render('joomla.content.language', $item); ?> </td> <td class="hidden-phone"> <span title="<?php echo sprintf('%d-%d', $item->lft, $item->rgt); ?>"> <?php echo (int) $item->id; ?></span> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php // Load the batch processing form. ?> <?php if ($user->authorise('core.create', $extension) && $user->authorise('core.edit', $extension) && $user->authorise('core.edit.state', $extension)) : ?> <?php echo JHtml::_( 'bootstrap.renderModal', 'collapseModal', array( 'title' => JText::_('COM_CATEGORIES_BATCH_OPTIONS'), 'footer' => $this->loadTemplate('batch_footer'), ), $this->loadTemplate('batch_body') ); ?> <?php endif; ?> <?php endif; ?> <input type="hidden" name="extension" value="<?php echo $extension; ?>" /> <input type="hidden" name="task" value="" /> <input type="hidden" name="boxchecked" value="0" /> <?php echo JHtml::_('form.token'); ?> </div> </form> views/categories/tmpl/modal.php 0000604 00000012643 15245557240 0012622 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; $app = JFactory::getApplication(); if ($app->isClient('site')) { JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); } JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); // 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')); $extension = $this->escape($this->state->get('filter.extension')); $function = $app->input->getCmd('function', 'jSelectCategory'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?> <div class="container-popup"> <form action="<?php echo JRoute::_('index.php?option=com_categories&view=categories&layout=modal&tmpl=component&function=' . $function . '&' . JSession::getFormToken() . '=1'); ?>" method="post" name="adminForm" id="adminForm"> <?php echo JLayoutHelper::render('joomla.searchtools.default', array('view' => $this)); ?> <div class="clearfix"></div> <?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="categoryList"> <thead> <tr> <th width="1%" class="nowrap center"> <?php echo JHtml::_('searchtools.sort', 'JSTATUS', 'a.published', $listDirn, $listOrder); ?> </th> <th class="nowrap"> <?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', 'access_level', $listDirn, $listOrder); ?> </th> <th width="15%" class="nowrap hidden-phone"> <?php echo JHtml::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'language_title', $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="5"> <?php echo $this->pagination->getListFooter(); ?> </td> </tr> </tfoot> <tbody> <?php $iconStates = array( -2 => 'icon-trash', 0 => 'icon-unpublish', 1 => 'icon-publish', 2 => 'icon-archive', ); ?> <?php foreach ($this->items as $i => $item) : ?> <?php if ($item->language && JLanguageMultilang::isEnabled()) { $tag = strlen($item->language); if ($tag == 5) { $lang = substr($item->language, 0, 2); } elseif ($tag == 6) { $lang = substr($item->language, 0, 3); } else { $lang = ''; } } elseif (!JLanguageMultilang::isEnabled()) { $lang = ''; } ?> <tr class="row<?php echo $i % 2; ?>"> <td class="center"> <span class="<?php echo $iconStates[$this->escape($item->published)]; ?>" aria-hidden="true"></span> </td> <td> <?php echo JLayoutHelper::render('joomla.html.treeprefix', array('level' => $item->level)); ?> <a href="javascript:void(0)" onclick="if (window.parent) window.parent.<?php echo $this->escape($function); ?>('<?php echo $item->id; ?>', '<?php echo $this->escape(addslashes($item->title)); ?>', null, '<?php echo $this->escape(ContentHelperRoute::getCategoryRoute($item->id, $item->language)); ?>', '<?php echo $this->escape($lang); ?>', null);"> <?php echo $this->escape($item->title); ?></a> <span class="small" title="<?php echo $this->escape($item->path); ?>"> <?php if (empty($item->note)) : ?> <?php echo JText::sprintf('JGLOBAL_LIST_ALIAS', $this->escape($item->alias)); ?> <?php else : ?> <?php echo JText::sprintf('JGLOBAL_LIST_ALIAS_NOTE', $this->escape($item->alias), $this->escape($item->note)); ?> <?php endif; ?> </span> </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="extension" value="<?php echo $extension; ?>" /> <input type="hidden" name="task" value="" /> <input type="hidden" name="boxchecked" value="0" /> <input type="hidden" name="forcedLanguage" value="<?php echo $app->input->get('forcedLanguage', '', 'CMD'); ?>" /> <?php echo JHtml::_('form.token'); ?> </form> </div> views/categories/tmpl/default_batch_footer.php 0000604 00000001304 15245557240 0015661 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2015 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-category-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('category.batch');return false;"> <?php echo JText::_('JGLOBAL_BATCH_PROCESS'); ?> </button> views/categories/tmpl/default_batch_body.php 0000604 00000004561 15245557240 0015330 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; $options = array( JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) ); $published = (int) $this->state->get('filter.published'); $extension = $this->escape($this->state->get('filter.extension')); ?> <div class="container-fluid"> <div class="row-fluid"> <div class="control-group span6"> <div class="controls"> <?php echo JHtml::_('batch.language'); ?> </div> </div> <div class="control-group span6"> <div class="controls"> <?php echo JHtml::_('batch.access'); ?> </div> </div> </div> <div class="row-fluid"> <?php if ($published >= 0) : ?> <div class="span6"> <div class="control-group"> <label id="batch-choose-action-lbl" for="batch-category-id" class="control-label"> <?php echo JText::_('JLIB_HTML_BATCH_MENU_LABEL'); ?> </label> <div id="batch-choose-action" class="combo controls"> <select name="batch[category_id]" id="batch-category-id"> <option value=""><?php echo JText::_('JLIB_HTML_BATCH_NO_CATEGORY') ?></option> <?php echo JHtml::_('select.options', JHtml::_('category.categories', $extension, array('filter.published' => $this->state->get('filter.published')))); ?> </select> </div> </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> <?php endif; ?> <div class="control-group span6"> <div class="controls"> <?php echo JHtml::_('batch.tag'); ?> </div> </div> </div> <?php if ($extension === 'com_content') : ?> <div class="row-fluid"> <div class="span6"> <div class="control-group"> <label id="flip-ordering-id-lbl" for="flip-ordering-id" class="control-label"> <?php echo JText::_('JLIB_HTML_BATCH_FLIPORDERING_LABEL'); ?> </label> <?php echo JHtml::_('select.booleanlist', 'batch[flip_ordering]', array(), 0, 'JYES', 'JNO', 'flip-ordering-id'); ?> </div> </div> </div> <?php endif; ?> </div> views/categories/view.html.php 0000604 00000020311 15245557240 0012456 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Categories view class for the Category package. * * @since 1.6 */ class CategoriesViewCategories extends JViewLegacy { /** * An array of items * * @var array */ protected $items; /** * The pagination object * * @var JPagination */ protected $pagination; /** * The model state * * @var object */ protected $state; /** * Flag if an association exists * * @var boolean */ protected $assoc; /** * Form object for search filters * * @var JForm */ public $filterForm; /** * The active search filters * * @var array */ public $activeFilters; /** * The sidebar markup * * @var string */ protected $string; /** * Display the view * * @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. */ public function display($tpl = null) { $this->state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->assoc = $this->get('Assoc'); $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); } // Preprocess the list of items to find ordering divisions. foreach ($this->items as &$item) { $this->ordering[$item->parent_id][] = $item->id; } // Levels filter - Used in Hathor. $this->f_levels = array( JHtml::_('select.option', '1', JText::_('J1')), JHtml::_('select.option', '2', JText::_('J2')), JHtml::_('select.option', '3', JText::_('J3')), JHtml::_('select.option', '4', JText::_('J4')), JHtml::_('select.option', '5', JText::_('J5')), JHtml::_('select.option', '6', JText::_('J6')), JHtml::_('select.option', '7', JText::_('J7')), JHtml::_('select.option', '8', JText::_('J8')), JHtml::_('select.option', '9', JText::_('J9')), JHtml::_('select.option', '10', JText::_('J10')), ); // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') { $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); } else { // In article associations modal we need to remove language filter if forcing a language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement('<field name="language" type="hidden" default="' . $forcedLanguage . '" />'); $this->filterForm->setField($languageXml, 'filter', true); // Also, unset the active language filter so the search tools is not open by default with this filter. unset($this->activeFilters['language']); } } return parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $categoryId = $this->state->get('filter.category_id'); $component = $this->state->get('filter.component'); $section = $this->state->get('filter.section'); $canDo = JHelperContent::getActions($component, 'category', $categoryId); $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolbar::getInstance('toolbar'); // Avoid nonsense situation. if ($component == 'com_categories') { return; } // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = JFactory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); // Load the category helper. JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); // If a component categories title string is present, let's use it. if ($lang->hasKey($component_title_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_TITLE')) { $title = JText::_($component_title_key); } elseif ($lang->hasKey($component_section_key = strtoupper($component . ($section ? "_$section" : '')))) // Else if the component section string exits, let's use it { $title = JText::sprintf('COM_CATEGORIES_CATEGORIES_TITLE', $this->escape(JText::_($component_section_key))); } else // Else use the base title { $title = JText::_('COM_CATEGORIES_CATEGORIES_BASE_TITLE'); } // Load specific css component JHtml::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); // Prepare the toolbar. JToolbarHelper::title($title, 'folder categories ' . substr($component, 4) . ($section ? "-$section" : '') . '-categories'); if ($canDo->get('core.create') || count($user->getAuthorisedCategories($component, 'core.create')) > 0) { JToolbarHelper::addNew('category.add'); } if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) { JToolbarHelper::editList('category.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('categories.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('categories.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::archiveList('categories.archive'); } if (JFactory::getUser()->authorise('core.admin')) { JToolbarHelper::checkin('categories.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')) { JToolbarHelper::custom('categories.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); } if ($canDo->get('core.admin') || $canDo->get('core.options')) { JToolbarHelper::preferences($component); } if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete', $component)) { JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'categories.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('categories.trash'); } // Compute the ref_key if it does exist in the component if (!$lang->hasKey($ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_HELP_KEY')) { $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORIES'; } /* * Get help for the categories view for the component by * -remotely searching in a language defined dedicated URL: *component*_HELP_URL * -locally searching in a component help file if helpURL param exists in the component and is set to '' * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' */ if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) { $debug = $lang->setDebug(false); $url = JText::_($lang_help_url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($ref_key, JComponentHelper::getParams($component)->exists('helpURL'), $url); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID'), ); } } models/category.php 0000604 00000104040 15245557240 0010361 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 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\CMS\Factory; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; /** * Categories Component Category Model * * @since 1.6 */ class CategoriesModelCategory extends JModelAdmin { /** * The prefix to use with controller messages. * * @var string * @since 1.6 */ protected $text_prefix = 'COM_CATEGORIES'; /** * The type alias for this content type. Used for content version history. * * @var string * @since 3.2 */ public $typeAlias = null; /** * The context used for the associations table * * @var string * @since 3.4.4 */ protected $associationsContext = 'com_categories.item'; /** * Does an association exist? Caches the result of getAssoc(). * * @var boolean|null * @since 3.10.4 */ private $hasAssociation; /** * Override parent constructor. * * @param array $config An optional associative array of configuration settings. * * @see JModelLegacy * @since 3.2 */ public function __construct($config = array()) { parent::__construct($config); $extension = JFactory::getApplication()->input->get('extension', 'com_content'); $this->typeAlias = $extension . '.category'; // Add a new batch command $this->batch_commands['flip_ordering'] = 'batchFlipordering'; } /** * 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 set in the component. * * @since 1.6 */ protected function canDelete($record) { if (empty($record->id) || $record->published != -2) { return false; } return JFactory::getUser()->authorise('core.delete', $record->extension . '.category.' . (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 set in the component. * * @since 1.6 */ protected function canEditState($record) { $user = JFactory::getUser(); // Check for existing category. if (!empty($record->id)) { return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->id); } // New category, so check against the parent. if (!empty($record->parent_id)) { return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->parent_id); } // Default to component settings if neither category nor parent known. return $user->authorise('core.edit.state', $record->extension); } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A JTable object * * @since 1.6 */ public function getTable($type = 'Category', $prefix = 'CategoriesTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 */ protected function populateState() { $app = JFactory::getApplication('administrator'); $parentId = $app->input->getInt('parent_id'); $this->setState('category.parent_id', $parentId); // Load the User state. $pk = $app->input->getInt('id'); $this->setState($this->getName() . '.id', $pk); $extension = $app->input->get('extension', 'com_content'); $this->setState('category.extension', $extension); $parts = explode('.', $extension); // Extract the component name $this->setState('category.component', $parts[0]); // Extract the optional section name $this->setState('category.section', (count($parts) > 1) ? $parts[1] : null); // Load the parameters. $params = JComponentHelper::getParams('com_categories'); $this->setState('params', $params); } /** * Method to get a category. * * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. * * @return mixed Category data object on success, false on failure. * * @since 1.6 */ public function getItem($pk = null) { if ($result = parent::getItem($pk)) { // Prime required properties. if (empty($result->id)) { $result->parent_id = $this->getState('category.parent_id'); $result->extension = $this->getState('category.extension'); } // Convert the metadata field to an array. $registry = new Registry($result->metadata); $result->metadata = $registry->toArray(); if (!empty($result->id)) { $result->tags = new JHelperTags; $result->tags->getTagIds($result->id, $result->extension . '.category'); } } $assoc = $this->getAssoc(); if ($assoc) { if ($result->id != null) { $result->associations = ArrayHelper::toInteger(CategoriesHelper::getAssociations($result->id, $result->extension)); } else { $result->associations = array(); } } return $result; } /** * Method to get the row form. * * @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 JForm|boolean A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { $extension = $this->getState('category.extension'); $jinput = JFactory::getApplication()->input; // A workaround to get the extension into the model for save requests. if (empty($extension) && isset($data['extension'])) { $extension = $data['extension']; $parts = explode('.', $extension); $this->setState('category.extension', $extension); $this->setState('category.component', $parts[0]); $this->setState('category.section', @$parts[1]); } // Get the form. $form = $this->loadForm('com_categories.category' . $extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Modify the form based on Edit State access controls. if (empty($data['extension'])) { $data['extension'] = $extension; } $categoryId = $jinput->get('id'); $parts = explode('.', $extension); $assetKey = $categoryId ? $extension . '.category.' . $categoryId : $parts[0]; if (!JFactory::getUser()->authorise('core.edit.state', $assetKey)) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', '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('published', 'filter', 'unset'); } return $form; } /** * A protected method to get the where clause for the reorder * This ensures that the row will be moved relative to a row with the same extension * * @param JTableCategory $table Current table instance * * @return array An array of conditions to add to add to ordering queries. * * @since 1.6 */ protected function getReorderConditions($table) { return 'extension = ' . $this->_db->quote($table->extension); } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $app = JFactory::getApplication(); $data = $app->getUserState('com_categories.edit.' . $this->getName() . '.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 extension the Category Manager is used and get selected fields $extension = substr($app->getUserState('com_categories.categories.filter.extension'), 4); $filters = (array) $app->getUserState('com_categories.categories.' . $extension . '.filter'); $data->set( 'published', $app->input->getInt( 'published', ((isset($filters['published']) && $filters['published'] !== '') ? $filters['published'] : 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_categories.category', $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', $data['extension'])) { if (isset($data['rules'])) { unset($data['rules']); } } return parent::validate($form, $data, $group); } /** * 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. * * @return mixed * * @see JFormField * @since 1.6 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { jimport('joomla.filesystem.path'); $lang = JFactory::getLanguage(); $component = $this->getState('category.component'); $section = $this->getState('category.section'); $extension = JFactory::getApplication()->input->get('extension', null); // Get the component form if it exists $name = 'category' . ($section ? ('.' . $section) : ''); // Looking first in the component models/forms folder $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/models/forms/$name.xml"); // Old way: looking in the component folder if (!file_exists($path)) { $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/$name.xml"); } if (file_exists($path)) { $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')); } } // Try to find the component helper. $eName = str_replace('com_', '', $component); $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/helpers/category.php"); if (file_exists($path)) { $cName = ucfirst($eName) . ucfirst($section) . 'HelperCategory'; JLoader::register($cName, $path); if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) { $lang->load($component, JPATH_BASE, null, false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); call_user_func_array(array($cName, 'onPrepareForm'), array(&$form)); // Check for an error. if ($form instanceof Exception) { $this->setError($form->getMessage()); return false; } } } // Set the access control rules field component value. $form->setFieldAttribute('rules', 'component', $component); $form->setFieldAttribute('rules', 'section', $name); // Association category items if ($this->getAssoc()) { $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); if (count($languages) > 1) { $addform = new SimpleXMLElement('<form />'); $fields = $addform->addChild('fields'); $fields->addAttribute('name', 'associations'); $fieldset = $fields->addChild('fieldset'); $fieldset->addAttribute('name', 'item_associations'); foreach ($languages as $language) { $field = $fieldset->addChild('field'); $field->addAttribute('name', $language->lang_code); $field->addAttribute('type', 'modal_category'); $field->addAttribute('language', $language->lang_code); $field->addAttribute('label', $language->title); $field->addAttribute('translate_label', 'false'); $field->addAttribute('extension', $extension); $field->addAttribute('select', 'true'); $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); $field->addAttribute('propagate', 'true'); } $form->load($addform, false); } } // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 1.6 */ public function save($data) { $dispatcher = JEventDispatcher::getInstance(); $table = $this->getTable(); $input = JFactory::getApplication()->input; $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); $isNew = true; $context = $this->option . '.' . $this->name; if (!empty($data['tags']) && $data['tags'][0] != '') { $table->newTags = $data['tags']; } // Include the plugins for the save events. JPluginHelper::importPlugin($this->events_map['save']); // Load the row if saving an existing category. if ($pk > 0) { $table->load($pk); $isNew = false; } // Set the new parent id if parent id not matched OR while New/Save as Copy . if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) { $table->setLocation($data['parent_id'], 'last-child'); } // Alter the title for save as copy if ($input->get('task') == 'save2copy') { $origTable = clone $this->getTable(); $origTable->load($input->getInt('id')); if ($data['title'] == $origTable->title) { list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); $data['title'] = $title; $data['alias'] = $alias; } else { if ($data['alias'] == $origTable->alias) { $data['alias'] = ''; } } $data['published'] = 0; } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Bind the rules. if (isset($data['rules'])) { $rules = new JAccessRules($data['rules']); $table->setRules($rules); } // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the before save event. $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew, $data)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } $assoc = $this->getAssoc(); if ($assoc) { // Adding self to the association $associations = isset($data['associations']) ? $data['associations'] : array(); // Unset any invalid associations $associations = Joomla\Utilities\ArrayHelper::toInteger($associations); foreach ($associations as $tag => $id) { if (!$id) { unset($associations[$tag]); } } // Detecting all item menus $allLanguage = $table->language == '*'; if ($allLanguage && !empty($associations)) { JError::raiseNotice(403, JText::_('COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED')); } // Get associationskey for edited item $db = $this->getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('key')) ->from($db->quoteName('#__associations')) ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)) ->where($db->quoteName('id') . ' = ' . (int) $table->id); $db->setQuery($query); $oldKey = $db->loadResult(); // Deleting old associations for the associated items $query = $db->getQuery(true) ->delete($db->quoteName('#__associations')) ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)); if ($associations) { $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')'); } else { $query->where($db->quoteName('key') . ' = ' . $db->quote($oldKey)); } $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // Adding self to the association if (!$allLanguage) { $associations[$table->language] = (int) $table->id; } if (count($associations) > 1) { // Adding new association for these items $key = md5(json_encode($associations)); $query->clear() ->insert('#__associations'); foreach ($associations as $id) { $query->values(((int) $id) . ',' . $db->quote($this->associationsContext) . ',' . $db->quote($key)); } $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } } // Trigger the after save event. $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew, $data)); // Rebuild the path for the category: if (!$table->rebuildPath($table->id)) { $this->setError($table->getError()); return false; } // Rebuild the paths of the category's children: if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) { $this->setError($table->getError()); return false; } $this->setState($this->getName() . '.id', $table->id); if (Factory::getApplication()->input->get('task') == 'editAssociations') { return $this->redirectToAssociations($data); } // Clear the cache $this->cleanCache(); return true; } /** * Method to change the published state of one or more records. * * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { if (parent::publish($pks, $value)) { $dispatcher = JEventDispatcher::getInstance(); $extension = JFactory::getApplication()->input->get('extension'); // Include the content plugins for the change of category state event. JPluginHelper::importPlugin('content'); // Trigger the onCategoryChangeState event. $dispatcher->trigger('onCategoryChangeState', array($extension, $pks, $value)); return true; } } /** * Method rebuild the entire nested set tree. * * @return boolean False on failure or error, true otherwise. * * @since 1.6 */ public function rebuild() { // Get an instance of the table object. $table = $this->getTable(); if (!$table->rebuild()) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Method to save the reordered nested set tree. * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * * @param array $idArray An array of primary key ids. * @param integer $lftArray The lft value * * @return boolean False on failure or error, True otherwise * * @since 1.6 */ public function saveorder($idArray = null, $lftArray = null) { // Get an instance of the table object. $table = $this->getTable(); if (!$table->saveorder($idArray, $lftArray)) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch tag a list of categories. * * @param integer $value The value of the new tag. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean true if successful; false otherwise. */ protected function batchTag($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); foreach ($pks as $pk) { if ($user->authorise('core.edit', $contexts[$pk])) { $table->reset(); $table->load($pk); $tags = array($value); /** @var JTableObserverTags $tagsObserver */ $tagsObserver = $table->getObserverOfClass('JTableObserverTags'); $result = $tagsObserver->setNewTags($tags, false); if (!$result) { $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; } /** * Batch flip category ordering. * * @param integer $value The new category. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return mixed An array of new IDs on success, boolean false on failure. * * @since 3.6.3 */ protected function batchFlipordering($value, $pks, $contexts) { $successful = array(); $db = $this->getDbo(); $query = $db->getQuery(true); /** * For each category get the max ordering value * Re-order with max - ordering */ foreach ($pks as $id) { $query->select('MAX(ordering)') ->from('#__content') ->where($db->qn('catid') . ' = ' . $db->q($id)); $db->setQuery($query); $max = (int) $db->loadresult(); $max++; $query->clear(); $query->update('#__content') ->set($db->qn('ordering') . ' = ' . $max . ' - ' . $db->qn('ordering')) ->where($db->qn('catid') . ' = ' . $db->q($id)); $db->setQuery($query); if ($db->execute()) { $successful[] = $id; } } return empty($successful) ? false : $successful; } /** * Batch copy categories to a new category. * * @param integer $value The new category. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return mixed An array of new IDs on success, boolean false on failure. * * @since 1.6 */ protected function batchCopy($value, $pks, $contexts) { $type = new JUcmType; $this->type = $type->getTypeByAlias($this->typeAlias); // $value comes as {parent_id}.{extension} $parts = explode('.', $value); $parentId = (int) ArrayHelper::getValue($parts, 0, 1); $db = $this->getDbo(); $extension = JFactory::getApplication()->input->get('extension', '', 'word'); $newIds = array(); // Check that the parent exists if ($parentId) { if (!$this->table->load($parentId)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category if ($parentId == $this->table->getRootId()) { $canCreate = $this->user->authorise('core.create', $extension); } else { $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); } if (!$canCreate) { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } } // If the parent is 0, set it to the ID of the root item in the tree if (empty($parentId)) { if (!$parentId = $this->table->getRootId()) { $this->setError($db->getErrorMsg()); return false; } // Make sure we can create in root elseif (!$this->user->authorise('core.create', $extension)) { $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } } // We need to log the parent ID $parents = array(); // Calculate the emergency stop count as a precaution against a runaway loop bug $query = $db->getQuery(true) ->select('COUNT(id)') ->from($db->quoteName('#__categories')); $db->setQuery($query); try { $count = $db->loadResult(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // Parent exists so let's proceed while (!empty($pks) && $count > 0) { // Pop the first id off the stack $pk = array_shift($pks); $this->table->reset(); // Check that the row actually exists if (!$this->table->load($pk)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Copy is a bit tricky, because we also need to copy the children $query->clear() ->select('id') ->from($db->quoteName('#__categories')) ->where('lft > ' . (int) $this->table->lft) ->where('rgt < ' . (int) $this->table->rgt); $db->setQuery($query); $childIds = $db->loadColumn(); // Add child ID's to the array only if they aren't already there. foreach ($childIds as $childId) { if (!in_array($childId, $pks)) { $pks[] = $childId; } } // Make a copy of the old ID, Parent ID and Asset ID $oldId = $this->table->id; $oldParentId = $this->table->parent_id; $oldAssetId = $this->table->asset_id; // Reset the id because we are making a copy. $this->table->id = 0; // If we a copying children, the Old ID will turn up in the parents list // otherwise it's a new top level item $this->table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; // Set the new location in the tree for the node. $this->table->setLocation($this->table->parent_id, 'last-child'); // @TODO: Deal with ordering? // $this->table->ordering = 1; $this->table->level = null; $this->table->asset_id = null; $this->table->lft = null; $this->table->rgt = null; // Alter the title & alias list($title, $alias) = $this->generateNewTitle($this->table->parent_id, $this->table->alias, $this->table->title); $this->table->title = $title; $this->table->alias = $alias; // Unpublish because we are making a copy $this->table->published = 0; $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); // Store the row. if (!$this->table->store()) { $this->setError($this->table->getError()); return false; } // Get the new item ID $newId = $this->table->get('id'); // Add the new ID to the array $newIds[$pk] = $newId; // Copy rules $query->clear() ->update($db->quoteName('#__assets', 't')) ->join('INNER', $db->quoteName('#__assets', 's') . ' ON ' . $db->quoteName('s.id') . ' = ' . $oldAssetId ) ->set($db->quoteName('t.rules') . ' = ' . $db->quoteName('s.rules')) ->where($db->quoteName('t.id') . ' = ' . $this->table->asset_id); $db->setQuery($query)->execute(); // Now we log the old 'parent' to the new 'parent' $parents[$oldId] = $this->table->id; $count--; } // Rebuild the hierarchy. if (!$this->table->rebuild()) { $this->setError($this->table->getError()); return false; } // Rebuild the tree path. if (!$this->table->rebuildPath($this->table->id)) { $this->setError($this->table->getError()); return false; } return $newIds; } /** * Batch move categories to a new category. * * @param integer $value The new category ID. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True on success. * * @since 1.6 */ protected function batchMove($value, $pks, $contexts) { $parentId = (int) $value; $type = new JUcmType; $this->type = $type->getTypeByAlias($this->typeAlias); $db = $this->getDbo(); $query = $db->getQuery(true); $extension = JFactory::getApplication()->input->get('extension', '', 'word'); // Check that the parent exists. if ($parentId) { if (!$this->table->load($parentId)) { if ($error = $this->table->getError()) { // Fatal error. $this->setError($error); return false; } else { // Non-fatal error. $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category. if ($parentId == $this->table->getRootId()) { $canCreate = $this->user->authorise('core.create', $extension); } else { $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); } if (!$canCreate) { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } // Check that user has edit permission for every category being moved // Note that the entire batch operation fails if any category lacks edit permission foreach ($pks as $pk) { if (!$this->user->authorise('core.edit', $extension . '.category.' . $pk)) { // Error since user cannot edit this category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); return false; } } } // We are going to store all the children and just move the category $children = array(); // Parent exists so let's proceed foreach ($pks as $pk) { // Check that the row actually exists if (!$this->table->load($pk)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Set the new location in the tree for the node. $this->table->setLocation($parentId, 'last-child'); // Check if we are moving to a different parent if ($parentId != $this->table->parent_id) { // Add the child node ids to the children array. $query->clear() ->select('id') ->from($db->quoteName('#__categories')) ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $this->table->lft . ' AND ' . (int) $this->table->rgt); $db->setQuery($query); try { $children = array_merge($children, (array) $db->loadColumn()); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); // Store the row. if (!$this->table->store()) { $this->setError($this->table->getError()); return false; } // Rebuild the tree path. if (!$this->table->rebuildPath()) { $this->setError($this->table->getError()); return false; } } // Process the child rows if (!empty($children)) { // Remove any duplicates and sanitize ids. $children = array_unique($children); $children = ArrayHelper::toInteger($children); } return true; } /** * Custom clean the cache of com_content and content modules * * @param string $group Cache group name. * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ protected function cleanCache($group = null, $clientId = 0) { $extension = JFactory::getApplication()->input->get('extension'); switch ($extension) { 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($extension); break; } } /** * Method to change the title & alias. * * @param integer $parentId The id of the parent. * @param string $alias The alias. * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 1.7 */ protected function generateNewTitle($parentId, $alias, $title) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) { $title = StringHelper::increment($title); $alias = StringHelper::increment($alias, 'dash'); } return array($title, $alias); } /** * Method to determine if a category association is available. * * @return boolean True if a category association is available; false otherwise. */ public function getAssoc() { if (!is_null($this->hasAssociation)) { return $this->hasAssociation; } $extension = $this->getState('category.extension'); $this->hasAssociation = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); if (!$this->hasAssociation || !$component || !$cname) { $this->hasAssociation = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); $this->hasAssociation = class_exists($hname) && !empty($hname::$category_association); } return $this->hasAssociation; } } models/categories.php 0000604 00000025240 15245557240 0010675 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Categories Component Categories Model * * @since 1.6 */ class CategoriesModelCategories extends JModelList { /** * Does an association exist? Caches the result of getAssoc(). * * @var boolean|null * @since 3.10.4 */ private $hasAssociation; /** * Constructor. * * @param array $config An optional associative array of configuration settings. * * @see JControllerLegacy * @since 1.6 */ public function __construct($config = array()) { if (empty($config['filter_fields'])) { $config['filter_fields'] = array( 'id', 'a.id', 'title', 'a.title', 'alias', 'a.alias', 'published', 'a.published', 'access', 'a.access', 'access_level', 'language', 'a.language', 'language_title', 'checked_out', 'a.checked_out', 'checked_out_time', 'a.checked_out_time', 'created_time', 'a.created_time', 'created_user_id', 'a.created_user_id', 'lft', 'a.lft', 'rgt', 'a.rgt', 'level', 'a.level', 'path', 'a.path', 'tag', ); } if (JLanguageAssociations::isEnabled()) { $config['filter_fields'][] = 'association'; } parent::__construct($config); } /** * Method to auto-populate the model state. * * 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 1.6 */ protected function populateState($ordering = 'a.lft', $direction = 'asc') { $app = JFactory::getApplication(); $forcedLanguage = $app->input->get('forcedLanguage', '', 'cmd'); // Adjust the context to support modal layouts. if ($layout = $app->input->get('layout')) { $this->context .= '.' . $layout; } // Adjust the context to support forced languages. if ($forcedLanguage) { $this->context .= '.' . $forcedLanguage; } $extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); $this->setState('filter.extension', $extension); $parts = explode('.', $extension); // Extract the component name $this->setState('filter.component', $parts[0]); // Extract the optional section name $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.search', 'filter_search', '', 'string')); $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); $this->setState('filter.tag', $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', '', 'string')); $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'string')); // List state information. parent::populateState($ordering, $direction); // Force a language. if (!empty($forcedLanguage)) { $this->setState('filter.language', $forcedLanguage); } } /** * Method to get a store id based on 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 A prefix for the store id. * * @return string A store id. * * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.extension'); $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.published'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.language'); $id .= ':' . $this->getState('filter.level'); $id .= ':' . $this->getState('filter.tag'); return parent::getStoreId($id); } /** * Method to get a database query to list categories. * * @return JDatabaseQuery object. * * @since 1.6 */ 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.id, a.title, a.alias, a.note, a.published, a.access' . ', a.checked_out, a.checked_out_time, a.created_user_id' . ', a.path, a.parent_id, a.level, a.lft, a.rgt' . ', a.language' ) ); $query->from('#__categories 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 associations. $this->hasAssociation = $this->getAssoc(); if ($this->hasAssociation) { $query->select('COUNT(asso2.id)>1 as association') ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_categories.item')) ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') ->group('a.id, l.title, uc.name, ag.title, ua.name'); } // Filter by extension if ($extension = $this->getState('filter.extension')) { $query->where('a.extension = ' . $db->quote($extension)); } // Filter on the level. if ($level = $this->getState('filter.level')) { $query->where('a.level <= ' . (int) $level); } // Filter by access level. if ($access = $this->getState('filter.access')) { $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 $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif ($published === '') { $query->where('(a.published 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 . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } // Filter by a single tag. $tagId = $this->getState('filter.tag'); if (is_numeric($tagId)) { $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) ->join( 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote($extension . '.category') ); } // Add the list ordering clause $listOrdering = $this->getState('list.ordering', 'a.lft'); $listDirn = $db->escape($this->getState('list.direction', 'ASC')); if ($listOrdering == 'a.access') { $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); } else { $query->order($db->escape($listOrdering) . ' ' . $listDirn); } // Group by on Categories for JOIN with component tables to count items $query->group('a.id, a.title, a.alias, a.note, a.published, a.access, a.checked_out, a.checked_out_time, a.created_user_id, a.path, a.parent_id, a.level, a.lft, a.rgt, a.language, l.title, l.image, uc.name, ag.title, ua.name' ); return $query; } /** * Method to determine if an association exists * * @return boolean True if the association exists * * @since 3.0 */ public function getAssoc() { if (!is_null($this->hasAssociation)) { return $this->hasAssociation; } $extension = $this->getState('filter.extension'); $this->hasAssociation = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); if (!$this->hasAssociation || !$component || !$cname) { $this->hasAssociation = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); $this->hasAssociation = class_exists($hname) && !empty($hname::$category_association); } return $this->hasAssociation; } /** * Method to get an array of data items. * * @return mixed An array of data items on success, false on failure. * * @since 3.0.1 */ public function getItems() { $items = parent::getItems(); if ($items != false) { $extension = $this->getState('filter.extension'); $this->countItems($items, $extension); } return $items; } /** * Method to load the countItems method from the extensions * * @param stdClass[] $items The category items * @param string $extension The category extension * * @return void * * @since 3.5 */ public function countItems(&$items, $extension) { $parts = explode('.', $extension, 2); $component = $parts[0]; $section = null; if (count($parts) > 1) { $section = $parts[1]; } // 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)) { $prefix = ucfirst($eName); $cName = $prefix . 'Helper'; JLoader::register($cName, $file); if (class_exists($cName) && is_callable(array($cName, 'countItems'))) { $cName::countItems($items, $section); } } } } models/fields/modal/category.php 0000604 00000023564 15245557240 0012736 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2013 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\CMS\Language\LanguageHelper; /** * Supports a modal category picker. * * @since 3.1 */ class JFormFieldModal_Category extends JFormField { /** * The form field type. * * @var string * @since 1.6 */ protected $type = 'Modal_Category'; /** * Method to get the field input markup. * * @return string The field input markup. * * @since 1.6 */ protected function getInput() { if ($this->element['extension']) { $extension = (string) $this->element['extension']; } else { $extension = (string) JFactory::getApplication()->input->get('extension', 'com_content'); } $allowNew = ((string) $this->element['new'] == 'true'); $allowEdit = ((string) $this->element['edit'] == 'true'); $allowClear = ((string) $this->element['clear'] != 'false'); $allowSelect = ((string) $this->element['select'] != 'false'); $allowPropagate = ((string) $this->element['propagate'] == 'true'); $languages = LanguageHelper::getContentLanguages(array(0, 1)); // Load language. JFactory::getLanguage()->load('com_categories', JPATH_ADMINISTRATOR); // The active category id field. $value = (int) $this->value > 0 ? (int) $this->value : ''; // Create the modal id. $modalId = 'Category_' . $this->id; // Add the modal field script to the document head. JHtml::_('jquery.framework'); JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); // Script to proxy the select modal function to the modal-fields.js file. if ($allowSelect) { static $scriptSelect = null; if (is_null($scriptSelect)) { $scriptSelect = array(); } if (!isset($scriptSelect[$this->id])) { JFactory::getDocument()->addScriptDeclaration(" function jSelectCategory_" . $this->id . "(id, title, object) { window.processModalSelect('Category', '" . $this->id . "', id, title, '', object); } "); JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); $scriptSelect[$this->id] = true; } } // Setup variables for display. $linkCategories = 'index.php?option=com_categories&view=categories&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1' . '&extension=' . $extension; $linkCategory = 'index.php?option=com_categories&view=category&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1' . '&extension=' . $extension; $modalTitle = JText::_('COM_CATEGORIES_CHANGE_CATEGORY'); if (isset($this->element['language'])) { $linkCategories .= '&forcedLanguage=' . $this->element['language']; $linkCategory .= '&forcedLanguage=' . $this->element['language']; $modalTitle .= ' — ' . $this->element['label']; } $urlSelect = $linkCategories . '&function=jSelectCategory_' . $this->id; $urlEdit = $linkCategory . '&task=category.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; $urlNew = $linkCategory . '&task=category.add'; if ($value) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('title')) ->from($db->quoteName('#__categories')) ->where($db->quoteName('id') . ' = ' . (int) $value); $db->setQuery($query); try { $title = $db->loadResult(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } } $title = empty($title) ? JText::_('COM_CATEGORIES_SELECT_A_CATEGORY') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); // The current category display field. $html = '<span class="input-append">'; $html .= '<input class="input-medium" id="' . $this->id . '_name" type="text" value="' . $title . '" disabled="disabled" size="35" />'; // Select category button. if ($allowSelect) { $html .= '<button' . ' type="button"' . ' class="btn hasTooltip' . ($value ? ' hidden' : '') . '"' . ' id="' . $this->id . '_select"' . ' data-toggle="modal"' . ' data-target="#ModalSelect' . $modalId . '"' . ' title="' . JHtml::tooltipText('COM_CATEGORIES_CHANGE_CATEGORY') . '">' . '<span class="icon-file" aria-hidden="true"></span> ' . JText::_('JSELECT') . '</button>'; } // New category button. if ($allowNew) { $html .= '<button' . ' type="button"' . ' class="btn hasTooltip' . ($value ? ' hidden' : '') . '"' . ' id="' . $this->id . '_new"' . ' data-toggle="modal"' . ' data-target="#ModalNew' . $modalId . '"' . ' title="' . JHtml::tooltipText('COM_CATEGORIES_NEW_CATEGORY') . '">' . '<span class="icon-new" aria-hidden="true"></span> ' . JText::_('JACTION_CREATE') . '</button>'; } // Edit category button. if ($allowEdit) { $html .= '<button' . ' type="button"' . ' class="btn hasTooltip' . ($value ? '' : ' hidden') . '"' . ' id="' . $this->id . '_edit"' . ' data-toggle="modal"' . ' data-target="#ModalEdit' . $modalId . '"' . ' title="' . JHtml::tooltipText('COM_CATEGORIES_EDIT_CATEGORY') . '">' . '<span class="icon-edit" aria-hidden="true"></span> ' . JText::_('JACTION_EDIT') . '</button>'; } // Clear category button. if ($allowClear) { $html .= '<button' . ' type="button"' . ' class="btn' . ($value ? '' : ' hidden') . '"' . ' id="' . $this->id . '_clear"' . ' onclick="window.processModalParent(\'' . $this->id . '\'); return false;">' . '<span class="icon-remove" aria-hidden="true"></span>' . JText::_('JCLEAR') . '</button>'; } // Propagate category button if ($allowPropagate && count($languages) > 2) { // Strip off language tag at the end $tagLength = (int) strlen($this->element['language']); $callbackFunctionStem = substr("jSelectCategory_" . $this->id, 0, -$tagLength); $html .= '<a' . ' class="btn hasTooltip' . ($value ? '' : ' hidden') . '"' . ' id="' . $this->id . '_propagate"' . ' href="#"' . ' title="' . JHtml::tooltipText('JGLOBAL_ASSOCIATIONS_PROPAGATE_TIP') . '"' . ' onclick="Joomla.propagateAssociation(\'' . $this->id . '\', \'' . $callbackFunctionStem . '\');">' . '<span class="icon-refresh" aria-hidden="true"></span>' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') . '</a>'; } $html .= '</span>'; // Select category modal. if ($allowSelect) { $html .= JHtml::_( 'bootstrap.renderModal', 'ModalSelect' . $modalId, array( 'title' => $modalTitle, 'url' => $urlSelect, 'height' => '400px', 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', 'footer' => '<button type="button" class="btn" data-dismiss="modal">' . JText::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>', ) ); } // New category modal. if ($allowNew) { $html .= JHtml::_( 'bootstrap.renderModal', 'ModalNew' . $modalId, array( 'title' => JText::_('COM_CATEGORIES_NEW_CATEGORY'), 'backdrop' => 'static', 'keyboard' => false, 'closeButton' => false, 'url' => $urlNew, 'height' => '400px', 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', 'footer' => '<button type="button" class="btn"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'add\', \'category\', \'cancel\', \'item-form\'); return false;">' . JText::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>' . '<button type="button" class="btn btn-primary"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'add\', \'category\', \'save\', \'item-form\'); return false;">' . JText::_('JSAVE') . '</button>' . '<button type="button" class="btn btn-success"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'add\', \'category\', \'apply\', \'item-form\'); return false;">' . JText::_('JAPPLY') . '</button>', ) ); } // Edit category modal. if ($allowEdit) { $html .= JHtml::_( 'bootstrap.renderModal', 'ModalEdit' . $modalId, array( 'title' => JText::_('COM_CATEGORIES_EDIT_CATEGORY'), 'backdrop' => 'static', 'keyboard' => false, 'closeButton' => false, 'url' => $urlEdit, 'height' => '400px', 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', 'footer' => '<button type="button" class="btn"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'edit\', \'category\', \'cancel\', \'item-form\'); return false;">' . JText::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</button>' . '<button type="button" class="btn btn-primary"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'edit\', \'category\', \'save\', \'item-form\'); return false;">' . JText::_('JSAVE') . '</button>' . '<button type="button" class="btn btn-success"' . ' onclick="window.processModalEdit(this, \'' . $this->id . '\', \'edit\', \'category\', \'apply\', \'item-form\'); return false;">' . JText::_('JAPPLY') . '</button>', ) ); } // Note: class='required' for client side validation $class = $this->required ? ' class="required modal-value"' : ''; $html .= '<input type="hidden" id="' . $this->id . '_id"' . $class . ' data-required="' . (int) $this->required . '" name="' . $this->name . '" data-text="' . htmlspecialchars(JText::_('COM_CATEGORIES_SELECT_A_CATEGORY', true), ENT_COMPAT, 'UTF-8') . '" value="' . $value . '" />'; return $html; } /** * Method to get the field label markup. * * @return string The field label markup. * * @since 3.7.0 */ protected function getLabel() { return str_replace($this->id, $this->id . '_id', parent::getLabel()); } } models/fields/categoryparent.php 0000604 00000012155 15245557240 0013046 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 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'); /** * Category Parent field. * * @since 1.6 * @deprecated 4.0 Use categoryedit instead. */ class JFormFieldCategoryParent extends JFormFieldList { /** * The form field type. * * @var string * @since 1.6 */ protected $type = 'CategoryParent'; /** * Method to get the field options. * * @return array The field option objects. * * @since 1.6 */ protected function getOptions() { // Initialise variables. $options = array(); $name = (string) $this->element['name']; // Let's get the id for the current item, either category or content item. $jinput = JFactory::getApplication()->input; // For categories the old category is the category id 0 for new category. if ($this->element['parent']) { $oldCat = $jinput->get('id', 0); } else // For items the old category is the category they are in when opened or 0 if new. { $oldCat = $this->form->getValue($name); } $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, a.level') ->from('#__categories AS a') ->join('LEFT', $db->quoteName('#__categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); // Filter by the type if ($extension = $this->form->getValue('extension')) { $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); } if ($this->element['parent']) { // Prevent parenting to children of this item. if ($id = $this->form->getValue('id')) { $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $id) ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); $rowQuery = $db->getQuery(true); $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') ->from('#__categories AS a') ->where('a.id = ' . (int) $id); $db->setQuery($rowQuery); $row = $db->loadObject(); } } $query->where('a.published IN (0,1)') ->group('a.id, a.title, a.level, a.lft, a.rgt, a.extension, a.parent_id') ->order('a.lft ASC'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { // Translate ROOT if ($options[$i]->level == 0) { $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); } // Displays language code if not set to All $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('language')) ->where($db->quoteName('id') . '=' . (int) $options[$i]->value) ->from($db->quoteName('#__categories')); $db->setQuery($query); $language = $db->loadResult(); $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; if ($language !== '*') { $options[$i]->text = $options[$i]->text . ' (' . $language . ')'; } } // Get the current user object. $user = JFactory::getUser(); // For new items we want a list of categories you are allowed to create in. if ($oldCat == 0) { foreach ($options as $i => $option) { /* * To take save or create in a category you need to have create rights for that category unless the item is already in that category. * Unset the option if the user isn't authorised for it. In this field assets are always categories. */ if ($user->authorise('core.create', $extension . '.category.' . $option->value) != true) { unset($options[$i]); } } } // If you have an existing category id things are more complex. else { foreach ($options as $i => $option) { /* * If you are only allowed to edit in this category but not edit.state, you should not get any * option to change the category parent for a category or the category for a content item, * but you should be able to save in that category. */ if ($user->authorise('core.edit.state', $extension . '.category.' . $oldCat) != true) { if ($option->value != $oldCat) { echo 'y'; unset($options[$i]); } } /* * However, if you can edit.state you can also move this to another category for which you have * create permission and you should also still be able to save in the current category. */ elseif (($user->authorise('core.create', $extension . '.category.' . $option->value) != true) && $option->value != $oldCat ) { echo 'x'; unset($options[$i]); } } } if (isset($row) && !isset($options[0])) { if ($row->parent_id == '1') { $parent = new stdClass; $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); array_unshift($options, $parent); } } // Merge any additional options in the XML definition. return array_merge(parent::getOptions(), $options); } } models/fields/categoryedit.php 0000604 00000031524 15245557240 0012503 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2012 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'); /** * Category Edit field.. * * @since 1.6 */ class JFormFieldCategoryEdit extends JFormFieldList { /** * To allow creation of new categories. * * @var integer * @since 3.6 */ protected $allowAdd; /** * Optional prefix for new categories. * * @var string * @since 3.9.11 */ protected $customPrefix; /** * A flexible category list that respects access controls * * @var string * @since 1.6 */ public $type = 'CategoryEdit'; /** * Method to attach a JForm object to the field. * * @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see JFormField::setup() * @since 3.2 */ public function setup(SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { $this->allowAdd = isset($this->element['allowAdd']) ? $this->element['allowAdd'] : ''; $this->customPrefix = (string) $this->element['customPrefix']; } return $return; } /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.6 */ public function __get($name) { switch ($name) { case 'allowAdd': case 'customPrefix': return $this->$name; } return parent::__get($name); } /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.6 */ public function __set($name, $value) { $value = (string) $value; switch ($name) { case 'allowAdd': $value = (string) $value; $this->$name = ($value === 'true' || $value === $name || $value === '1'); break; case 'customPrefix': $this->$name = (string) $value; break; default: parent::__set($name, $value); } } /** * Method to get a list of categories that respects access controls and can be used for * either category assignment or parent category assignment in edit screens. * Use the parent element to indicate that the field will be used for assigning parent categories. * * @return array The field option objects. * * @since 1.6 */ protected function getOptions() { $options = array(); $published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(0, 1); $name = (string) $this->element['name']; // Let's get the id for the current item, either category or content item. $jinput = JFactory::getApplication()->input; // Load the category options for a given extension. // For categories the old category is the category id or 0 for new category. if ($this->element['parent'] || $jinput->get('option') == 'com_categories') { $oldCat = $jinput->get('id', 0); $oldParent = $this->form->getValue($name, 0); $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('extension', 'com_content'); } else // For items the old category is the category they are in when opened or 0 if new. { $oldCat = $this->form->getValue($name, 0); $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('option', 'com_content'); } // Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category $oldCat = is_array($oldCat) ? (int) reset($oldCat) : (int) $oldCat; $db = JFactory::getDbo(); $user = JFactory::getUser(); $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, a.level, a.published, a.lft, a.language') ->from('#__categories AS a'); // Filter by the extension type if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') { $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); } else { $query->where('(a.extension = ' . $db->quote($extension) . ')'); } // Filter language if (!empty($this->element['language'])) { if (strpos($this->element['language'], ',') !== false) { $language = implode(',', $db->quote(explode(',', $this->element['language']))); } else { $language = $db->quote($this->element['language']); } $query->where($db->quoteName('a.language') . ' IN (' . $language . ')'); } // Filter on the published state $query->where('a.published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')'); // Filter categories on User Access Level // Filter by access level on categories. if (!$user->authorise('core.admin')) { $groups = implode(',', $user->getAuthorisedViewLevels()); $query->where('a.access IN (' . $groups . ')'); } $query->order('a.lft ASC'); // If parent isn't explicitly stated but we are in com_categories assume we want parents if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) { // Prevent parenting to children of this item. // To rearrange parents and children move the children up, not the parents down. $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $oldCat) ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); $rowQuery = $db->getQuery(true); $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') ->from('#__categories AS a') ->where('a.id = ' . (int) $oldCat); $db->setQuery($rowQuery); $row = $db->loadObject(); } // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { // Translate ROOT if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') { if ($options[$i]->level == 0) { $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); } } if ($options[$i]->published == 1) { $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . $options[$i]->text; } else { $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . '[' . $options[$i]->text . ']'; } // Displays language code if not set to All if ($options[$i]->language !== '*') { $options[$i]->text = $options[$i]->text . ' (' . $options[$i]->language . ')'; } } // For new items we want a list of categories you are allowed to create in. if ($oldCat == 0) { foreach ($options as $i => $option) { /* * To take save or create in a category you need to have create rights for that category unless the item is already in that category. * Unset the option if the user isn't authorised for it. In this field assets are always categories. */ if ($option->level != 0 && !$user->authorise('core.create', $extension . '.category.' . $option->value)) { unset($options[$i]); } } } // If you have an existing category id things are more complex. else { /* * If you are only allowed to edit in this category but not edit.state, you should not get any * option to change the category parent for a category or the category for a content item, * but you should be able to save in that category. */ foreach ($options as $i => $option) { $assetKey = $extension . '.category.' . $oldCat; if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.edit.state', $assetKey)) { unset($options[$i]); continue; } if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) { unset($options[$i]); continue; } /* * However, if you can edit.state you can also move this to another category for which you have * create permission and you should also still be able to save in the current category. */ $assetKey = $extension . '.category.' . $option->value; if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.create', $assetKey)) { unset($options[$i]); continue; } if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) { unset($options[$i]); continue; } } } if (($this->element['parent'] == true || $jinput->get('option') == 'com_categories') && (isset($row) && !isset($options[0])) && isset($this->element['show_root'])) { if ($row->parent_id == '1') { $parent = new stdClass; $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); array_unshift($options, $parent); } array_unshift($options, JHtml::_('select.option', '0', JText::_('JGLOBAL_ROOT'))); } // Merge any additional options in the XML definition. return array_merge(parent::getOptions(), $options); } /** * 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.6 */ protected function getInput() { $html = array(); $class = array(); $attr = ''; // Initialize some field attributes. $class[] = !empty($this->class) ? $this->class : ''; if ($this->allowAdd) { $customGroupText = JText::_('JGLOBAL_CUSTOM_CATEGORY'); $class[] = 'chzn-custom-value'; $attr .= ' data-custom_group_text="' . $customGroupText . '" ' . 'data-no_results_text="' . JText::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' . 'data-placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; if ($this->customPrefix !== '') { $attr .= 'data-custom_value_prefix="' . $this->customPrefix . '" '; } } if ($class) { $attr .= 'class="' . implode(' ', $class) . '"'; } $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; $attr .= $this->multiple ? ' multiple' : ''; $attr .= $this->required ? ' required aria-required="true"' : ''; $attr .= $this->autofocus ? ' autofocus' : ''; // To avoid user's confusion, readonly="true" should imply disabled="true". if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1' || (string) $this->disabled == 'true') { $attr .= ' disabled="disabled"'; } // Initialize JavaScript field attributes. $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; // Get the field options. $options = (array) $this->getOptions(); // Create a read-only list (no name) with hidden input(s) to store the value(s). if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') { $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); // E.g. form field type tag sends $this->value as array if ($this->multiple && is_array($this->value)) { if (!count($this->value)) { $this->value[] = ''; } foreach ($this->value as $value) { $html[] = '<input type="hidden" name="' . $this->name . '" value="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"/>'; } } else { $html[] = '<input type="hidden" name="' . $this->name . '" value="' . htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . '"/>'; } } else { // Create a regular list. if (count($options) === 0) { // All Categories have been deleted, so we need a new category (This will create on save if selected). $options[0] = new stdClass; $options[0]->value = 'Uncategorised'; $options[0]->text = 'Uncategorised'; $options[0]->level = '1'; $options[0]->published = '1'; $options[0]->lft = '1'; } $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); } return implode($html); } } models/forms/category.xml 0000604 00000012522 15245557240 0011523 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <form> <field name="id" type="number" label="JGLOBAL_FIELD_ID_LABEL" description="JGLOBAL_FIELD_ID_DESC" default="0" class="readonly" readonly="true" /> <field name="hits" type="number" label="JGLOBAL_HITS" description="COM_CATEGORIES_FIELD_HITS_DESC" default="0" class="readonly" readonly="true" filter="unset" /> <field name="asset_id" type="hidden" filter="unset" label="JFIELD_ASSET_ID_LABEL" description="JFIELD_ASSET_ID_DESC" /> <field name="parent_id" type="categoryedit" label="COM_CATEGORIES_FIELD_PARENT_LABEL" description="COM_CATEGORIES_FIELD_PARENT_DESC" /> <field name="lft" type="hidden" filter="unset" /> <field name="rgt" type="hidden" filter="unset" /> <field name="level" type="hidden" filter="unset" /> <field name="path" type="text" label="COM_CATEGORIES_PATH_LABEL" description="COM_CATEGORIES_PATH_DESC" class="readonly" size="40" readonly="true" /> <field name="extension" type="hidden" /> <field name="title" type="text" label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC" class="input-xxlarge input-large-text" size="40" required="true" /> <field name="alias" type="text" label="JFIELD_ALIAS_LABEL" description="JFIELD_ALIAS_DESC" size="45" hint="JFIELD_ALIAS_PLACEHOLDER" /> <field name="version_note" type="text" label="JGLOBAL_FIELD_VERSION_NOTE_LABEL" description="JGLOBAL_FIELD_VERSION_NOTE_DESC" class="span12" size="45" maxlength="255" /> <field name="note" type="text" label="COM_CATEGORIES_FIELD_NOTE_LABEL" description="COM_CATEGORIES_FIELD_NOTE_DESC" class="span12" size="40" maxlength="255" /> <field name="description" type="editor" label="JGLOBAL_DESCRIPTION" description="COM_CATEGORIES_DESCRIPTION_DESC" filter="JComponentHelper::filterText" buttons="true" hide="readmore,pagebreak" /> <field name="published" type="list" label="JSTATUS" description="JFIELD_PUBLISHED_DESC" default="1" class="chzn-color-state" 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="access" type="accesslevel" label="JFIELD_ACCESS_LABEL" description="JFIELD_ACCESS_DESC" /> <field name="metadesc" type="textarea" label="JFIELD_META_DESCRIPTION_LABEL" description="JFIELD_META_DESCRIPTION_DESC" rows="3" cols="40" /> <field name="metakey" type="textarea" label="JFIELD_META_KEYWORDS_LABEL" description="JFIELD_META_KEYWORDS_DESC" rows="3" cols="40" /> <field name="created_user_id" type="user" label="JGLOBAL_FIELD_CREATED_BY_LABEL" desc="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_user_id" 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_CATEGORIES_FIELD_LANGUAGE_DESC" > <option value="*">JALL</option> </field> <field name="tags" type="tag" label="JTAG" description="JTAG_DESC" class="span12" multiple="true" /> <field name="rules" type="rules" label="JFIELD_RULES_LABEL" id="rules" translate_label="false" filter="rules" validate="rules" component="com_content" section="category" /> <fields name="params" label="COM_CATEGORIES_FIELD_BASIC_LABEL"> <fieldset name="basic"> <field name="category_layout" type="componentlayout" label="JFIELD_ALT_LAYOUT_LABEL" description="JFIELD_ALT_COMPONENT_LAYOUT_DESC" view="category" useglobal="true" /> <field name="image" type="media" label="COM_CATEGORIES_FIELD_IMAGE_LABEL" description="COM_CATEGORIES_FIELD_IMAGE_DESC" /> <field name="image_alt" type="text" label="COM_CATEGORIES_FIELD_IMAGE_ALT_LABEL" description="COM_CATEGORIES_FIELD_IMAGE_ALT_DESC" size="20" /> </fieldset> </fields> <fields name="metadata" label="JGLOBAL_FIELDSET_METADATA_OPTIONS"> <fieldset name="jmetadata" label="JGLOBAL_FIELDSET_METADATA_OPTIONS"> <field name="author" type="text" label="JAUTHOR" description="JFIELD_METADATA_AUTHOR_DESC" size="30" /> <field name="robots" type="list" label="JFIELD_METADATA_ROBOTS_LABEL" description="JFIELD_METADATA_ROBOTS_DESC" > <option value="">JGLOBAL_USE_GLOBAL</option> <option value="index, follow"></option> <option value="noindex, follow"></option> <option value="index, nofollow"></option> <option value="noindex, nofollow"></option> </field> </fieldset> </fields> </form> models/forms/filter_categories.xml 0000604 00000005663 15245557240 0013410 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <form> <fields name="filter"> <field name="search" type="text" inputmode="search" label="COM_CATEGORIES_FILTER_SEARCH_LABEL" description="COM_CATEGORIES_FILTER_SEARCH_DESC" hint="JSEARCH_FILTER" /> <field name="published" type="status" label="COM_CATEGORIES_FILTER_PUBLISHED" description="COM_CATEGORIES_FILTER_PUBLISHED_DESC" onchange="this.form.submit();" > <option value="">JOPTION_SELECT_PUBLISHED</option> </field> <field name="access" type="accesslevel" label="JOPTION_FILTER_ACCESS" description="JOPTION_FILTER_ACCESS_DESC" onchange="this.form.submit();" > <option value="">JOPTION_SELECT_ACCESS</option> </field> <field name="language" type="contentlanguage" label="JOPTION_FILTER_LANGUAGE" description="JOPTION_FILTER_LANGUAGE_DESC" onchange="this.form.submit();" > <option value="">JOPTION_SELECT_LANGUAGE</option> <option value="*">JALL</option> </field> <field name="tag" type="tag" label="JOPTION_FILTER_TAG" description="JOPTION_FILTER_TAG_DESC" mode="nested" onchange="this.form.submit();" > <option value="">JOPTION_SELECT_TAG</option> </field> <field name="level" type="integer" label="JOPTION_FILTER_LEVEL" description="JOPTION_FILTER_LEVEL_DESC" first="1" last="10" step="1" languages="*" onchange="this.form.submit();" > <option value="">JOPTION_SELECT_MAX_LEVELS</option> </field> </fields> <fields name="list"> <field name="fullordering" type="list" label="JGLOBAL_SORT_BY" description="JGLOBAL_SORT_BY" default="a.lft ASC" statuses="*,0,1,2,-2" onchange="this.form.submit();" validate="options" > <option value="">JGLOBAL_SORT_BY</option> <option value="a.lft ASC">JGRID_HEADING_ORDERING_ASC</option> <option value="a.lft DESC">JGRID_HEADING_ORDERING_DESC</option> <option value="a.published ASC">JSTATUS_ASC</option> <option value="a.published DESC">JSTATUS_DESC</option> <option value="a.title ASC">JGLOBAL_TITLE_ASC</option> <option value="a.title DESC">JGLOBAL_TITLE_DESC</option> <option value="access_level ASC">JGRID_HEADING_ACCESS_ASC</option> <option value="access_level DESC">JGRID_HEADING_ACCESS_DESC</option> <option value="association ASC" requires="associations">JASSOCIATIONS_ASC</option> <option value="association DESC" requires="associations">JASSOCIATIONS_DESC</option> <option value="language_title ASC">JGRID_HEADING_LANGUAGE_ASC</option> <option value="language_title 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_CATEGORIES_LIST_LIMIT" description="COM_CATEGORIES_LIST_LIMIT_DESC" default="25" class="input-mini" onchange="this.form.submit();" /> </fields> </form> helpers/association.php 0000604 00000003206 15245557240 0011241 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2012 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('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); /** * Category Component Association Helper * * @since 3.0 */ abstract class CategoryHelperAssociation { public static $category_association = true; /** * Method to get the associations for a given category * * @param integer $id Id of the item * @param string $extension Name of the component * @param string $layout Category layout * * @return array Array of associations for the component categories * * @since 3.0 */ public static function getCategoryAssociations($id = 0, $extension = 'com_content', $layout = null) { $return = array(); if ($id) { // Load route helper jimport('helper.route', JPATH_COMPONENT_SITE); $helperClassname = ucfirst(substr($extension, 4)) . 'HelperRoute'; $associations = CategoriesHelper::getAssociations($id, $extension); foreach ($associations as $tag => $item) { if (class_exists($helperClassname) && is_callable(array($helperClassname, 'getCategoryRoute'))) { $return[$tag] = $helperClassname::getCategoryRoute($item, $tag, $layout); } else { $viewLayout = $layout ? '&layout=' . $layout : ''; $return[$tag] = 'index.php?option=' . $extension . '&view=category&id=' . $item . $viewLayout; } } } return $return; } } helpers/html/categoriesadministrator.php 0000604 00000004573 15245557240 0014627 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2012 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; JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); /** * Administrator category HTML * * @since 3.2 */ abstract class JHtmlCategoriesAdministrator { /** * Render the list of associated items * * @param integer $catid Category identifier to search its associations * @param string $extension Category Extension * * @return string The language HTML * * @since 3.2 * @throws Exception */ public static function association($catid, $extension = 'com_content') { // Defaults $html = ''; // Get the associations if ($associations = CategoriesHelper::getAssociations($catid, $extension)) { $associations = ArrayHelper::toInteger($associations); // Get the associated categories $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('c.id, c.title') ->select('l.sef as lang_sef') ->select('l.lang_code') ->from('#__categories as c') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') ->where('c.id != ' . $catid) ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); $db->setQuery($query); try { $items = $db->loadObjectList('id'); } catch (RuntimeException $e) { throw new Exception($e->getMessage(), 500, $e); } if ($items) { foreach ($items as &$item) { $text = $item->lang_sef ? strtoupper($item->lang_sef) : 'XX'; $url = JRoute::_('index.php?option=com_categories&task=category.edit&id=' . (int) $item->id . '&extension=' . $extension); $classes = 'hasPopover label label-association label-' . $item->lang_sef; $item->link = '<a href="' . $url . '" title="' . $item->language_title . '" class="' . $classes . '" data-content="' . htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '" data-placement="top">' . $text . '</a>'; } } JHtml::_('bootstrap.popover'); $html = JLayoutHelper::render('joomla.content.associations', $items); } return $html; } } helpers/categories.php 0000604 00000011423 15245557240 0011052 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Categories helper. * * @since 1.6 */ class CategoriesHelper { /** * Configure the Submenu links. * * @param string $extension The extension being used for the categories. * * @return void * * @since 1.6 */ public static function addSubmenu($extension) { // Avoid nonsense situation. if ($extension == 'com_categories') { return; } $parts = explode('.', $extension); $component = $parts[0]; if (count($parts) > 1) { $section = $parts[1]; } // 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)) { $prefix = ucfirst(str_replace('com_', '', $component)); $cName = $prefix . 'Helper'; JLoader::register($cName, $file); if (class_exists($cName)) { if (is_callable(array($cName, 'addSubmenu'))) { $lang = JFactory::getLanguage(); // Loading language file from the administrator/language directory then // loading language file from the administrator/components/*extension*/language directory $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); call_user_func(array($cName, 'addSubmenu'), 'categories' . (isset($section) ? '.' . $section : '')); } } } } /** * Gets a list of the actions that can be performed. * * @param string $extension The extension. * @param integer $categoryId The category ID. * * @return JObject * * @since 1.6 * @deprecated 3.2 Use JHelperContent::getActions() instead */ public static function getActions($extension, $categoryId = 0) { // Log usage of deprecated function try { JLog::add( sprintf('%s() is deprecated, use JHelperContent::getActions() with new arguments order instead.', __METHOD__), JLog::WARNING, 'deprecated' ); } catch (RuntimeException $exception) { // Informational log only } // Get list of actions return JHelperContent::getActions($extension, 'category', $categoryId); } /** * Gets a list of associations for a given item. * * @param integer $pk Content item key. * @param string $extension Optional extension name. * * @return array of associations. */ public static function getAssociations($pk, $extension = 'com_content') { $langAssociations = JLanguageAssociations::getAssociations($extension, '#__categories', 'com_categories.item', $pk, 'id', 'alias', ''); $associations = array(); $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); foreach ($langAssociations as $langAssociation) { // Include only published categories with user access $arrId = explode(':', $langAssociation->id); $assocId = $arrId[0]; $db = \JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->qn('published')) ->from($db->qn('#__categories')) ->where('access IN (' . $groups . ')') ->where($db->qn('id') . ' = ' . (int) $assocId); $result = (int) $db->setQuery($query)->loadResult(); if ($result === 1) { $associations[$langAssociation->language] = $langAssociation->id; } } return $associations; } /** * Check if Category ID exists otherwise assign to ROOT category. * * @param mixed $catid Name or ID of category. * @param string $extension Extension that triggers this function * * @return integer $catid Category ID. */ public static function validateCategoryId($catid, $extension) { JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); $categoryTable = JTable::getInstance('Category'); $data = array(); $data['id'] = $catid; $data['extension'] = $extension; if (!$categoryTable->load($data)) { $catid = 0; } return (int) $catid; } /** * Create new Category from within item view. * * @param array $data Array of data for new category. * * @return integer */ public static function createCategory($data) { JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/models'); JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); $categoryModel = JModelLegacy::getInstance('Category', 'CategoriesModel', array('ignore_request' => true)); $categoryModel->save($data); $catid = $categoryModel->getState('category.id'); return $catid; } } tables/category.php 0000604 00000001426 15245557240 0010354 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Category table * * @since 1.6 */ class CategoriesTableCategory extends JTableCategory { /** * Method to delete a node and, optionally, its child nodes from the table. * * @param integer $pk The primary key of the node to delete. * @param boolean $children True to delete child nodes, false to move them up a level. * * @return boolean True on success. * * @since 2.5 */ public function delete($pk = null, $children = false) { return parent::delete($pk, $children); } } categories.php 0000604 00000001647 15245557240 0007417 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2005 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::_('behavior.tabstate'); $input = JFactory::getApplication()->input; // If you have a URL like this: com_categories&view=categories&extension=com_example.example_cat $parts = explode('.', $input->get('extension')); $component = $parts[0]; if (!JFactory::getUser()->authorise('core.manage', $component)) { throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); } JLoader::register('JHtmlCategoriesAdministrator', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/html/categoriesadministrator.php'); $controller = JControllerLegacy::getInstance('Categories'); $controller->execute($input->get('task')); $controller->redirect(); categories.xml 0000604 00000001771 15245557240 0007426 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <extension type="component" version="3.1" method="upgrade"> <name>com_categories</name> <author>Joomla! Project</author> <creationDate>December 2007</creationDate> <copyright>(C) 2007 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.0.0</version> <description>COM_CATEGORIES_XML_DESCRIPTION</description> <administration> <files folder="admin"> <filename>categories.php</filename> <filename>config.xml</filename> <filename>controller.php</filename> <folder>controllers</folder> <folder>helpers</folder> <folder>models</folder> <folder>views</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB.com_categories.ini</language> <language tag="en-GB">language/en-GB.com_categories.sys.ini</language> </languages> </administration> </extension> controller.php 0000604 00000005453 15245557240 0007454 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_categories * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Categories view class for the Category package. * * @since 1.6 */ class CategoriesController extends JControllerLegacy { /** * The extension for which the categories apply. * * @var string * @since 1.6 */ protected $extension; /** * Constructor. * * @param array $config An optional associative array of configuration settings. * * @see JControllerLegacy * @since 1.6 */ public function __construct($config = array()) { parent::__construct($config); // Guess the JText message prefix. Defaults to the option. if (empty($this->extension)) { $this->extension = $this->input->get('extension', 'com_content'); } } /** * Method to display a view. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return CategoriesController This object to support chaining. * * @since 1.5 */ public function display($cachable = false, $urlparams = array()) { // Get the document object. $document = JFactory::getDocument(); // Set the default view name and format from the Request. $vName = $this->input->get('view', 'categories'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); $id = $this->input->getInt('id'); // Check for edit form. if ($vName == 'category' && $lName == 'edit' && !$this->checkEditId('com_categories.edit.category', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $this->extension, false)); return false; } // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { // Get the model for the view. $model = $this->getModel($vName, 'CategoriesModel', array('name' => $vName . '.' . substr($this->extension, 4))); // Push the model into the view (as default). $view->setModel($model, true); $view->setLayout($lName); // Push document object into the view. $view->document = $document; // Load the submenu. JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); CategoriesHelper::addSubmenu($model->getState('filter.extension')); $view->display(); } return $this; } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка