Skip to content

Commit 4e4e2e5

Browse files
committed
Refactor NodeFactory::getInstance() to use class strings
Improves type inference. Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
1 parent 4d75658 commit 4e4e2e5

25 files changed

Lines changed: 141 additions & 282 deletions

libraries/classes/Navigation/NavigationTree.php

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,23 @@
1111
use PhpMyAdmin\DatabaseInterface;
1212
use PhpMyAdmin\Html\Generator;
1313
use PhpMyAdmin\Navigation\Nodes\Node;
14+
use PhpMyAdmin\Navigation\Nodes\NodeColumn;
15+
use PhpMyAdmin\Navigation\Nodes\NodeColumnContainer;
1416
use PhpMyAdmin\Navigation\Nodes\NodeDatabase;
17+
use PhpMyAdmin\Navigation\Nodes\NodeDatabaseContainer;
18+
use PhpMyAdmin\Navigation\Nodes\NodeEvent;
19+
use PhpMyAdmin\Navigation\Nodes\NodeEventContainer;
20+
use PhpMyAdmin\Navigation\Nodes\NodeFunction;
21+
use PhpMyAdmin\Navigation\Nodes\NodeFunctionContainer;
22+
use PhpMyAdmin\Navigation\Nodes\NodeIndex;
23+
use PhpMyAdmin\Navigation\Nodes\NodeIndexContainer;
24+
use PhpMyAdmin\Navigation\Nodes\NodeProcedure;
25+
use PhpMyAdmin\Navigation\Nodes\NodeProcedureContainer;
1526
use PhpMyAdmin\Navigation\Nodes\NodeTable;
1627
use PhpMyAdmin\Navigation\Nodes\NodeTableContainer;
28+
use PhpMyAdmin\Navigation\Nodes\NodeTrigger;
29+
use PhpMyAdmin\Navigation\Nodes\NodeTriggerContainer;
30+
use PhpMyAdmin\Navigation\Nodes\NodeView;
1731
use PhpMyAdmin\Navigation\Nodes\NodeViewContainer;
1832
use PhpMyAdmin\RecentFavoriteTable;
1933
use PhpMyAdmin\ResponseRenderer;
@@ -198,7 +212,7 @@ public function __construct($template, DatabaseInterface $dbi)
198212
}
199213

200214
// Initialize the tree by creating a root node
201-
$this->tree = NodeFactory::getInstance('NodeDatabaseContainer', 'root');
215+
$this->tree = NodeFactory::getInstance(NodeDatabaseContainer::class, 'root');
202216
if (! $GLOBALS['cfg']['NavigationTreeEnableGrouping'] || ! $GLOBALS['cfg']['ShowDatabasesNavigationAsTree']) {
203217
return;
204218
}
@@ -319,8 +333,7 @@ private function buildPath()
319333
$data = $this->tree->getData('databases', $this->pos, $this->searchClause);
320334
$hiddenCounts = $this->tree->getNavigationHidingData();
321335
foreach ($data as $db) {
322-
/** @var NodeDatabase $node */
323-
$node = NodeFactory::getInstance('NodeDatabase', $db);
336+
$node = NodeFactory::getInstance(NodeDatabase::class, $db);
324337
if (isset($hiddenCounts[$db])) {
325338
$node->setHiddenCount($hiddenCounts[$db]);
326339
}
@@ -395,19 +408,19 @@ private function buildPathPart(array $path, string $type2, int $pos2, string $ty
395408
foreach ($dbData as $item) {
396409
switch ($container->realName) {
397410
case 'events':
398-
$node = NodeFactory::getInstance('NodeEvent', $item);
411+
$node = NodeFactory::getInstance(NodeEvent::class, $item);
399412
break;
400413
case 'functions':
401-
$node = NodeFactory::getInstance('NodeFunction', $item);
414+
$node = NodeFactory::getInstance(NodeFunction::class, $item);
402415
break;
403416
case 'procedures':
404-
$node = NodeFactory::getInstance('NodeProcedure', $item);
417+
$node = NodeFactory::getInstance(NodeProcedure::class, $item);
405418
break;
406419
case 'tables':
407-
$node = NodeFactory::getInstance('NodeTable', $item);
420+
$node = NodeFactory::getInstance(NodeTable::class, $item);
408421
break;
409422
case 'views':
410-
$node = NodeFactory::getInstance('NodeView', $item);
423+
$node = NodeFactory::getInstance(NodeView::class, $item);
411424
break;
412425
default:
413426
break;
@@ -441,7 +454,7 @@ private function buildPathPart(array $path, string $type2, int $pos2, string $ty
441454
return false;
442455
}
443456

444-
$node = NodeFactory::getInstance('NodeTable', $path[0]);
457+
$node = NodeFactory::getInstance(NodeTable::class, $path[0]);
445458
if ($type2 == $container->realName) {
446459
$node->pos2 = $pos2;
447460
}
@@ -468,13 +481,13 @@ private function buildPathPart(array $path, string $type2, int $pos2, string $ty
468481
foreach ($tableData as $item) {
469482
switch ($container->realName) {
470483
case 'indexes':
471-
$node = NodeFactory::getInstance('NodeIndex', $item);
484+
$node = NodeFactory::getInstance(NodeIndex::class, $item);
472485
break;
473486
case 'columns':
474-
$node = NodeFactory::getInstance('NodeColumn', $item);
487+
$node = NodeFactory::getInstance(NodeColumn::class, $item);
475488
break;
476489
case 'triggers':
477-
$node = NodeFactory::getInstance('NodeTrigger', $item);
490+
$node = NodeFactory::getInstance(NodeTrigger::class, $item);
478491
break;
479492
default:
480493
break;
@@ -517,15 +530,15 @@ private function addTableContainers(NodeTable $table, int $pos2, string $type3,
517530
$retval = [];
518531
if (! $table->hasChildren()) {
519532
if ($table->getPresence('columns')) {
520-
$retval['columns'] = NodeFactory::getInstance('NodeColumnContainer');
533+
$retval['columns'] = NodeFactory::getInstance(NodeColumnContainer::class);
521534
}
522535

523536
if ($table->getPresence('indexes')) {
524-
$retval['indexes'] = NodeFactory::getInstance('NodeIndexContainer');
537+
$retval['indexes'] = NodeFactory::getInstance(NodeIndexContainer::class);
525538
}
526539

527540
if ($table->getPresence('triggers')) {
528-
$retval['triggers'] = NodeFactory::getInstance('NodeTriggerContainer');
541+
$retval['triggers'] = NodeFactory::getInstance(NodeTriggerContainer::class);
529542
}
530543

531544
// Add all new Nodes to the tree
@@ -592,23 +605,23 @@ private function addDbContainers(NodeDatabase $db, string $type, int $pos2): arr
592605
$retval = [];
593606
if (! $db->hasChildren()) {
594607
if (! in_array('tables', $hidden) && $db->getPresence('tables')) {
595-
$retval['tables'] = NodeFactory::getInstance('NodeTableContainer');
608+
$retval['tables'] = NodeFactory::getInstance(NodeTableContainer::class);
596609
}
597610

598611
if (! in_array('views', $hidden) && $db->getPresence('views')) {
599-
$retval['views'] = NodeFactory::getInstance('NodeViewContainer');
612+
$retval['views'] = NodeFactory::getInstance(NodeViewContainer::class);
600613
}
601614

602615
if (! in_array('functions', $hidden) && $db->getPresence('functions')) {
603-
$retval['functions'] = NodeFactory::getInstance('NodeFunctionContainer');
616+
$retval['functions'] = NodeFactory::getInstance(NodeFunctionContainer::class);
604617
}
605618

606619
if (! in_array('procedures', $hidden) && $db->getPresence('procedures')) {
607-
$retval['procedures'] = NodeFactory::getInstance('NodeProcedureContainer');
620+
$retval['procedures'] = NodeFactory::getInstance(NodeProcedureContainer::class);
608621
}
609622

610623
if (! in_array('events', $hidden) && $db->getPresence('events')) {
611-
$retval['events'] = NodeFactory::getInstance('NodeEventContainer');
624+
$retval['events'] = NodeFactory::getInstance(NodeEventContainer::class);
612625
}
613626

614627
// Add all new Nodes to the tree
@@ -768,12 +781,8 @@ public function groupNode($node): void
768781
continue;
769782
}
770783

771-
$class = get_class($child);
772-
$className = substr($class, strrpos($class, '\\') + 1);
773-
unset($class);
774-
/** @var NodeDatabase $newChild */
775784
$newChild = NodeFactory::getInstance(
776-
$className,
785+
get_class($child),
777786
mb_substr(
778787
$child->name,
779788
$keySeparatorLength

libraries/classes/Navigation/NodeFactory.php

Lines changed: 9 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -9,97 +9,30 @@
99

1010
use PhpMyAdmin\Navigation\Nodes\Node;
1111

12-
use function __;
13-
use function class_exists;
14-
use function preg_match;
15-
use function sprintf;
16-
use function trigger_error;
17-
18-
use const E_USER_ERROR;
19-
2012
/**
2113
* Node factory - instantiates Node objects or objects derived from the Node class
2214
*/
2315
class NodeFactory
2416
{
25-
/** @var string */
26-
protected static $namespace = 'PhpMyAdmin\\Navigation\\Nodes\\%s';
27-
2817
/**
29-
* Sanitizes the name of a Node class
18+
* Instantiates a Node object
3019
*
31-
* @param string $class The class name to be sanitized
20+
* @param class-string<T> $class The name of the class to instantiate
21+
* @param string|mixed[] $name An identifier for the new node
22+
* @param int $type Type of node, may be one of CONTAINER or OBJECT
23+
* @param bool $isGroup Whether this object has been created while grouping nodes
3224
*
33-
* @return string
34-
* @psalm-return class-string
35-
*/
36-
private static function sanitizeClass($class)
37-
{
38-
if (! preg_match('@^Node\w*$@', $class)) {
39-
$class = 'Node';
40-
trigger_error(
41-
sprintf(
42-
/* l10n: The word "Node" must not be translated here */
43-
__('Invalid class name "%1$s", using default of "Node"'),
44-
$class
45-
),
46-
E_USER_ERROR
47-
);
48-
}
49-
50-
return self::checkClass($class);
51-
}
52-
53-
/**
54-
* Checks if a class exists and try to load it.
55-
* Will return the default class name back if the
56-
* file for some subclass is not available
25+
* @return T
5726
*
58-
* @param string $class The class name to check
59-
*
60-
* @return string
61-
* @psalm-return class-string
62-
*/
63-
private static function checkClass($class)
64-
{
65-
/** @var class-string $class */
66-
$class = sprintf(self::$namespace, $class);
67-
68-
if (! class_exists($class)) {
69-
/** @var class-string $class */
70-
$class = sprintf(self::$namespace, 'Node');
71-
trigger_error(
72-
sprintf(
73-
__('Could not load class "%1$s"'),
74-
$class
75-
),
76-
E_USER_ERROR
77-
);
78-
}
79-
80-
return $class;
81-
}
82-
83-
/**
84-
* Instantiates a Node object
85-
*
86-
* @param string $class The name of the class to instantiate
87-
* @param string|array $name An identifier for the new node
88-
* @param int $type Type of node, may be one of CONTAINER or OBJECT
89-
* @param bool $isGroup Whether this object has been created while grouping nodes
27+
* @template T of Node
9028
*/
9129
public static function getInstance(
92-
$class = 'Node',
30+
string $class,
9331
$name = 'default',
9432
$type = Node::OBJECT,
9533
$isGroup = false
9634
): Node {
97-
$class = self::sanitizeClass($class);
98-
99-
/** @var Node $node */
100-
$node = new $class($name, $type, $isGroup);
101-
102-
return $node;
35+
return new $class($name, $type, $isGroup);
10336
}
10437

10538
/**

phpstan-baseline.neon

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5685,6 +5685,11 @@ parameters:
56855685
count: 2
56865686
path: libraries/classes/Navigation/NavigationTree.php
56875687

5688+
-
5689+
message: "#^Call to an undefined method PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\:\\:setHiddenCount\\(\\)\\.$#"
5690+
count: 1
5691+
path: libraries/classes/Navigation/NavigationTree.php
5692+
56885693
-
56895694
message: "#^Cannot access property \\$pos2 on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|null\\.$#"
56905695
count: 1
@@ -5727,7 +5732,7 @@ parameters:
57275732

57285733
-
57295734
message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#"
5730-
count: 2
5735+
count: 1
57315736
path: libraries/classes/Navigation/NavigationTree.php
57325737

57335738
-
@@ -5765,11 +5770,6 @@ parameters:
57655770
count: 1
57665771
path: libraries/classes/Navigation/NavigationTree.php
57675772

5768-
-
5769-
message: "#^Method PhpMyAdmin\\\\Navigation\\\\NodeFactory\\:\\:getInstance\\(\\) has parameter \\$name with no value type specified in iterable type array\\.$#"
5770-
count: 1
5771-
path: libraries/classes/Navigation/NodeFactory.php
5772-
57735773
-
57745774
message: "#^Cannot access property \\$children on PhpMyAdmin\\\\Navigation\\\\Nodes\\\\Node\\|null\\.$#"
57755775
count: 1

0 commit comments

Comments
 (0)