Spade
Mini Shell
| Directory:~$ /proc/self/root/home/lmsyaran/www/joomla5/libraries/src/Table/ |
| [Home] [System Details] [Kill Me] |
<?php
/**
* Joomla! Content Management System
*
* @copyright (C) 2005 Open Source Matters, Inc.
<https://www.joomla.org>
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
namespace Joomla\CMS\Table;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\ParameterType;
use Joomla\Event\DispatcherInterface;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Menu table
*
* @since 1.5
*/
class Menu extends Nested
{
/**
* Indicates that columns fully support the NULL value in the database
*
* @var boolean
* @since 4.0.0
*/
protected $_supportNullValue = true;
/**
* Constructor
*
* @param DatabaseDriver $db Database connector
object
* @param ?DispatcherInterface $dispatcher Event dispatcher for
this table
*
* @since 1.5
*/
public function __construct(DatabaseDriver $db, DispatcherInterface
$dispatcher = null)
{
parent::__construct('#__menu', 'id', $db,
$dispatcher);
// Set the default access level.
$this->access = (int)
Factory::getApplication()->get('access');
}
/**
* Overloaded bind function
*
* @param array $array Named array
* @param mixed $ignore An optional array or space separated list
of properties to ignore while binding.
*
* @return mixed Null if operation was satisfactory, otherwise
returns an error
*
* @see Table::bind()
* @since 1.5
*/
public function bind($array, $ignore = '')
{
// Verify that the default home menu is not unset
if ($this->home == '1' && $this->language
=== '*' && $array['home'] == '0') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT_DEFAULT'));
return false;
}
// Verify that the default home menu set to "all"
languages" is not unset
if ($this->home == '1' && $this->language
=== '*' && $array['language'] !==
'*') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT'));
return false;
}
// Verify that the default home menu is not unpublished
if ($this->home == '1' && $this->language
=== '*' && $array['published'] !=
'1') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME'));
return false;
}
if (isset($array['params']) &&
\is_array($array['params'])) {
$registry = new Registry($array['params']);
$array['params'] = (string) $registry;
}
return parent::bind($array, $ignore);
}
/**
* Overloaded check function
*
* @return boolean True on success
*
* @see Table::check()
* @since 1.5
*/
public function check()
{
try {
parent::check();
} catch (\Exception $e) {
$this->setError($e->getMessage());
return false;
}
// Check for a title.
if ($this->title === null || trim($this->title) ===
'') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MENUITEM'));
return false;
}
// Check for a path.
if ($this->path === null || trim($this->path) ===
'') {
$this->path = $this->alias;
}
// Check for params.
if ($this->params === null || trim($this->params) ===
'') {
$this->params = '{}';
}
// Check for img.
if ($this->img === null || trim($this->img) === '')
{
$this->img = ' ';
}
// Cast the home property to an int for checking.
$this->home = (int) $this->home;
// Verify that the home item is a component.
if ($this->home && $this->type !==
'component') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_HOME_NOT_COMPONENT'));
return false;
}
// Set publish_up, publish_down to null if not set
if (!$this->publish_up) {
$this->publish_up = null;
}
if (!$this->publish_down) {
$this->publish_down = null;
}
return true;
}
/**
* Overloaded store function
*
* @param boolean $updateNulls True to update fields even if they
are null.
*
* @return mixed False on failure, positive integer on success.
*
* @see Table::store()
* @since 1.6
*/
public function store($updateNulls = true)
{
$db = $this->getDbo();
// Verify that the alias is unique
$table = new self($db, $this->getDispatcher());
$originalAlias = trim($this->alias);
$this->alias = !$originalAlias ? $this->title :
$originalAlias;
$this->alias =
ApplicationHelper::stringURLSafe(trim($this->alias),
$this->language);
if ($this->parent_id == 1 && $this->client_id == 0) {
// Verify that a first level menu item alias is not
'component'.
if ($this->alias === 'component') {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_COMPONENT'));
return false;
}
// Verify that a first level menu item alias is not the name of
a folder.
if (\in_array($this->alias, Folder::folders(JPATH_ROOT))) {
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_FOLDER',
$this->alias, $this->alias));
return false;
}
}
// If alias still empty (for instance, new menu item with chinese
characters with no unicode alias setting).
if (empty($this->alias)) {
$this->alias =
Factory::getDate()->format('Y-m-d-H-i-s');
} else {
$itemSearch = ['alias' => $this->alias,
'parent_id' => $this->parent_id, 'client_id'
=> (int) $this->client_id];
$error = false;
// Check if the alias already exists. For multilingual site.
if (Multilanguage::isEnabled() && (int)
$this->client_id == 0) {
// If there is a menu item at the same level with the same
alias (in the All or the same language).
if (
($table->load(array_replace($itemSearch,
['language' => '*'])) && ($table->id !=
$this->id || $this->id == 0))
|| ($table->load(array_replace($itemSearch,
['language' => $this->language])) && ($table->id
!= $this->id || $this->id == 0))
|| ($this->language === '*' &&
$this->id == 0 && $table->load($itemSearch))
) {
$error = true;
} elseif ($this->language === '*' &&
$this->id != 0) {
// When editing an item with All language check if
there are more menu items with the same alias in any language.
$id = (int) $this->id;
$query = $db->getQuery(true)
->select('id')
->from($db->quoteName('#__menu'))
->where($db->quoteName('parent_id')
. ' = 1')
->where($db->quoteName('client_id')
. ' = 0')
->where($db->quoteName('id') .
' != :id')
->where($db->quoteName('alias') .
' = :alias')
->bind(':id', $id,
ParameterType::INTEGER)
->bind(':alias', $this->alias);
$otherMenuItemId = (int)
$db->setQuery($query)->loadResult();
if ($otherMenuItemId) {
$table->load(['id' =>
$otherMenuItemId]);
$error = true;
}
}
} else {
// Check if the alias already exists. For monolingual site.
// If there is a menu item at the same level with the same
alias (in any language).
if ($table->load($itemSearch) && ($table->id
!= $this->id || $this->id == 0)) {
$error = true;
}
}
// The alias already exists. Enqueue an error message.
if ($error) {
$menuTypeTable = new MenuType($this->getDbo(),
$this->getDispatcher());
$menuTypeTable->load(['menutype' =>
$table->menutype]);
$url =
Route::_('index.php?option=com_menus&task=item.edit&id='
. (int) $table->id);
// Is the existing menu item trashed?
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS',
$this->alias, $table->title, $menuTypeTable->title, $url));
if ($table->published === -2) {
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS_TRASHED',
$this->alias, $table->title, $menuTypeTable->title, $url));
}
return false;
}
}
if ($this->home == '1') {
// Verify that the home page for this menu is unique.
if (
$table->load(
[
'menutype' => $this->menutype,
'client_id' => (int) $this->client_id,
'home' => '1',
]
)
&& ($table->language != $this->language)
) {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_HOME_NOT_UNIQUE_IN_MENU'));
return false;
}
// Verify that the home page for this language is unique per
client id
if ($table->load(['home' => '1',
'language' => $this->language, 'client_id' =>
(int) $this->client_id])) {
if ($table->checked_out &&
$table->checked_out != $this->checked_out) {
$this->setError(Text::_('JLIB_DATABASE_ERROR_MENU_DEFAULT_CHECKIN_USER_MISMATCH'));
return false;
}
$table->home = 0;
$table->checked_out = null;
$table->checked_out_time = null;
$table->store();
}
}
if (!parent::store($updateNulls)) {
return false;
}
// Get the new path in case the node was moved
$pathNodes = $this->getPath();
$segments = [];
foreach ($pathNodes as $node) {
// Don't include root in path
if ($node->alias !== 'root') {
$segments[] = $node->alias;
}
}
$newPath = trim(implode('/', $segments), '
/\\');
// Use new path for partial rebuild of table
// Rebuild will return positive integer on success, false on
failure
return $this->rebuild($this->{$this->_tbl_key},
$this->lft, $this->level, $newPath) > 0;
}
}