[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_categories/src/Field/ -> CategoryeditField.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_categories
   6   *
   7   * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Categories\Administrator\Field;
  12  
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Form\Field\ListField;
  15  use Joomla\CMS\HTML\HTMLHelper;
  16  use Joomla\CMS\Language\Text;
  17  use Joomla\Database\ParameterType;
  18  use Joomla\Utilities\ArrayHelper;
  19  
  20  // phpcs:disable PSR1.Files.SideEffects
  21  \defined('_JEXEC') or die;
  22  // phpcs:enable PSR1.Files.SideEffects
  23  
  24  /**
  25   * Category Edit field..
  26   *
  27   * @since  1.6
  28   */
  29  class CategoryeditField extends ListField
  30  {
  31      /**
  32       * To allow creation of new categories.
  33       *
  34       * @var    integer
  35       * @since  3.6
  36       */
  37      protected $allowAdd;
  38  
  39      /**
  40       * Optional prefix for new categories.
  41       *
  42       * @var    string
  43       * @since  3.9.11
  44       */
  45      protected $customPrefix;
  46  
  47      /**
  48       * A flexible category list that respects access controls
  49       *
  50       * @var    string
  51       * @since  1.6
  52       */
  53      public $type = 'CategoryEdit';
  54  
  55      /**
  56       * Name of the layout being used to render the field
  57       *
  58       * @var    string
  59       * @since  4.0.0
  60       */
  61      protected $layout = 'joomla.form.field.categoryedit';
  62  
  63      /**
  64       * Method to attach a JForm object to the field.
  65       *
  66       * @param   \SimpleXMLElement  $element  The SimpleXMLElement object representing the <field /> tag for the form field object.
  67       * @param   mixed              $value    The form field value to validate.
  68       * @param   string|null        $group    The field name group control value. This acts as an array container for the field.
  69       *                                       For example if the field has name="foo" and the group value is set to "bar" then the
  70       *                                       full field name would end up being "bar[foo]".
  71       *
  72       * @return  boolean  True on success.
  73       *
  74       * @see     FormField::setup()
  75       * @since   3.2
  76       */
  77      public function setup(\SimpleXMLElement $element, $value, $group = null)
  78      {
  79          $return = parent::setup($element, $value, $group);
  80  
  81          if ($return) {
  82              $this->allowAdd = isset($this->element['allowAdd']) ? (bool) $this->element['allowAdd'] : false;
  83              $this->customPrefix = (string) $this->element['customPrefix'];
  84          }
  85  
  86          return $return;
  87      }
  88  
  89      /**
  90       * Method to get certain otherwise inaccessible properties from the form field object.
  91       *
  92       * @param   string  $name  The property name for which to get the value.
  93       *
  94       * @return  mixed  The property value or null.
  95       *
  96       * @since   3.6
  97       */
  98      public function __get($name)
  99      {
 100          switch ($name) {
 101              case 'allowAdd':
 102                  return (bool) $this->$name;
 103              case 'customPrefix':
 104                  return $this->$name;
 105          }
 106  
 107          return parent::__get($name);
 108      }
 109  
 110      /**
 111       * Method to set certain otherwise inaccessible properties of the form field object.
 112       *
 113       * @param   string  $name   The property name for which to set the value.
 114       * @param   mixed   $value  The value of the property.
 115       *
 116       * @return  void
 117       *
 118       * @since   3.6
 119       */
 120      public function __set($name, $value)
 121      {
 122          $value = (string) $value;
 123  
 124          switch ($name) {
 125              case 'allowAdd':
 126                  $value = (string) $value;
 127                  $this->$name = ($value === 'true' || $value === $name || $value === '1');
 128                  break;
 129              case 'customPrefix':
 130                  $this->$name = (string) $value;
 131                  break;
 132              default:
 133                  parent::__set($name, $value);
 134          }
 135      }
 136  
 137      /**
 138       * Method to get a list of categories that respects access controls and can be used for
 139       * either category assignment or parent category assignment in edit screens.
 140       * Use the parent element to indicate that the field will be used for assigning parent categories.
 141       *
 142       * @return  array  The field option objects.
 143       *
 144       * @since   1.6
 145       */
 146      protected function getOptions()
 147      {
 148          $options = array();
 149          $published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(0, 1);
 150          $name = (string) $this->element['name'];
 151  
 152          // Let's get the id for the current item, either category or content item.
 153          $jinput = Factory::getApplication()->input;
 154  
 155          // Load the category options for a given extension.
 156  
 157          // For categories the old category is the category id or 0 for new category.
 158          if ($this->element['parent'] || $jinput->get('option') == 'com_categories') {
 159              $oldCat = $jinput->get('id', 0);
 160              $oldParent = $this->form->getValue($name, 0);
 161              $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('extension', 'com_content');
 162          } else // For items the old category is the category they are in when opened or 0 if new.
 163          {
 164              $oldCat = $this->form->getValue($name, 0);
 165              $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('option', 'com_content');
 166          }
 167  
 168          // Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category
 169          $oldCat = \is_array($oldCat)
 170              ? (int) reset($oldCat)
 171              : (int) $oldCat;
 172  
 173          $db   = $this->getDatabase();
 174          $user = Factory::getUser();
 175  
 176          $query = $db->getQuery(true)
 177              ->select(
 178                  [
 179                      $db->quoteName('a.id', 'value'),
 180                      $db->quoteName('a.title', 'text'),
 181                      $db->quoteName('a.level'),
 182                      $db->quoteName('a.published'),
 183                      $db->quoteName('a.lft'),
 184                      $db->quoteName('a.language'),
 185                  ]
 186              )
 187              ->from($db->quoteName('#__categories', 'a'));
 188  
 189          // Filter by the extension type
 190          if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') {
 191              $query->where('(' . $db->quoteName('a.extension') . ' = :extension OR ' . $db->quoteName('a.parent_id') . ' = 0)')
 192                  ->bind(':extension', $extension);
 193          } else {
 194              $query->where($db->quoteName('a.extension') . ' = :extension')
 195                  ->bind(':extension', $extension);
 196          }
 197  
 198          // Filter language
 199          if (!empty($this->element['language'])) {
 200              if (strpos($this->element['language'], ',') !== false) {
 201                  $language = explode(',', $this->element['language']);
 202              } else {
 203                  $language = $this->element['language'];
 204              }
 205  
 206              $query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
 207          }
 208  
 209          // Filter on the published state
 210          $state = ArrayHelper::toInteger($published);
 211          $query->whereIn($db->quoteName('a.published'), $state);
 212  
 213          // Filter categories on User Access Level
 214          // Filter by access level on categories.
 215          if (!$user->authorise('core.admin')) {
 216              $groups = $user->getAuthorisedViewLevels();
 217              $query->whereIn($db->quoteName('a.access'), $groups);
 218          }
 219  
 220          $query->order($db->quoteName('a.lft') . ' ASC');
 221  
 222          // If parent isn't explicitly stated but we are in com_categories assume we want parents
 223          if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) {
 224              // Prevent parenting to children of this item.
 225              // To rearrange parents and children move the children up, not the parents down.
 226              $query->join(
 227                  'LEFT',
 228                  $db->quoteName('#__categories', 'p'),
 229                  $db->quoteName('p.id') . ' = :oldcat'
 230              )
 231                  ->bind(':oldcat', $oldCat, ParameterType::INTEGER)
 232                  ->where('NOT(' . $db->quoteName('a.lft') . ' >= ' . $db->quoteName('p.lft')
 233                      . ' AND ' . $db->quoteName('a.rgt') . ' <= ' . $db->quoteName('p.rgt') . ')');
 234          }
 235  
 236          // Get the options.
 237          $db->setQuery($query);
 238  
 239          try {
 240              $options = $db->loadObjectList();
 241          } catch (\RuntimeException $e) {
 242              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 243          }
 244  
 245          // Pad the option text with spaces using depth level as a multiplier.
 246          for ($i = 0, $n = \count($options); $i < $n; $i++) {
 247              // Translate ROOT
 248              if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') {
 249                  if ($options[$i]->level == 0) {
 250                      $options[$i]->text = Text::_('JGLOBAL_ROOT_PARENT');
 251                  }
 252              }
 253  
 254              if ($options[$i]->published == 1) {
 255                  $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . $options[$i]->text;
 256              } else {
 257                  $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . '[' . $options[$i]->text . ']';
 258              }
 259  
 260              // Displays language code if not set to All
 261              if ($options[$i]->language !== '*') {
 262                  $options[$i]->text = $options[$i]->text . ' (' . $options[$i]->language . ')';
 263              }
 264          }
 265  
 266          // For new items we want a list of categories you are allowed to create in.
 267          if ($oldCat == 0) {
 268              foreach ($options as $i => $option) {
 269                  /*
 270                   * 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.
 271                   * Unset the option if the user isn't authorised for it. In this field assets are always categories.
 272                   */
 273                  if ($option->level != 0 && !$user->authorise('core.create', $extension . '.category.' . $option->value)) {
 274                      unset($options[$i]);
 275                  }
 276              }
 277          } else {
 278              // If you have an existing category id things are more complex.
 279              /*
 280               * If you are only allowed to edit in this category but not edit.state, you should not get any
 281               * option to change the category parent for a category or the category for a content item,
 282               * but you should be able to save in that category.
 283               */
 284              foreach ($options as $i => $option) {
 285                  $assetKey = $extension . '.category.' . $oldCat;
 286  
 287                  if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.edit.state', $assetKey)) {
 288                      unset($options[$i]);
 289                      continue;
 290                  }
 291  
 292                  if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) {
 293                      unset($options[$i]);
 294                      continue;
 295                  }
 296  
 297                  /*
 298                   * However, if you can edit.state you can also move this to another category for which you have
 299                   * create permission and you should also still be able to save in the current category.
 300                   */
 301                  $assetKey = $extension . '.category.' . $option->value;
 302  
 303                  if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.create', $assetKey)) {
 304                      unset($options[$i]);
 305                      continue;
 306                  }
 307  
 308                  if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) {
 309                      unset($options[$i]);
 310                  }
 311              }
 312          }
 313  
 314          if (
 315              $oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')
 316              && !isset($options[0])
 317              && isset($this->element['show_root'])
 318          ) {
 319              $rowQuery = $db->getQuery(true)
 320                  ->select(
 321                      [
 322                          $db->quoteName('a.id', 'value'),
 323                          $db->quoteName('a.title', 'text'),
 324                          $db->quoteName('a.level'),
 325                          $db->quoteName('a.parent_id'),
 326                      ]
 327                  )
 328                  ->from($db->quoteName('#__categories', 'a'))
 329                  ->where($db->quoteName('a.id') . ' = :aid')
 330                  ->bind(':aid', $oldCat, ParameterType::INTEGER);
 331              $db->setQuery($rowQuery);
 332              $row = $db->loadObject();
 333  
 334              if ($row->parent_id == '1') {
 335                  $parent = new \stdClass();
 336                  $parent->text = Text::_('JGLOBAL_ROOT_PARENT');
 337                  array_unshift($options, $parent);
 338              }
 339  
 340              array_unshift($options, HTMLHelper::_('select.option', '0', Text::_('JGLOBAL_ROOT')));
 341          }
 342  
 343          // Merge any additional options in the XML definition.
 344          return array_merge(parent::getOptions(), $options);
 345      }
 346  
 347      /**
 348       * Method to get the field input markup for a generic list.
 349       * Use the multiple attribute to enable multiselect.
 350       *
 351       * @return  string  The field input markup.
 352       *
 353       * @since   3.6
 354       */
 355      protected function getInput()
 356      {
 357          $data = $this->getLayoutData();
 358  
 359          $data['options']        = $this->getOptions();
 360          $data['allowCustom']    = $this->allowAdd;
 361          $data['customPrefix']   = $this->customPrefix;
 362          $data['refreshPage']    = (bool) $this->element['refresh-enabled'];
 363          $data['refreshCatId']   = (string) $this->element['refresh-cat-id'];
 364          $data['refreshSection'] = (string) $this->element['refresh-section'];
 365  
 366          $renderer = $this->getRenderer($this->layout);
 367          $renderer->setComponent('com_categories');
 368          $renderer->setClient(1);
 369  
 370          return $renderer->render($data);
 371      }
 372  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer