!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: nginx/1.23.4. PHP/5.6.40-65+ubuntu20.04.1+deb.sury.org+1 

uname -a: Linux foro-restaurado-2 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023
aarch64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/usr/share/phpmyadmin/libraries/classes/Navigation/   drwxr-xr-x
Free 83.24 GB of 96.73 GB (86.06%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     NavigationTree.php (53.33 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * Functionality for the navigation tree
 */

declare(strict_types=1);

namespace 
PhpMyAdmin\Navigation;

use 
PhpMyAdmin\CheckUserPrivileges;
use 
PhpMyAdmin\DatabaseInterface;
use 
PhpMyAdmin\Html\Generator;
use 
PhpMyAdmin\Navigation\Nodes\Node;
use 
PhpMyAdmin\Navigation\Nodes\NodeDatabase;
use 
PhpMyAdmin\Navigation\Nodes\NodeTable;
use 
PhpMyAdmin\Navigation\Nodes\NodeTableContainer;
use 
PhpMyAdmin\Navigation\Nodes\NodeViewContainer;
use 
PhpMyAdmin\RecentFavoriteTable;
use 
PhpMyAdmin\Response;
use 
PhpMyAdmin\Template;
use 
PhpMyAdmin\Url;
use const 
E_USER_WARNING;
use function 
array_key_exists;
use function 
array_keys;
use function 
array_shift;
use function 
base64_decode;
use function 
count;
use function 
explode;
use function 
floor;
use function 
get_class;
use function 
htmlspecialchars;
use function 
in_array;
use function 
is_array;
use function 
is_bool;
use function 
is_object;
use function 
mb_strlen;
use function 
mb_strpos;
use function 
mb_substr;
use function 
method_exists;
use function 
sort;
use function 
sprintf;
use function 
strcasecmp;
use function 
strlen;
use function 
strnatcasecmp;
use function 
strpos;
use function 
strrpos;
use function 
strstr;
use function 
substr;
use function 
trigger_error;
use function 
trim;
use function 
urlencode;
use function 
usort;
use function 
vsprintf;

/**
 * Displays a collapsible of database objects in the navigation frame
 */
class NavigationTree
{
    
/** @var Node Reference to the root node of the tree */
    
private $tree;
    
/**
     * @var array The actual paths to all expanded nodes in the tree
     *            This does not include nodes created after the grouping
     *            of nodes has been performed
     */
    
private $aPath = [];
    
/**
     * @var array The virtual paths to all expanded nodes in the tree
     *            This includes nodes created after the grouping of
     *            nodes has been performed
     */
    
private $vPath = [];
    
/**
     * @var int Position in the list of databases,
     *          used for pagination
     */
    
private $pos;
    
/**
     * @var string[] The names of the type of items that are being paginated on
     *               the second level of the navigation tree. These may be
     *               tables, views, functions, procedures or events.
     */
    
private $pos2Name = [];
    
/**
     * @var int[] The positions of nodes in the lists of tables, views,
     *            routines or events used for pagination
     */
    
private $pos2Value = [];
    
/**
     * @var string[] The names of the type of items that are being paginated
     *               on the second level of the navigation tree.
     *               These may be columns or indexes
     */
    
private $pos3Name = [];
    
/**
     * @var int[] The positions of nodes in the lists of columns or indexes
     *            used for pagination
     */
    
private $pos3Value = [];
    
/**
     * @var string The search clause to use in SQL queries for
     *             fetching databases
     *             Used by the asynchronous fast filter
     */
    
private $searchClause '';
    
/**
     * @var string The search clause to use in SQL queries for
     *             fetching nodes
     *             Used by the asynchronous fast filter
     */
    
private $searchClause2 '';
    
/**
     * @var bool Whether a warning was raised for large item groups
     *           which can affect performance.
     */
    
private $largeGroupWarning false;

    
/** @var Template */
    
private $template;

    
/** @var DatabaseInterface */
    
private $dbi;

    
/**
     * @param Template          $template Template instance
     * @param DatabaseInterface $dbi      DatabaseInterface instance
     */
    
public function __construct($templateDatabaseInterface $dbi)
    {
        
$this->template $template;
        
$this->dbi $dbi;

        
$checkUserPrivileges = new CheckUserPrivileges($this->dbi);
        
$checkUserPrivileges->getPrivileges();

        
// Save the position at which we are in the database list
        
if (isset($_POST['pos'])) {
            
$this->pos = (int) $_POST['pos'];
        } elseif (isset(
$_GET['pos'])) {
            
$this->pos = (int) $_GET['pos'];
        }
        if (! isset(
$this->pos)) {
            
$this->pos $this->getNavigationDbPos();
        }
        
// Get the active node
        
if (isset($_REQUEST['aPath'])) {
            
$this->aPath[0] = $this->parsePath($_REQUEST['aPath']);
            
$this->pos2Name[0] = $_REQUEST['pos2_name'] ?? '';
            
$this->pos2Value[0] = (int) ($_REQUEST['pos2_value'] ?? 0);
            if (isset(
$_REQUEST['pos3_name'])) {
                
$this->pos3Name[0] = $_REQUEST['pos3_name'] ?? '';
                
$this->pos3Value[0] = (int) $_REQUEST['pos3_value'];
            }
        } else {
            if (isset(
$_POST['n0_aPath'])) {
                
$count 0;
                while (isset(
$_POST['n' $count '_aPath'])) {
                    
$this->aPath[$count] = $this->parsePath(
                        
$_POST['n' $count '_aPath']
                    );
                    
$index 'n' $count '_pos2_';
                    
$this->pos2Name[$count] = $_POST[$index 'name'];
                    
$this->pos2Value[$count] = (int) $_POST[$index 'value'];
                    
$index 'n' $count '_pos3_';
                    if (isset(
$_POST[$index])) {
                        
$this->pos3Name[$count] = $_POST[$index 'name'];
                        
$this->pos3Value[$count] = (int) $_POST[$index 'value'];
                    }
                    
$count++;
                }
            }
        }
        if (isset(
$_REQUEST['vPath'])) {
            
$this->vPath[0] = $this->parsePath($_REQUEST['vPath']);
        } else {
            if (isset(
$_POST['n0_vPath'])) {
                
$count 0;
                while (isset(
$_POST['n' $count '_vPath'])) {
                    
$this->vPath[$count] = $this->parsePath(
                        
$_POST['n' $count '_vPath']
                    );
                    
$count++;
                }
            }
        }
        if (isset(
$_REQUEST['searchClause'])) {
            
$this->searchClause $_REQUEST['searchClause'];
        }
        if (isset(
$_REQUEST['searchClause2'])) {
            
$this->searchClause2 $_REQUEST['searchClause2'];
        }
        
// Initialize the tree by creating a root node
        
$node NodeFactory::getInstance('NodeDatabaseContainer''root');
        
$this->tree $node;
        if (! 
$GLOBALS['cfg']['NavigationTreeEnableGrouping']
            || ! 
$GLOBALS['cfg']['ShowDatabasesNavigationAsTree']
        ) {
            return;
        }

        
$this->tree->separator $GLOBALS['cfg']['NavigationTreeDbSeparator'];
        
$this->tree->separatorDepth 10000;
    }

    
/**
     * Returns the database position for the page selector
     */
    
private function getNavigationDbPos(): int
    
{
        
$retval 0;

        if (
strlen($GLOBALS['db']) == 0) {
            return 
$retval;
        }

        
/*
         * @todo describe a scenario where this code is executed
         */
        
if (! $GLOBALS['cfg']['Server']['DisableIS']) {
            
$dbSeparator $this->dbi->escapeString(
                
$GLOBALS['cfg']['NavigationTreeDbSeparator']
            );
            
$query 'SELECT (COUNT(DB_first_level) DIV %d) * %d ';
            
$query .= 'from ( ';
            
$query .= ' SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, ';
            
$query .= " '%s', 1) ";
            
$query .= ' DB_first_level ';
            
$query .= ' FROM INFORMATION_SCHEMA.SCHEMATA ';
            
$query .= " WHERE `SCHEMA_NAME` < '%s' ";
            
$query .= ') t ';

            return (int) 
$this->dbi->fetchValue(
                
sprintf(
                    
$query,
                    (int) 
$GLOBALS['cfg']['FirstLevelNavigationItems'],
                    (int) 
$GLOBALS['cfg']['FirstLevelNavigationItems'],
                    
$dbSeparator,
                    
$this->dbi->escapeString($GLOBALS['db'])
                )
            );
        }

        
$prefixMap = [];
        if (
$GLOBALS['dbs_to_test'] === false) {
            
$handle $this->dbi->tryQuery('SHOW DATABASES');
            if (
$handle !== false) {
                while (
$arr $this->dbi->fetchArray($handle)) {
                    if (
strcasecmp($arr[0], $GLOBALS['db']) >= 0) {
                        break;
                    }

                    
$prefix strstr(
                        
$arr[0],
                        
$GLOBALS['cfg']['NavigationTreeDbSeparator'],
                        
true
                    
);
                    if (
$prefix === false) {
                        
$prefix $arr[0];
                    }
                    
$prefixMap[$prefix] = 1;
                }
            }
        } else {
            
$databases = [];
            foreach (
$GLOBALS['dbs_to_test'] as $db) {
                
$query "SHOW DATABASES LIKE '" $db "'";
                
$handle $this->dbi->tryQuery($query);
                if (
$handle === false) {
                    continue;
                }
                while (
$arr $this->dbi->fetchArray($handle)) {
                    
$databases[] = $arr[0];
                }
            }
            
sort($databases);
            foreach (
$databases as $database) {
                if (
strcasecmp($database$GLOBALS['db']) >= 0) {
                    break;
                }

                
$prefix strstr(
                    
$database,
                    
$GLOBALS['cfg']['NavigationTreeDbSeparator'],
                    
true
                
);
                if (
$prefix === false) {
                    
$prefix $database;
                }
                
$prefixMap[$prefix] = 1;
            }
        }

        
$navItems = (int) $GLOBALS['cfg']['FirstLevelNavigationItems'];

        return (int) 
floor(count($prefixMap) / $navItems) * $navItems;
    }

    
/**
     * Converts an encoded path to a node in string format to an array
     *
     * @param string $string The path to parse
     *
     * @return array
     */
    
private function parsePath($string): array
    {
        
$path explode('.'$string);
        foreach (
$path as $key => $value) {
            
$path[$key] = base64_decode($value);
        }

        return 
$path;
    }

    
/**
     * Generates the tree structure so that it can be rendered later
     *
     * @return Node|bool The active node or false in case of failure, or true: (@see buildPathPart())
     */
    
private function buildPath()
    {
        
$retval $this->tree;

        
// Add all databases unconditionally
        
$data $this->tree->getData(
            
'databases',
            
$this->pos,
            
$this->searchClause
        
);
        
$hiddenCounts $this->tree->getNavigationHidingData();
        foreach (
$data as $db) {
            
/** @var NodeDatabase $node */
            
$node NodeFactory::getInstance('NodeDatabase'$db);
            if (isset(
$hiddenCounts[$db])) {
                
$node->setHiddenCount($hiddenCounts[$db]);
            }
            
$this->tree->addChild($node);
        }

        
// Whether build other parts of the tree depends
        // on whether we have any paths in $this->aPath
        
foreach ($this->aPath as $key => $path) {
            
$retval $this->buildPathPart(
                
$path,
                
$this->pos2Name[$key] ?? '',
                
$this->pos2Value[$key] ?? 0,
                
$this->pos3Name[$key] ?? '',
                
$this->pos3Value[$key] ?? 0
            
);
        }

        return 
$retval;
    }

    
/**
     * Builds a branch of the tree
     *
     * @param array  $path  A paths pointing to the branch
     *                      of the tree that needs to be built
     * @param string $type2 The type of item being paginated on
     *                      the second level of the tree
     * @param int    $pos2  The position for the pagination of
     *                      the branch at the second level of the tree
     * @param string $type3 The type of item being paginated on
     *                      the third level of the tree
     * @param int    $pos3  The position for the pagination of
     *                      the branch at the third level of the tree
     *
     * @return Node|bool    The active node or false in case of failure, true if the path contains <= 1 items
     */
    
private function buildPathPart(array $pathstring $type2int $pos2string $type3int $pos3)
    {
        if (
count($path) <= 1) {
            return 
true;
        }

        
array_shift($path); // remove 'root'
        /** @var NodeDatabase|null $db */
        
$db $this->tree->getChild($path[0]);

        if (
$db === null) {
            return 
false;
        }

        
$retval $db;

        
$containers $this->addDbContainers($db$type2$pos2);

        
array_shift($path); // remove db

        
if ((count($path) <= || ! array_key_exists($path[0], $containers))
            && 
count($containers) != 1
        
) {
            return 
$retval;
        }

        if (
count($containers) === 1) {
            
$container array_shift($containers);
        } else {
            
$container $db->getChild($path[0], true);
            if (
$container === null) {
                return 
false;
            }
        }
        
$retval $container;

        if (
count($container->children) <= 1) {
            
$dbData $db->getData(
                
$container->realName,
                
$pos2,
                
$this->searchClause2
            
);
            foreach (
$dbData as $item) {
                switch (
$container->realName) {
                    case 
'events':
                        
$node NodeFactory::getInstance(
                            
'NodeEvent',
                            
$item
                        
);
                        break;
                    case 
'functions':
                        
$node NodeFactory::getInstance(
                            
'NodeFunction',
                            
$item
                        
);
                        break;
                    case 
'procedures':
                        
$node NodeFactory::getInstance(
                            
'NodeProcedure',
                            
$item
                        
);
                        break;
                    case 
'tables':
                        
$node NodeFactory::getInstance(
                            
'NodeTable',
                            
$item
                        
);
                        break;
                    case 
'views':
                        
$node NodeFactory::getInstance(
                            
'NodeView',
                            
$item
                        
);
                        break;
                    default:
                        break;
                }
                if (! isset(
$node)) {
                    continue;
                }

                if (
$type2 == $container->realName) {
                    
$node->pos2 $pos2;
                }
                
$container->addChild($node);
            }
        }
        if (
count($path) > && $path[0] !== 'tables') {
            return 
false;
        }

        
array_shift($path); // remove container
        
if (count($path) <= 0) {
            return 
$retval;
        }

        
/** @var NodeTable|null $table */
        
$table $container->getChild($path[0], true);
        if (
$table === null) {
            if (! 
$db->getPresence('tables'$path[0])) {
                return 
false;
            }

            
$node NodeFactory::getInstance(
                
'NodeTable',
                
$path[0]
            );
            if (
$type2 == $container->realName) {
                
$node->pos2 $pos2;
            }
            
$container->addChild($node);
            
$table $container->getChild($path[0], true);
        }
        
$retval $table ?? false;
        
$containers $this->addTableContainers(
            
$table,
            
$pos2,
            
$type3,
            
$pos3
        
);
        
array_shift($path); // remove table
        
if (count($path) <= 0
            
|| ! array_key_exists($path[0], $containers)
        ) {
            return 
$retval;
        }

        
$container $table->getChild($path[0], true);
        
$retval $container ?? false;
        
$tableData $table->getData(
            
$container->realName,
            
$pos3
        
);
        foreach (
$tableData as $item) {
            switch (
$container->realName) {
                case 
'indexes':
                    
$node NodeFactory::getInstance(
                        
'NodeIndex',
                        
$item
                    
);
                    break;
                case 
'columns':
                    
$node NodeFactory::getInstance(
                        
'NodeColumn',
                        
$item
                    
);
                    break;
                case 
'triggers':
                    
$node NodeFactory::getInstance(
                        
'NodeTrigger',
                        
$item
                    
);
                    break;
                default:
                    break;
            }
            if (! isset(
$node)) {
                continue;
            }

            
$node->pos2 $container->parent->pos2;
            if (
$type3 == $container->realName) {
                
$node->pos3 $pos3;
            }
            
$container->addChild($node);
        }

        return 
$retval;
    }

    
/**
     * Adds containers to a node that is a table
     *
     * References to existing children are returned
     * if this function is called twice on the same node
     *
     * @param NodeTable $table The table node, new containers will be
     *                         attached to this node
     * @param int       $pos2  The position for the pagination of
     *                         the branch at the second level of the tree
     * @param string    $type3 The type of item being paginated on
     *                         the third level of the tree
     * @param int       $pos3  The position for the pagination of
     *                         the branch at the third level of the tree
     *
     * @return array An array of new nodes
     */
    
private function addTableContainers(NodeTable $tableint $pos2string $type3int $pos3): array
    {
        
$retval = [];
        if (
$table->hasChildren(true) == 0) {
            if (
$table->getPresence('columns')) {
                
$retval['columns'] = NodeFactory::getInstance(
                    
'NodeColumnContainer'
                
);
            }
            if (
$table->getPresence('indexes')) {
                
$retval['indexes'] = NodeFactory::getInstance(
                    
'NodeIndexContainer'
                
);
            }
            if (
$table->getPresence('triggers')) {
                
$retval['triggers'] = NodeFactory::getInstance(
                    
'NodeTriggerContainer'
                
);
            }
            
// Add all new Nodes to the tree
            
foreach ($retval as $node) {
                
$node->pos2 $pos2;
                if (
$type3 == $node->realName) {
                    
$node->pos3 $pos3;
                }
                
$table->addChild($node);
            }
        } else {
            foreach (
$table->children as $node) {
                if (
$type3 == $node->realName) {
                    
$node->pos3 $pos3;
                }
                
$retval[$node->realName] = $node;
            }
        }

        return 
$retval;
    }

    
/**
     * Adds containers to a node that is a database
     *
     * References to existing children are returned
     * if this function is called twice on the same node
     *
     * @param NodeDatabase $db   The database node, new containers will be
     *                           attached to this node
     * @param string       $type The type of item being paginated on
     *                           the second level of the tree
     * @param int          $pos2 The position for the pagination of
     *                           the branch at the second level of the tree
     *
     * @return array An array of new nodes
     */
    
private function addDbContainers(NodeDatabase $dbstring $typeint $pos2): array
    {
        
// Get items to hide
        
$hidden $db->getHiddenItems('group');
        if (! 
$GLOBALS['cfg']['NavigationTreeShowTables']
            && ! 
in_array('tables'$hidden)
        ) {
            
$hidden[] = 'tables';
        }
        if (! 
$GLOBALS['cfg']['NavigationTreeShowViews']
            && ! 
in_array('views'$hidden)
        ) {
            
$hidden[] = 'views';
        }
        if (! 
$GLOBALS['cfg']['NavigationTreeShowFunctions']
            && ! 
in_array('functions'$hidden)
        ) {
            
$hidden[] = 'functions';
        }
        if (! 
$GLOBALS['cfg']['NavigationTreeShowProcedures']
            && ! 
in_array('procedures'$hidden)
        ) {
            
$hidden[] = 'procedures';
        }
        if (! 
$GLOBALS['cfg']['NavigationTreeShowEvents']
            && ! 
in_array('events'$hidden)
        ) {
            
$hidden[] = 'events';
        }

        
$retval = [];
        if (
$db->hasChildren(true) == 0) {
            if (! 
in_array('tables'$hidden) && $db->getPresence('tables')) {
                
$retval['tables'] = NodeFactory::getInstance(
                    
'NodeTableContainer'
                
);
            }
            if (! 
in_array('views'$hidden) && $db->getPresence('views')) {
                
$retval['views'] = NodeFactory::getInstance(
                    
'NodeViewContainer'
                
);
            }
            if (! 
in_array('functions'$hidden) && $db->getPresence('functions')) {
                
$retval['functions'] = NodeFactory::getInstance(
                    
'NodeFunctionContainer'
                
);
            }
            if (! 
in_array('procedures'$hidden) && $db->getPresence('procedures')) {
                
$retval['procedures'] = NodeFactory::getInstance(
                    
'NodeProcedureContainer'
                
);
            }
            if (! 
in_array('events'$hidden) && $db->getPresence('events')) {
                
$retval['events'] = NodeFactory::getInstance(
                    
'NodeEventContainer'
                
);
            }
            
// Add all new Nodes to the tree
            
foreach ($retval as $node) {
                if (
$type == $node->realName) {
                    
$node->pos2 $pos2;
                }
                
$db->addChild($node);
            }
        } else {
            foreach (
$db->children as $node) {
                if (
$type == $node->realName) {
                    
$node->pos2 $pos2;
                }
                
$retval[$node->realName] = $node;
            }
        }

        return 
$retval;
    }

    
/**
     * Recursively groups tree nodes given a separator
     *
     * @param Node $node The node to group or null
     *                   to group the whole tree. If
     *                   passed as an argument, $node
     *                   must be of type CONTAINER
     */
    
public function groupTree(?Node $node null): void
    
{
        if (
$node === null) {
            
$node $this->tree;
        }
        
$this->groupNode($node);
        foreach (
$node->children as $child) {
            
$this->groupTree($child);
        }
    }

    
/**
     * Recursively groups tree nodes given a separator
     *
     * @param Node $node The node to group
     */
    
public function groupNode($node): void
    
{
        if (
$node->type != Node::CONTAINER
            
|| ! $GLOBALS['cfg']['NavigationTreeEnableExpansion']
        ) {
            return;
        }

        
$separators = [];
        if (
is_array($node->separator)) {
            
$separators $node->separator;
        } else {
            if (
strlen($node->separator)) {
                
$separators[] = $node->separator;
            }
        }
        
$prefixes = [];
        if (
$node->separatorDepth 0) {
            foreach (
$node->children as $child) {
                
$prefixPos false;
                foreach (
$separators as $separator) {
                    
$sepPos mb_strpos((string) $child->name$separator);
                    if (
$sepPos == false
                        
|| $sepPos == mb_strlen($child->name)
                        || 
$sepPos == 0
                        
|| ($prefixPos !== false && $sepPos >= $prefixPos)
                    ) {
                        continue;
                    }

                    
$prefixPos $sepPos;
                }
                if (
$prefixPos !== false) {
                    
$prefix mb_substr($child->name0$prefixPos);
                    if (! isset(
$prefixes[$prefix])) {
                        
$prefixes[$prefix] = 1;
                    } else {
                        
$prefixes[$prefix]++;
                    }
                }
                
//Bug #4375: Check if prefix is the name of a DB, to create a group.
                
foreach ($node->children as $otherChild) {
                    if (! 
array_key_exists($otherChild->name$prefixes)) {
                        continue;
                    }

                    
$prefixes[$otherChild->name]++;
                }
            }
            
//Check if prefix is the name of a DB, to create a group.
            
foreach ($node->children as $child) {
                if (! 
array_key_exists($child->name$prefixes)) {
                    continue;
                }

                
$prefixes[$child->name]++;
            }
        }
        
// It is not a group if it has only one item
        
foreach ($prefixes as $key => $value) {
            if (
$value 1) {
                continue;
            }

            unset(
$prefixes[$key]);
        }
        
// rfe #1634 Don't group if there's only one group and no other items
        
if (count($prefixes) === 1) {
            
$keys array_keys($prefixes);
            
$key $keys[0];
            if (
$prefixes[$key] == count($node->children) - 1) {
                unset(
$prefixes[$key]);
            }
        }
        if (! 
count($prefixes)) {
            return;
        }

        
/** @var Node[] $groups */
        
$groups = [];
        foreach (
$prefixes as $key => $value) {
            
// warn about large groups
            
if ($value 500 && ! $this->largeGroupWarning) {
                
trigger_error(
                    
__(
                        
'There are large item groups in navigation panel which '
                        
'may affect the performance. Consider disabling item '
                        
'grouping in the navigation panel.'
                    
),
                    
E_USER_WARNING
                
);
                
$this->largeGroupWarning true;
            }

            
$groups[$key] = new Node(
                
htmlspecialchars((string) $key),
                
Node::CONTAINER,
                
true
            
);
            
$groups[$key]->separator $node->separator;
            
$groups[$key]->separatorDepth $node->separatorDepth 1;
            
$groups[$key]->icon Generator::getImage(
                
'b_group',
                
__('Groups')
            );
            
$groups[$key]->pos2 $node->pos2;
            
$groups[$key]->pos3 $node->pos3;
            if (
$node instanceof NodeTableContainer
                
|| $node instanceof NodeViewContainer
            
) {
                
$tblGroup '&amp;tbl_group=' urlencode((string) $key);
                
$groups[$key]->links = [
                    
'text' => $node->links['text'] . $tblGroup,
                    
'icon' => $node->links['icon'] . $tblGroup,
                ];
            }
            
$node->addChild($groups[$key]);
            foreach (
$separators as $separator) {
                
$separatorLength strlen($separator);
                
// FIXME: this could be more efficient
                
foreach ($node->children as $child) {
                    
$keySeparatorLength mb_strlen((string) $key) + $separatorLength;
                    
$nameSubstring mb_substr(
                        (string) 
$child->name,
                        
0,
                        
$keySeparatorLength
                    
);
                    if ((
$nameSubstring != $key $separator
                        
&& $child->name != $key)
                        || 
$child->type != Node::OBJECT
                    
) {
                        continue;
                    }
                    
$class get_class($child);
                    
$className substr($classstrrpos($class'\\') + 1);
                    unset(
$class);
                    
/** @var NodeDatabase $newChild */
                    
$newChild NodeFactory::getInstance(
                        
$className,
                        
mb_substr(
                            
$child->name,
                            
$keySeparatorLength
                        
)
                    );
                    if (
$child instanceof NodeDatabase
                        
&& $child->getHiddenCount() > 0
                    
) {
                        
$newChild->setHiddenCount($child->getHiddenCount());
                    }

                    
$newChild->realName $child->realName;
                    
$newChild->icon $child->icon;
                    
$newChild->links $child->links;
                    
$newChild->pos2 $child->pos2;
                    
$newChild->pos3 $child->pos3;
                    
$groups[$key]->addChild($newChild);
                    foreach (
$child->children as $elm) {
                        
$newChild->addChild($elm);
                    }
                    
$node->removeChild($child->name);
                }
            }
        }
        foreach (
$prefixes as $key => $value) {
            
$this->groupNode($groups[$key]);
            
$groups[$key]->classes 'navGroup';
        }
    }

    
/**
     * Renders a state of the tree, used in light mode when
     * either JavaScript and/or Ajax are disabled
     *
     * @return string HTML code for the navigation tree
     */
    
public function renderState(): string
    
{
        
$this->buildPath();

        
$quickWarp $this->quickWarp();
        
$fastFilter $this->fastFilterHtml($this->tree);
        
$controls '';
        if (
$GLOBALS['cfg']['NavigationTreeEnableExpansion']) {
            
$controls $this->controls();
        }
        
$pageSelector $this->getPageSelector($this->tree);

        
$this->groupTree();
        
$children $this->tree->children;
        
usort($children, [
            
self::class,
            
'sortNode',
        ]);
        
$this->setVisibility();

        
$nodes '';
        for (
$i 0$nbChildren count($children); $i $nbChildren$i++) {
            if (
$i == 0) {
                
$nodes .= $this->renderNode($children[0], true'first');
            } else {
                if (
$i != $nbChildren) {
                    
$nodes .= $this->renderNode($children[$i], true);
                } else {
                    
$nodes .= $this->renderNode($children[$i], true'last');
                }
            }
        }

        return 
$this->template->render('navigation/tree/state', [
            
'quick_warp' => $quickWarp,
            
'fast_filter' => $fastFilter,
            
'controls' => $controls,
            
'page_selector' => $pageSelector,
            
'nodes' => $nodes,
        ]);
    }

    
/**
     * Renders a part of the tree, used for Ajax requests in light mode
     *
     * @return string|false HTML code for the navigation tree
     */
    
public function renderPath()
    {
        
$node $this->buildPath();
        if (! 
is_bool($node)) {
            
$this->groupTree();

            
$listContent $this->fastFilterHtml($node);
            
$listContent .= $this->getPageSelector($node);
            
$children $node->children;
            
usort($children, [
                
self::class,
                
'sortNode',
            ]);

            for (
$i 0$nbChildren count($children); $i $nbChildren$i++) {
                if (
$i != $nbChildren) {
                    
$listContent .= $this->renderNode($children[$i], true);
                } else {
                    
$listContent .= $this->renderNode($children[$i], true'last');
                }
            }

            if (! 
$GLOBALS['cfg']['ShowDatabasesNavigationAsTree']) {
                
$parents $node->parents(true);
                
$parentName $parents[0]->realName;
            }
        }

        
$hasSearchClause = ! empty($this->searchClause) || ! empty($this->searchClause2);
        if (
$hasSearchClause && ! is_bool($node)) {
            
$results 0;
            if (! empty(
$this->searchClause2)) {
                if (
is_object($node->realParent())) {
                    
$results $node->realParent()
                        ->
getPresence(
                            
$node->realName,
                            
$this->searchClause2
                        
);
                }
            } else {
                
$results $this->tree->getPresence(
                    
'databases',
                    
$this->searchClause
                
);
            }
            
$results sprintf(
                
_ngettext(
                    
'%s result found',
                    
'%s results found',
                    
$results
                
),
                
$results
            
);
            
Response::getInstance()
                ->
addJSON(
                    
'results',
                    
$results
                
);
        }

        if (
$node !== false) {
            return 
$this->template->render('navigation/tree/path', [
                
'has_search_results' => ! empty($this->searchClause) || ! empty($this->searchClause2),
                
'list_content' => $listContent ?? '',
                
'is_tree' => $GLOBALS['cfg']['ShowDatabasesNavigationAsTree'],
                
'parent_name' => $parentName ?? '',
            ]);
        }

        return 
false;
    }

    
/**
     * Renders the parameters that are required on the client
     * side to know which page(s) we will be requesting data from
     *
     * @param Node $node The node to create the pagination parameters for
     */
    
private function getPaginationParamsHtml(Node $node): string
    
{
        
$retval '';
        
$paths $node->getPaths();
        if (isset(
$paths['aPath_clean'][2])) {
            
$retval .= '<span class="hide pos2_nav"';
            
$retval .= ' data-name="' $paths['aPath_clean'][2] . '"';
            
$retval .= ' data-value="' htmlspecialchars((string) $node->pos2) . '"';
            
$retval .= '"></span>';
        }
        if (isset(
$paths['aPath_clean'][4])) {
            
$retval .= '<span class="hide pos3_nav"';
            
$retval .= ' data-name="' $paths['aPath_clean'][4] . '"';
            
$retval .= ' data-value="' htmlspecialchars((string) $node->pos3) . '"';
            
$retval .= '"></span>';
        }

        return 
$retval;
    }

    
/**
     * Finds whether given tree matches this tree.
     *
     * @param array $tree  Tree to check
     * @param array $paths Paths to check
     */
    
private function findTreeMatch(array $tree, array $paths): bool
    
{
        
$match false;
        foreach (
$tree as $path) {
            
$match true;
            foreach (
$paths as $key => $part) {
                if (! isset(
$path[$key]) || $part != $path[$key]) {
                    
$match false;
                    break;
                }
            }
            if (
$match) {
                break;
            }
        }

        return 
$match;
    }

    
/**
     * Renders a single node or a branch of the tree
     *
     * @param Node   $node      The node to render
     * @param bool   $recursive Whether to render a single node or a branch
     * @param string $class     An additional class for the list item
     *
     * @return string HTML code for the tree node or branch
     */
    
private function renderNode(Node $nodebool $recursivestring $class ''): string
    
{
        
$retval '';
        
$paths $node->getPaths();
        
$nodeIsContainer $node->type === Node::CONTAINER;

        if (
$node->hasSiblings()
            || 
$node->realParent() === false
        
) {
            
$response Response::getInstance();
            if (
$nodeIsContainer
                
&& count($node->children) === 0
                
&& ! $response->isAjax()
            ) {
                return 
'';
            }
            
$retval .= '<li class="' trim($class ' ' $node->classes) . '">';
            
$sterile = [
                
'events',
                
'triggers',
                
'functions',
                
'procedures',
                
'views',
                
'columns',
                
'indexes',
            ];
            
$parentName '';
            
$parents $node->parents(falsetrue);
            if (
count($parents)) {
                
$parentName $parents[0]->realName;
            }
            
// if node name itself is in sterile, then allow
            
if ($node->isGroup
                
|| (! in_array($parentName$sterile) && ! $node->isNew)
                || (
in_array($node->realName$sterile) && ! empty($node->children))
            ) {
                
$retval .= "<div class='block'>";
                
$iClass '';
                if (
$class === 'first') {
                    
$iClass " class='first'";
                }
                
$retval .= '<i' $iClass '></i>';
                if (
strpos($class'last') === false) {
                    
$retval .= '<b></b>';
                }

                
$match $this->findTreeMatch(
                    
$this->vPath,
                    
$paths['vPath_clean']
                );

                
$retval .= '<a class="' $node->getCssClasses($match) . '"';
                
$retval .= " href='#'>";

                
$retval .= '<span class="hide paths_nav"';
                
$retval .= ' data-apath="' $paths['aPath'] . '"';
                
$retval .= ' data-vpath="' $paths['vPath'] . '"';
                
$retval .= ' data-pos="' $this->pos '"';
                
$retval .= '"></span>';
                
$retval .= $this->getPaginationParamsHtml($node);
                if (
$GLOBALS['cfg']['ShowDatabasesNavigationAsTree']
                    || 
$parentName !== 'root'
                
) {
                    
$retval .= $node->getIcon($match);
                }

                
$retval .= '</a>';
                
$retval .= '</div>';
            } else {
                
$retval .= "<div class='block'>";
                
$iClass '';
                if (
$class === 'first') {
                    
$iClass " class='first'";
                }
                
$retval .= '<i' $iClass '></i>';
                
$retval .= $this->getPaginationParamsHtml($node);
                
$retval .= '</div>';
            }

            
$linkClass '';
            
$haveAjax = [
                
'functions',
                
'procedures',
                
'events',
                
'triggers',
                
'indexes',
            ];
            
$parent $node->parents(falsetrue);
            
$isNewView $parent[0]->realName === 'views' && $node->isNew === true;
            if (
$parent[0]->type == Node::CONTAINER
                
&& (in_array($parent[0]->realName$haveAjax) || $isNewView)
            ) {
                
$linkClass ' ajax';
            }

            if (
$nodeIsContainer) {
                
$retval .= '<i>';
            }

            
// The .second class is used in js/src/navigation.js
            
$divClass 'second';

            
$iconLinks = [];
            
$icons = [];
            if (isset(
$node->links['icon']) && ! empty($node->links['icon'])) {
                
$iconLinks $node->links['icon'];
                
/** @var array|string $icons */
                
$icons $node->icon;
                if (! 
is_array($iconLinks)) {
                    
$iconLinks = [$iconLinks];
                    
$icons = [$icons];
                }
                
/** @var array $icons */
                
if (count($icons) > 1) {
                    
// Generates: .second double class for NavigationTreeDefaultTabTable2
                    
$divClass 'second double';
                }
            }

            
$retval .= '<div class="block ' $divClass '">';

            if (isset(
$node->links['icon']) && ! empty($node->links['icon'])) {
                
$args = [];
                foreach (
$node->parents(true) as $parent) {
                    
$args[] = urlencode($parent->realName);
                }

                foreach (
$icons as $key => $icon) {
                    
$link vsprintf($iconLinks[$key], $args);
                    if (
$linkClass != '') {
                        
$retval .= "<a class='" $linkClass "' href='" $link "'>";
                        
$retval .= '' $icon '</a>';
                    } else {
                        
$retval .= "<a href='" $link "'>" $icon '</a>';
                    }
                }
            } else {
                
$retval .= '<u>' $node->icon '</u>';
            }
            
$retval .= '</div>';

            if (isset(
$node->links['text'])) {
                
$args = [];
                foreach (
$node->parents(true) as $parent) {
                    
$args[] = urlencode($parent->realName);
                }
                
$link vsprintf($node->links['text'], $args);
                
$title $node->links['title'] ?? $node->title ?? '';
                if (
$nodeIsContainer) {
                    
$retval .= "&nbsp;<a class='hover_show_full' href='" $link "'>";
                    
$retval .= htmlspecialchars($node->name);
                    
$retval .= '</a>';
                } else {
                    
$retval .= "<a class='hover_show_full" $linkClass "' href='" $link "'";
                    
$retval .= " title='" $title "'>";
                    
$retval .= htmlspecialchars($node->displayName ?? $node->realName);
                    
$retval .= '</a>';
                }
            } else {
                
$retval .= '&nbsp;' $node->name '';
            }
            
$retval .= $node->getHtmlForControlButtons();
            if (
$nodeIsContainer) {
                
$retval .= '</i>';
            }
            
$retval .= '<div class="clearfloat"></div>';
            
$wrap true;
        } else {
            
$node->visible true;
            
$wrap false;
            
$retval .= $this->getPaginationParamsHtml($node);
        }

        if (
$recursive) {
            
$hide '';
            if (! 
$node->visible) {
                
$hide " style='display: none;'";
            }
            
$children $node->children;
            
usort(
                
$children,
                [
                    
self::class,
                    
'sortNode',
                ]
            );
            
$buffer '';
            
$extraClass '';
            for (
$i 0$nbChildren count($children); $i $nbChildren$i++) {
                if (
$i == $nbChildren) {
                    
$extraClass ' last';
                }
                
$buffer .= $this->renderNode(
                    
$children[$i],
                    
true,
                    
$children[$i]->classes $extraClass
                
);
            }
            if (! empty(
$buffer)) {
                if (
$wrap) {
                    
$retval .= '<div' $hide " class='list_container'><ul>";
                }
                
$retval .= $this->fastFilterHtml($node);
                
$retval .= $this->getPageSelector($node);
                
$retval .= $buffer;
                if (
$wrap) {
                    
$retval .= '</ul></div>';
                }
            }
        }
        if (
$node->hasSiblings()) {
            
$retval .= '</li>';
        }

        return 
$retval;
    }

    
/**
     * Renders a database select box like the pre-4.0 navigation panel
     *
     * @return string HTML code
     */
    
public function renderDbSelect(): string
    
{
        
$this->buildPath();

        
$quickWarp $this->quickWarp();

        
$this->tree->isGroup false;

        
// Provide for pagination in database select
        
$listNavigator Generator::getListNavigator(
            
$this->tree->getPresence('databases'''),
            
$this->pos,
            [
'server' => $GLOBALS['server']],
            
Url::getFromRoute('/navigation'),
            
'frame_navigation',
            
$GLOBALS['cfg']['FirstLevelNavigationItems'],
            
'pos',
            [
'dbselector']
        );

        
$children $this->tree->children;
        
$selected $GLOBALS['db'];
        
$options = [];
        foreach (
$children as $node) {
            if (
$node->isNew) {
                continue;
            }
            
$paths $node->getPaths();
            if (! isset(
$node->links['text'])) {
                continue;
            }

            
$title = isset($node->links['title']) ? '' $node->links['title'];
            
$options[] = [
                
'title' => $title,
                
'name' => $node->realName,
                
'data' => [
                    
'apath' => $paths['aPath'],
                    
'vpath' => $paths['vPath'],
                    
'pos' => $this->pos,
                ],
                
'isSelected' => $node->realName === $selected,
            ];
        }

        
$children $this->tree->children;
        
usort($children, [
            
self::class,
            
'sortNode',
        ]);
        
$this->setVisibility();

        
$nodes '';
        for (
$i 0$nbChildren count($children); $i $nbChildren$i++) {
            if (
$i == 0) {
                
$nodes .= $this->renderNode($children[0], true'first');
            } else {
                if (
$i != $nbChildren) {
                    
$nodes .= $this->renderNode($children[$i], true);
                } else {
                    
$nodes .= $this->renderNode($children[$i], true'last');
                }
            }
        }

        return 
$this->template->render('navigation/tree/database_select', [
            
'quick_warp' => $quickWarp,
            
'list_navigator' => $listNavigator,
            
'server' => $GLOBALS['server'],
            
'options' => $options,
            
'nodes' => $nodes,
        ]);
    }

    
/**
     * Makes some nodes visible based on the which node is active
     */
    
private function setVisibility(): void
    
{
        foreach (
$this->vPath as $path) {
            
$node $this->tree;
            foreach (
$path as $value) {
                
$child $node->getChild($value);
                if (
$child === null) {
                    continue;
                }

                
$child->visible true;
                
$node $child;
            }
        }
    }

    
/**
     * Generates the HTML code for displaying the fast filter for tables
     *
     * @param Node $node The node for which to generate the fast filter html
     *
     * @return string LI element used for the fast filter
     */
    
private function fastFilterHtml(Node $node): string
    
{
        
$retval '';
        
$filterDbMin
            
= (int) $GLOBALS['cfg']['NavigationTreeDisplayDbFilterMinimum'];
        
$filterItemMin
            
= (int) $GLOBALS['cfg']['NavigationTreeDisplayItemFilterMinimum'];
        if (
$node === $this->tree
            
&& $this->tree->getPresence() >= $filterDbMin
        
) {
            
$urlParams = ['pos' => 0];
            
$retval .= '<li class="fast_filter db_fast_filter">';
            
$retval .= '<form class="ajax fast_filter">';
            
$retval .= Url::getHiddenInputs($urlParams);
            
$retval .= '<input class="searchClause" type="text"';
            
$retval .= ' name="searchClause" accesskey="q"';
            
$retval .= " placeholder='"
                
__('Type to filter these, Enter to search all');
            
$retval .= "'>";
            
$retval .= '<span title="' __('Clear fast filter') . '">X</span>';
            
$retval .= '</form>';
            
$retval .= '</li>';

            return 
$retval;
        }

        
$nodeIsContainer $node->type === Node::CONTAINER;
        
$nodeIsSpecial $node->realName === 'tables'
                            
|| $node->realName === 'views'
                            
|| $node->realName === 'functions'
                            
|| $node->realName === 'procedures'
                            
|| $node->realName === 'events';
        
/** @var Node $realParent */
        
$realParent $node->realParent();
        if ((
$nodeIsContainer && $nodeIsSpecial)
            && 
method_exists($realParent'getPresence')
            && 
$realParent->getPresence($node->realName) >= $filterItemMin
        
) {
            
$paths $node->getPaths();
            
$urlParams = [
                
'pos'        => $this->pos,
                
'aPath'      => $paths['aPath'],
                
'vPath'      => $paths['vPath'],
                
'pos2_name'  => $node->realName,
                
'pos2_value' => 0,
            ];
            
$retval .= "<li class='fast_filter'>";
            
$retval .= "<form class='ajax fast_filter'>";
            
$retval .= Url::getHiddenFields($urlParams);
            
$retval .= "<input class='searchClause' type='text'";
            
$retval .= " name='searchClause2'";
            
$retval .= " placeholder='"
                
__('Type to filter these, Enter to search all') . "'>";
            
$retval .= "<span title='" __('Clear fast filter') . "'>X</span>";
            
$retval .= '</form>';
            
$retval .= '</li>';
        }

        return 
$retval;
    }

    
/**
     * Creates the code for displaying the controls
     * at the top of the navigation tree
     *
     * @return string HTML code for the controls
     */
    
private function controls(): string
    
{
        
// always iconic
        
$showIcon true;
        
$showText false;

        
$retval '<!-- CONTROLS START -->';
        
$retval .= '<li id="navigation_controls_outer">';
        
$retval .= '<div id="navigation_controls">';
        
$retval .= Generator::getNavigationLink(
            
'#',
            
$showText,
            
__('Collapse all'),
            
$showIcon,
            
's_collapseall',
            
'pma_navigation_collapse'
        
);
        
$syncImage 's_unlink';
        
$title __('Link with main panel');
        if (
$GLOBALS['cfg']['NavigationLinkWithMainPanel']) {
            
$syncImage 's_link';
            
$title __('Unlink from main panel');
        }
        
$retval .= Generator::getNavigationLink(
            
'#',
            
$showText,
            
$title,
            
$showIcon,
            
$syncImage,
            
'pma_navigation_sync'
        
);
        
$retval .= '</div>';
        
$retval .= '</li>';
        
$retval .= '<!-- CONTROLS ENDS -->';

        return 
$retval;
    }

    
/**
     * Generates the HTML code for displaying the list pagination
     *
     * @param Node $node The node for whose children the page
     *                   selector will be created
     */
    
private function getPageSelector(Node $node): string
    
{
        
$retval '';
        if (
$node === $this->tree) {
            
$retval .= Generator::getListNavigator(
                
$this->tree->getPresence('databases'$this->searchClause),
                
$this->pos,
                [
'server' => $GLOBALS['server']],
                
Url::getFromRoute('/navigation'),
                
'frame_navigation',
                
$GLOBALS['cfg']['FirstLevelNavigationItems'],
                
'pos',
                [
'dbselector']
            );
        } else {
            if (
$node->type == Node::CONTAINER && ! $node->isGroup) {
                
$paths $node->getPaths();

                
$level = isset($paths['aPath_clean'][4]) ? 2;
                
$urlParams = [
                    
'aPath'     => $paths['aPath'],
                    
'vPath'     => $paths['vPath'],
                    
'pos'       => $this->pos,
                    
'server'    => $GLOBALS['server'],
                    
'pos2_name' => $paths['aPath_clean'][2],
                ];
                if (
$level == 3) {
                    
$pos $node->pos3;
                    
$urlParams['pos2_value'] = $node->pos2;
                    
$urlParams['pos3_name'] = $paths['aPath_clean'][4];
                } else {
                    
$pos $node->pos2;
                }
                
/** @var Node $realParent */
                
$realParent $node->realParent();
                
$num $realParent->getPresence(
                    
$node->realName,
                    
$this->searchClause2
                
);
                
$retval .= Generator::getListNavigator(
                    
$num,
                    
$pos,
                    
$urlParams,
                    
Url::getFromRoute('/navigation'),
                    
'frame_navigation',
                    
$GLOBALS['cfg']['MaxNavigationItems'],
                    
'pos' $level '_value'
                
);
            }
        }

        return 
$retval;
    }

    
/**
     * Called by usort() for sorting the nodes in a container
     *
     * @param Node $a The first element used in the comparison
     * @param Node $b The second element used in the comparison
     *
     * @return int See strnatcmp() and strcmp()
     */
    
public static function sortNode(Node $aNode $b): int
    
{
        if (
$a->isNew) {
            return -
1;
        }

        if (
$b->isNew) {
            return 
1;
        }

        if (
$GLOBALS['cfg']['NaturalOrder']) {
            return 
strnatcasecmp($a->name$b->name);
        }

        return 
strcasecmp($a->name$b->name);
    }

    
/**
     * Display quick warp links, contain Recents and Favorites
     *
     * @return string HTML code
     */
    
private function quickWarp(): string
    
{
        
$retval '<div class="pma_quick_warp">';
        if (
$GLOBALS['cfg']['NumRecentTables'] > 0) {
            
$retval .= RecentFavoriteTable::getInstance('recent')
                ->
getHtml();
        }
        if (
$GLOBALS['cfg']['NumFavoriteTables'] > 0) {
            
$retval .= RecentFavoriteTable::getInstance('favorite')
                ->
getHtml();
        }
        
$retval .= '<div class="clearfloat"></div>';
        
$retval .= '</div>';

        return 
$retval;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by HackingTool | HackingTool | Generation time: 0.0064 ]--