Fix all found errors and add typehints if possible on NavigationTree class

Signed-off-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
William Desportes 2020-06-02 23:36:47 +02:00
parent 62baf0b8ea
commit 7623fed14a
No known key found for this signature in database
GPG Key ID: 90A0EF1B8251A889
5 changed files with 93 additions and 168 deletions

View File

@ -31,6 +31,7 @@ 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;
@ -76,24 +77,24 @@ class NavigationTree
*/
private $pos;
/**
* @var array 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.
* @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 array The positions of nodes in the lists of tables, views,
* @var int[] The positions of nodes in the lists of tables, views,
* routines or events used for pagination
*/
private $pos2Value = [];
/**
* @var array 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
* @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 array The positions of nodes in the lists of columns or indexes
* @var int[] The positions of nodes in the lists of columns or indexes
* used for pagination
*/
private $pos3Value = [];
@ -125,7 +126,7 @@ class NavigationTree
* @param Template $template Template instance
* @param DatabaseInterface $dbi DatabaseInterface instance
*/
public function __construct($template, $dbi)
public function __construct($template, DatabaseInterface $dbi)
{
$this->template = $template;
$this->dbi = $dbi;
@ -160,11 +161,11 @@ class NavigationTree
);
$index = 'n' . $count . '_pos2_';
$this->pos2Name[$count] = $_POST[$index . 'name'];
$this->pos2Value[$count] = $_POST[$index . 'value'];
$this->pos2Value[$count] = (int) $_POST[$index . 'value'];
$index = 'n' . $count . '_pos3_';
if (isset($_POST[$index])) {
$this->pos3Name[$count] = $_POST[$index . 'name'];
$this->pos3Value[$count] = $_POST[$index . 'value'];
$this->pos3Value[$count] = (int) $_POST[$index . 'value'];
}
$count++;
}
@ -207,7 +208,7 @@ class NavigationTree
*
* @return int
*/
private function getNavigationDbPos()
private function getNavigationDbPos(): int
{
$retval = 0;
@ -231,7 +232,7 @@ class NavigationTree
$query .= " WHERE `SCHEMA_NAME` < '%s' ";
$query .= ') t ';
return $this->dbi->fetchValue(
return (int) $this->dbi->fetchValue(
sprintf(
$query,
(int) $GLOBALS['cfg']['FirstLevelNavigationItems'],
@ -304,7 +305,7 @@ class NavigationTree
*
* @return array
*/
private function parsePath($string)
private function parsePath($string): array
{
$path = explode('.', $string);
foreach ($path as $key => $value) {
@ -317,7 +318,7 @@ class NavigationTree
/**
* Generates the tree structure so that it can be rendered later
*
* @return Node|false The active node or false in case of failure
* @return Node|bool The active node or false in case of failure, or true: (@see buildPathPart())
*/
private function buildPath()
{
@ -344,10 +345,10 @@ class NavigationTree
foreach ($this->aPath as $key => $path) {
$retval = $this->buildPathPart(
$path,
$this->pos2Name[$key],
$this->pos2Value[$key],
$this->pos2Name[$key] ?? '',
$this->pos2Value[$key] ?? 0,
$this->pos3Name[$key] ?? '',
$this->pos3Value[$key] ?? ''
$this->pos3Value[$key] ?? 0
);
}
@ -357,20 +358,20 @@ class NavigationTree
/**
* 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
* @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|null $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|null $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 $path, $type2, $pos2, $type3, $pos3)
private function buildPathPart(array $path, string $type2, ?int $pos2, string $type3, ?int $pos3)
{
if (empty($pos2)) {
$pos2 = 0;
@ -379,20 +380,20 @@ class NavigationTree
$pos3 = 0;
}
$retval = true;
if (count($path) <= 1) {
return $retval;
return true;
}
array_shift($path); // remove 'root'
/** @var NodeDatabase|null $db */
$db = $this->tree->getChild($path[0]);
$retval = $db;
if ($db === null) {
return false;
}
$retval = $db;
$containers = $this->addDbContainers($db, $type2, $pos2);
array_shift($path); // remove db
@ -473,7 +474,7 @@ class NavigationTree
return $retval;
}
/** @var NodeTable $table */
/** @var NodeTable|null $table */
$table = $container->getChild($path[0], true);
if ($table === null) {
if (! $db->getPresence('tables', $path[0])) {
@ -490,7 +491,7 @@ class NavigationTree
$container->addChild($node);
$table = $container->getChild($path[0], true);
}
$retval = $table === null ? false : $table;
$retval = $table ?? false;
$containers = $this->addTableContainers(
$table,
$pos2,
@ -505,7 +506,7 @@ class NavigationTree
}
$container = $table->getChild($path[0], true);
$retval = $container === null ? false : $container;
$retval = $container ?? false;
$tableData = $table->getData(
$container->realName,
$pos3
@ -564,7 +565,7 @@ class NavigationTree
*
* @return array An array of new nodes
*/
private function addTableContainers($table, $pos2, $type3, $pos3)
private function addTableContainers(NodeTable $table, int $pos2, string $type3, int $pos3): array
{
$retval = [];
if ($table->hasChildren(true) == 0) {
@ -618,7 +619,7 @@ class NavigationTree
*
* @return array An array of new nodes
*/
private function addDbContainers($db, $type, $pos2)
private function addDbContainers(NodeDatabase $db, string $type, int $pos2): array
{
// Get items to hide
$hidden = $db->getHiddenItems('group');
@ -720,7 +721,7 @@ class NavigationTree
*
* @return void
*/
public function groupNode($node)
public function groupNode($node): void
{
if ($node->type != Node::CONTAINER
|| ! $GLOBALS['cfg']['NavigationTreeEnableExpansion']
@ -895,7 +896,7 @@ class NavigationTree
*
* @return string HTML code for the navigation tree
*/
public function renderState()
public function renderState(): string
{
$this->buildPath();
@ -945,7 +946,7 @@ class NavigationTree
public function renderPath()
{
$node = $this->buildPath();
if ($node !== false) {
if (! is_bool($node)) {
$this->groupTree();
$listContent = $this->fastFilterHtml($node);
@ -970,7 +971,8 @@ class NavigationTree
}
}
if (! empty($this->searchClause) || ! empty($this->searchClause2)) {
$hasSearchClause = ! empty($this->searchClause) || ! empty($this->searchClause2);
if ($hasSearchClause && ! is_bool($node)) {
$results = 0;
if (! empty($this->searchClause2)) {
if (is_object($node->realParent())) {
@ -1049,7 +1051,7 @@ class NavigationTree
*
* @return bool
*/
private function findTreeMatch(array $tree, array $paths)
private function findTreeMatch(array $tree, array $paths): bool
{
$match = false;
foreach ($tree as $path) {
@ -1072,20 +1074,22 @@ class NavigationTree
* Renders a single node or a branch of the tree
*
* @param Node $node The node to render
* @param bool $recursive Bool: Whether to render a single node or a branch
* @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, $recursive, $class = '')
private function renderNode(Node $node, bool $recursive, string $class = ''): string
{
$retval = '';
$paths = $node->getPaths();
$nodeIsContainer = $node->type === Node::CONTAINER;
if ($node->hasSiblings()
|| $node->realParent() === false
) {
$response = Response::getInstance();
if ($node->type == Node::CONTAINER
if ($nodeIsContainer
&& count($node->children) === 0
&& ! $response->isAjax()
) {
@ -1170,7 +1174,7 @@ class NavigationTree
$linkClass = ' ajax';
}
if ($node->type == Node::CONTAINER) {
if ($nodeIsContainer) {
$retval .= '<i>';
}
@ -1180,18 +1184,19 @@ class NavigationTree
$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) {
$divClass = 'double';
}
}
$retval .= "<div class='block second" . $divClass . "'>";
$retval .= '<div class="block second' . $divClass . '">';
if (isset($node->links['icon']) && ! empty($node->links['icon'])) {
$args = [];
@ -1220,7 +1225,7 @@ class NavigationTree
}
$link = vsprintf($node->links['text'], $args);
$title = $node->links['title'] ?? $node->title ?? '';
if ($node->type == Node::CONTAINER) {
if ($nodeIsContainer) {
$retval .= "&nbsp;<a class='hover_show_full' href='" . $link . "'>";
$retval .= htmlspecialchars($node->name);
$retval .= '</a>';
@ -1234,7 +1239,7 @@ class NavigationTree
$retval .= '&nbsp;' . $node->name . '';
}
$retval .= $node->getHtmlForControlButtons();
if ($node->type == Node::CONTAINER) {
if ($nodeIsContainer) {
$retval .= '</i>';
}
$retval .= '<div class="clearfloat"></div>';
@ -1294,7 +1299,7 @@ class NavigationTree
*
* @return string HTML code
*/
public function renderDbSelect()
public function renderDbSelect(): string
{
$this->buildPath();
@ -1397,7 +1402,7 @@ class NavigationTree
*
* @return string LI element used for the fast filter
*/
private function fastFilterHtml($node): string
private function fastFilterHtml(Node $node): string
{
$retval = '';
$filterDbMin
@ -1423,14 +1428,17 @@ class NavigationTree
return $retval;
}
if (($node->type == Node::CONTAINER
&& ($node->realName == 'tables'
|| $node->realName == 'views'
|| $node->realName == 'functions'
|| $node->realName == 'procedures'
|| $node->realName == 'events'))
&& method_exists($node->realParent(), 'getPresence')
&& $node->realParent()->getPresence($node->realName) >= $filterItemMin
$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 = [
@ -1540,11 +1548,12 @@ class NavigationTree
} else {
$pos = $node->pos2;
}
$num = $node->realParent()
->getPresence(
$node->realName,
$this->searchClause2
);
/** @var Node $realParent */
$realParent = $node->realParent();
$num = $realParent->getPresence(
$node->realName,
$this->searchClause2
);
$retval .= Generator::getListNavigator(
$num,
$pos,
@ -1590,7 +1599,7 @@ class NavigationTree
*
* @return string HTML code
*/
private function quickWarp()
private function quickWarp(): string
{
$retval = '<div class="pma_quick_warp">';
if ($GLOBALS['cfg']['NumRecentTables'] > 0) {

View File

@ -74,7 +74,7 @@ class Node
* Only relevant if the node is of type CONTAINER
*/
public $separatorDepth = 1;
/** @var string|array An IMG tag, used when rendering the node, an array for NodeTabl */
/** @var string An IMG tag, used when rendering the node*/
public $icon;
/**
* @var array An array of A tags, used when rendering the node

View File

@ -19,6 +19,9 @@ use function strpos;
*/
class NodeTable extends NodeDatabaseChild
{
/** @var array IMG tags, used when rendering the node */
public $icon;
/**
* Initialises the class
*
@ -43,7 +46,7 @@ class NodeTable extends NodeDatabaseChild
'table'
)
);
$title = Util::getTitleForTarget(
$title = (string) Util::getTitleForTarget(
$GLOBALS['cfg']['DefaultTabTable']
);
$this->title = $title;

View File

@ -1930,66 +1930,6 @@ parameters:
count: 1
path: libraries/classes/Navigation/Navigation.php
-
message: "#^Method PhpMyAdmin\\\\Navigation\\\\NavigationTree\\:\\:buildPath\\(\\) should return PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false but returns bool\\|PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Strict comparison using \\=\\=\\= between PhpMyAdmin\\\\Navigation\\\\Nodes\\\\NodeDatabase and false will always evaluate to false\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Strict comparison using \\=\\=\\= between PhpMyAdmin\\\\Navigation\\\\Nodes\\\\NodeTable and false will always evaluate to false\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Cannot access property \\$realName on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 4
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Cannot access property \\$parent on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Cannot call method addChild\\(\\) on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Cannot call method realParent\\(\\) on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 2
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\|string given\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Argument of an invalid type array\\|string supplied for foreach, only iterables are supported\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Binary operation \"\\.\" between '\\<u\\>' and array\\|string results in an error\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Parameter \\#1 \\$object of function method_exists expects object\\|string, PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false given\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Cannot call method getPresence\\(\\) on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 1
path: libraries/classes/Navigation/NavigationTree.php
-
message: "#^Property PhpMyAdmin\\\\Navigation\\\\NodeFactory\\:\\:\\$namespace has no typehint specified\\.$#"
count: 1
@ -2005,21 +1945,11 @@ parameters:
count: 1
path: libraries/classes/Navigation/Nodes/NodeDatabaseChild.php
-
message: "#^Property PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\:\\:\\$title \\(string\\) does not accept bool\\|string\\.$#"
count: 1
path: libraries/classes/Navigation/Nodes/NodeTable.php
-
message: "#^Cannot access property \\$realName on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|false\\.$#"
count: 2
path: libraries/classes/Navigation/Nodes/NodeTable.php
-
message: "#^Cannot assign new offset to array\\|string\\.$#"
count: 5
path: libraries/classes/Navigation/Nodes/NodeTable.php
-
message: "#^Parameter \\#2 \\$haystack of function in_array expects array, array\\|string given\\.$#"
count: 1

View File

@ -808,6 +808,9 @@
<code>$row['Engine']</code>
<code>$row['Data_free']</code>
</PossiblyInvalidArrayAccess>
<PossiblyInvalidArrayOffset occurrences="1">
<code>$row[$value]</code>
</PossiblyInvalidArrayOffset>
</file>
<file src="libraries/classes/Dbal/DbiMysqli.php">
<ImplementedReturnTypeMismatch occurrences="5">
@ -1450,29 +1453,10 @@
</InvalidArgument>
</file>
<file src="libraries/classes/Navigation/NavigationTree.php">
<InvalidReturnStatement occurrences="1">
<code>$retval</code>
</InvalidReturnStatement>
<InvalidReturnType occurrences="1">
<code>Node|false</code>
</InvalidReturnType>
<InvalidScalarArgument occurrences="1">
<code>$this-&gt;pos3Value[$key] ?? ''</code>
</InvalidScalarArgument>
<PossiblyFalseArgument occurrences="2">
<code>$table</code>
<code>$node-&gt;realParent()</code>
</PossiblyFalseArgument>
<PossiblyFalseOperand occurrences="1">
<code>strrpos($class, '\\')</code>
</PossiblyFalseOperand>
<PossiblyFalseReference occurrences="7">
<code>getChild</code>
<code>getData</code>
<code>addChild</code>
<code>realParent</code>
<code>getPresence</code>
<code>getPresence</code>
<PossiblyFalseReference occurrences="1">
<code>getPresence</code>
</PossiblyFalseReference>
<PossiblyInvalidArgument occurrences="1">
@ -1481,16 +1465,18 @@
<PossiblyInvalidIterator occurrences="1">
<code>$icons</code>
</PossiblyInvalidIterator>
<PossiblyInvalidOperand occurrences="1">
<code>$node-&gt;icon</code>
</PossiblyInvalidOperand>
<PossiblyInvalidPropertyFetch occurrences="2">
<PossiblyNullArgument occurrences="3">
<code>$table</code>
<code>$container-&gt;realName</code>
<code>$container-&gt;parent</code>
</PossiblyInvalidPropertyFetch>
<PossiblyNullArgument occurrences="1">
<code>$title</code>
</PossiblyNullArgument>
<PossiblyNullPropertyFetch occurrences="2">
<code>$container-&gt;realName</code>
<code>$container-&gt;parent</code>
</PossiblyNullPropertyFetch>
<PossiblyNullReference occurrences="1">
<code>addChild</code>
</PossiblyNullReference>
<TypeDoesNotContainType occurrences="2">
<code>(int) $_REQUEST['pos2_value']</code>
<code>(int) $_REQUEST['pos3_value']</code>
@ -1510,9 +1496,6 @@
</PossiblyInvalidPropertyFetch>
</file>
<file src="libraries/classes/Navigation/Nodes/NodeTable.php">
<PossiblyInvalidPropertyAssignmentValue occurrences="1">
<code>$title</code>
</PossiblyInvalidPropertyAssignmentValue>
<PossiblyInvalidPropertyFetch occurrences="2">
<code>$this-&gt;realParent()-&gt;realName</code>
<code>$this-&gt;realParent()-&gt;realName</code>