[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Table/ -> Menu.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Table;
  11  
  12  use Joomla\CMS\Application\ApplicationHelper;
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Filesystem\Folder;
  15  use Joomla\CMS\Language\Multilanguage;
  16  use Joomla\CMS\Language\Text;
  17  use Joomla\Database\DatabaseDriver;
  18  use Joomla\Database\ParameterType;
  19  use Joomla\Registry\Registry;
  20  
  21  // phpcs:disable PSR1.Files.SideEffects
  22  \defined('JPATH_PLATFORM') or die;
  23  // phpcs:enable PSR1.Files.SideEffects
  24  
  25  /**
  26   * Menu table
  27   *
  28   * @since  1.5
  29   */
  30  class Menu extends Nested
  31  {
  32      /**
  33       * Indicates that columns fully support the NULL value in the database
  34       *
  35       * @var    boolean
  36       * @since  4.0.0
  37       */
  38      protected $_supportNullValue = true;
  39  
  40      /**
  41       * Constructor
  42       *
  43       * @param   DatabaseDriver  $db  Database driver object.
  44       *
  45       * @since   1.5
  46       */
  47      public function __construct(DatabaseDriver $db)
  48      {
  49          parent::__construct('#__menu', 'id', $db);
  50  
  51          // Set the default access level.
  52          $this->access = (int) Factory::getApplication()->get('access');
  53      }
  54  
  55      /**
  56       * Overloaded bind function
  57       *
  58       * @param   array  $array   Named array
  59       * @param   mixed  $ignore  An optional array or space separated list of properties to ignore while binding.
  60       *
  61       * @return  mixed  Null if operation was satisfactory, otherwise returns an error
  62       *
  63       * @see     Table::bind()
  64       * @since   1.5
  65       */
  66      public function bind($array, $ignore = '')
  67      {
  68          // Verify that the default home menu is not unset
  69          if ($this->home == '1' && $this->language === '*' && $array['home'] == '0') {
  70              $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT_DEFAULT'));
  71  
  72              return false;
  73          }
  74  
  75          // Verify that the default home menu set to "all" languages" is not unset
  76          if ($this->home == '1' && $this->language === '*' && $array['language'] !== '*') {
  77              $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT'));
  78  
  79              return false;
  80          }
  81  
  82          // Verify that the default home menu is not unpublished
  83          if ($this->home == '1' && $this->language === '*' && $array['published'] != '1') {
  84              $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME'));
  85  
  86              return false;
  87          }
  88  
  89          if (isset($array['params']) && \is_array($array['params'])) {
  90              $registry = new Registry($array['params']);
  91              $array['params'] = (string) $registry;
  92          }
  93  
  94          return parent::bind($array, $ignore);
  95      }
  96  
  97      /**
  98       * Overloaded check function
  99       *
 100       * @return  boolean  True on success
 101       *
 102       * @see     Table::check()
 103       * @since   1.5
 104       */
 105      public function check()
 106      {
 107          try {
 108              parent::check();
 109          } catch (\Exception $e) {
 110              $this->setError($e->getMessage());
 111  
 112              return false;
 113          }
 114  
 115          // Check for a title.
 116          if ($this->title === null || trim($this->title) === '') {
 117              $this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MENUITEM'));
 118  
 119              return false;
 120          }
 121  
 122          // Check for a path.
 123          if ($this->path === null || trim($this->path) === '') {
 124              $this->path = $this->alias;
 125          }
 126  
 127          // Check for params.
 128          if ($this->params === null || trim($this->params) === '') {
 129              $this->params = '{}';
 130          }
 131  
 132          // Check for img.
 133          if ($this->img === null || trim($this->img) === '') {
 134              $this->img = ' ';
 135          }
 136  
 137          // Cast the home property to an int for checking.
 138          $this->home = (int) $this->home;
 139  
 140          // Verify that the home item is a component.
 141          if ($this->home && $this->type !== 'component') {
 142              $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_HOME_NOT_COMPONENT'));
 143  
 144              return false;
 145          }
 146  
 147          // Set publish_up, publish_down to null if not set
 148          if (!$this->publish_up) {
 149              $this->publish_up = null;
 150          }
 151  
 152          if (!$this->publish_down) {
 153              $this->publish_down = null;
 154          }
 155  
 156          return true;
 157      }
 158  
 159      /**
 160       * Overloaded store function
 161       *
 162       * @param   boolean  $updateNulls  True to update fields even if they are null.
 163       *
 164       * @return  mixed  False on failure, positive integer on success.
 165       *
 166       * @see     Table::store()
 167       * @since   1.6
 168       */
 169      public function store($updateNulls = true)
 170      {
 171          $db = $this->getDbo();
 172  
 173          // Verify that the alias is unique
 174          $table = Table::getInstance('Menu', 'JTable', array('dbo' => $db));
 175  
 176          $originalAlias = trim($this->alias);
 177          $this->alias   = !$originalAlias ? $this->title : $originalAlias;
 178          $this->alias   = ApplicationHelper::stringURLSafe(trim($this->alias), $this->language);
 179  
 180          if ($this->parent_id == 1 && $this->client_id == 0) {
 181              // Verify that a first level menu item alias is not 'component'.
 182              if ($this->alias === 'component') {
 183                  $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_COMPONENT'));
 184  
 185                  return false;
 186              }
 187  
 188              // Verify that a first level menu item alias is not the name of a folder.
 189              if (\in_array($this->alias, Folder::folders(JPATH_ROOT))) {
 190                  $this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_FOLDER', $this->alias, $this->alias));
 191  
 192                  return false;
 193              }
 194          }
 195  
 196          // If alias still empty (for instance, new menu item with chinese characters with no unicode alias setting).
 197          if (empty($this->alias)) {
 198              $this->alias = Factory::getDate()->format('Y-m-d-H-i-s');
 199          } else {
 200              $itemSearch = array('alias' => $this->alias, 'parent_id' => $this->parent_id, 'client_id' => (int) $this->client_id);
 201              $error      = false;
 202  
 203              // Check if the alias already exists. For multilingual site.
 204              if (Multilanguage::isEnabled() && (int) $this->client_id == 0) {
 205                  // If there is a menu item at the same level with the same alias (in the All or the same language).
 206                  if (
 207                      ($table->load(array_replace($itemSearch, array('language' => '*'))) && ($table->id != $this->id || $this->id == 0))
 208                      || ($table->load(array_replace($itemSearch, array('language' => $this->language))) && ($table->id != $this->id || $this->id == 0))
 209                      || ($this->language === '*' && $this->id == 0 && $table->load($itemSearch))
 210                  ) {
 211                      $error = true;
 212                  } elseif ($this->language === '*' && $this->id != 0) {
 213                      // When editing an item with All language check if there are more menu items with the same alias in any language.
 214                      $id    = (int) $this->id;
 215                      $query = $db->getQuery(true)
 216                          ->select('id')
 217                          ->from($db->quoteName('#__menu'))
 218                          ->where($db->quoteName('parent_id') . ' = 1')
 219                          ->where($db->quoteName('client_id') . ' = 0')
 220                          ->where($db->quoteName('id') . ' != :id')
 221                          ->where($db->quoteName('alias') . ' = :alias')
 222                          ->bind(':id', $id, ParameterType::INTEGER)
 223                          ->bind(':alias', $this->alias);
 224  
 225                      $otherMenuItemId = (int) $db->setQuery($query)->loadResult();
 226  
 227                      if ($otherMenuItemId) {
 228                          $table->load(array('id' => $otherMenuItemId));
 229                          $error = true;
 230                      }
 231                  }
 232              } else {
 233                  // Check if the alias already exists. For monolingual site.
 234                  // If there is a menu item at the same level with the same alias (in any language).
 235                  if ($table->load($itemSearch) && ($table->id != $this->id || $this->id == 0)) {
 236                      $error = true;
 237                  }
 238              }
 239  
 240              // The alias already exists. Enqueue an error message.
 241              if ($error) {
 242                  $menuTypeTable = Table::getInstance('MenuType', 'JTable', array('dbo' => $db));
 243                  $menuTypeTable->load(array('menutype' => $table->menutype));
 244                  $this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS', $this->alias, $table->title, $menuTypeTable->title));
 245  
 246                  return false;
 247              }
 248          }
 249  
 250          if ($this->home == '1') {
 251              // Verify that the home page for this menu is unique.
 252              if (
 253                  $table->load(
 254                      array(
 255                      'menutype' => $this->menutype,
 256                      'client_id' => (int) $this->client_id,
 257                      'home' => '1',
 258                      )
 259                  )
 260                  && ($table->language != $this->language)
 261              ) {
 262                  $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_HOME_NOT_UNIQUE_IN_MENU'));
 263  
 264                  return false;
 265              }
 266  
 267              // Verify that the home page for this language is unique per client id
 268              if ($table->load(array('home' => '1', 'language' => $this->language, 'client_id' => (int) $this->client_id))) {
 269                  if ($table->checked_out && $table->checked_out != $this->checked_out) {
 270                      $this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_DEFAULT_CHECKIN_USER_MISMATCH'));
 271  
 272                      return false;
 273                  }
 274  
 275                  $table->home = 0;
 276                  $table->checked_out = null;
 277                  $table->checked_out_time = null;
 278                  $table->store();
 279              }
 280          }
 281  
 282          if (!parent::store($updateNulls)) {
 283              return false;
 284          }
 285  
 286          // Get the new path in case the node was moved
 287          $pathNodes = $this->getPath();
 288          $segments = array();
 289  
 290          foreach ($pathNodes as $node) {
 291              // Don't include root in path
 292              if ($node->alias !== 'root') {
 293                  $segments[] = $node->alias;
 294              }
 295          }
 296  
 297          $newPath = trim(implode('/', $segments), ' /\\');
 298  
 299          // Use new path for partial rebuild of table
 300          // Rebuild will return positive integer on success, false on failure
 301          return $this->rebuild($this->{$this->_tbl_key}, $this->lft, $this->level, $newPath) > 0;
 302      }
 303  }


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