diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c97f601954..c4a05ac23a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2537,7 +2537,7 @@ parameters: - message: "#^Cannot access offset 'db' on mixed\\.$#" - count: 2 + count: 1 path: src/Controllers/Database/Structure/FavoriteTableController.php - @@ -2547,7 +2547,7 @@ parameters: - message: "#^Cannot access offset 'table' on mixed\\.$#" - count: 2 + count: 1 path: src/Controllers/Database/Structure/FavoriteTableController.php - @@ -2560,21 +2560,6 @@ parameters: count: 1 path: src/Controllers/Database/Structure/FavoriteTableController.php - - - message: "#^Parameter \\#1 \\$currentTable of method PhpMyAdmin\\\\Controllers\\\\Database\\\\Structure\\\\FavoriteTableController\\:\\:checkFavoriteTable\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - - - message: "#^Parameter \\#1 \\$db of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:add\\(\\) expects string, mixed given\\.$#" - count: 2 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - - - message: "#^Parameter \\#1 \\$db of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:remove\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, mixed given\\.$#" count: 1 @@ -2585,21 +2570,6 @@ parameters: count: 1 path: src/Controllers/Database/Structure/FavoriteTableController.php - - - message: "#^Parameter \\#1 \\$string of function md5 expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:add\\(\\) expects string, mixed given\\.$#" - count: 2 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:remove\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Database/Structure/FavoriteTableController.php - - message: "#^Parameter \\#3 \\$favoriteTables of method PhpMyAdmin\\\\Controllers\\\\Database\\\\Structure\\\\FavoriteTableController\\:\\:synchronizeFavoriteTables\\(\\) expects array, mixed given\\.$#" count: 1 @@ -2735,16 +2705,6 @@ parameters: count: 1 path: src/Controllers/Database/StructureController.php - - - message: "#^Cannot access offset 'db' on mixed\\.$#" - count: 1 - path: src/Controllers/Database/StructureController.php - - - - message: "#^Cannot access offset 'table' on mixed\\.$#" - count: 1 - path: src/Controllers/Database/StructureController.php - - message: "#^Only booleans are allowed in &&, int\\|false given on the right side\\.$#" count: 1 @@ -2795,11 +2755,6 @@ parameters: count: 1 path: src/Controllers/Database/StructureController.php - - - message: "#^Parameter \\#1 \\$currentTable of method PhpMyAdmin\\\\Controllers\\\\Database\\\\StructureController\\:\\:checkFavoriteTable\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Database/StructureController.php - - message: "#^Parameter \\#1 \\$currentTable of method PhpMyAdmin\\\\Controllers\\\\Database\\\\StructureController\\:\\:getStuffForEngineTypeTable\\(\\) expects array, mixed given\\.$#" count: 1 @@ -10280,6 +10235,61 @@ parameters: count: 1 path: src/Export/Template.php + - + message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Call to function in_array\\(\\) requires parameter \\#3 to be true\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot access an offset on mixed\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot access offset 'favoriteTables'\\|'recentTables' on mixed\\.$#" + count: 5 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot access offset 'favorites_synced' on mixed\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot access offset mixed on mixed\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot access offset string on mixed\\.$#" + count: 5 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Cannot cast mixed to string\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Method PhpMyAdmin\\\\Favorites\\\\RecentFavoriteTables\\:\\:getFromDb\\(\\) should return array\\ but returns mixed\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Parameter \\#1 \\$array of static method PhpMyAdmin\\\\Favorites\\\\RecentFavoriteTable\\:\\:fromArray\\(\\) expects array\\{db\\: string, table\\: string\\}, mixed given\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + + - + message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, string\\|false given\\.$#" + count: 1 + path: src/Favorites/RecentFavoriteTables.php + - message: "#^Cannot access offset 'multi_edit' on mixed\\.$#" count: 7 @@ -10895,11 +10905,6 @@ parameters: count: 1 path: src/Header.php - - - message: "#^Parameter \\#1 \\$db of method PhpMyAdmin\\\\Header\\:\\:addRecentTable\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Header.php - - message: "#^Parameter \\#1 \\$message of static method PhpMyAdmin\\\\Html\\\\Generator\\:\\:getMessage\\(\\) expects PhpMyAdmin\\\\Message\\|string, mixed given\\.$#" count: 1 @@ -10910,11 +10915,6 @@ parameters: count: 1 path: src/Header.php - - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\Header\\:\\:addRecentTable\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Header.php - - message: "#^Parameter \\#3 \\$db of class PhpMyAdmin\\\\Menu constructor expects string, mixed given\\.$#" count: 1 @@ -16035,86 +16035,6 @@ parameters: count: 4 path: src/Query/Utilities.php - - - message: "#^Cannot access offset 'db' on mixed\\.$#" - count: 6 - path: src/RecentFavoriteTable.php - - - - message: "#^Cannot access offset 'favoriteTables'\\|'recentTables' on mixed\\.$#" - count: 3 - path: src/RecentFavoriteTable.php - - - - message: "#^Cannot access offset 'favorites_synced' on mixed\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Cannot access offset 'table' on mixed\\.$#" - count: 6 - path: src/RecentFavoriteTable.php - - - - message: "#^Cannot access offset mixed on mixed\\.$#" - count: 3 - path: src/RecentFavoriteTable.php - - - - message: "#^Method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:getFromDb\\(\\) should return array but returns mixed\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Only booleans are allowed in a negated boolean, PhpMyAdmin\\\\Dbal\\\\ResultInterface\\|false given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Only booleans are allowed in a ternary operator condition, string\\|null given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Only booleans are allowed in an if condition, PhpMyAdmin\\\\Dbal\\\\ResultInterface\\|false given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Only booleans are allowed in an if condition, string\\|null given\\.$#" - count: 2 - path: src/RecentFavoriteTable.php - - - - message: "#^Parameter \\#1 \\$database of method PhpMyAdmin\\\\DatabaseInterface\\:\\:getColumns\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Parameter \\#1 \\$db of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:remove\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\DatabaseInterface\\:\\:getColumns\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\RecentFavoriteTable\\:\\:remove\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - - - message: "#^Property PhpMyAdmin\\\\RecentFavoriteTable\\:\\:\\$tables \\(array\\) does not accept mixed\\.$#" - count: 1 - path: src/RecentFavoriteTable.php - - message: "#^Cannot access offset 'File' on mixed\\.$#" count: 1 @@ -19340,16 +19260,6 @@ parameters: count: 1 path: tests/classes/Controllers/Database/PrivilegesControllerTest.php - - - message: "#^Cannot access offset 'favoriteTables' on mixed\\.$#" - count: 1 - path: tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php - - - - message: "#^Parameter \\#2 \\$array of method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) expects array\\|ArrayAccess, mixed given\\.$#" - count: 1 - path: tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php - - message: "#^Cannot access offset 'COUNTED' on mixed\\.$#" count: 4 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index c34a41db77..5568549efb 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1493,16 +1493,11 @@ - $favoriteTable $favoriteTables $favoriteTables - - - - @@ -1512,11 +1507,9 @@ - $favoriteTable $favoriteTables $favoriteTables $value - $value @@ -1612,7 +1605,6 @@ - $dbTable $overheadSize @@ -1647,8 +1639,6 @@ - - @@ -1671,7 +1661,6 @@ $truename $updateTime $updateTimeAll - $value getCharset @@ -5925,6 +5914,45 @@ + + + Config::getInstance() + Config::getInstance() + Config::getInstance() + DatabaseInterface::getInstance() + + + $table + + + tableType->value . 'Tables']]]> + tableType->value . 'Tables'][$this->serverId]]]> + + + tableType->value . 'Tables']]]> + tableType->value . 'Tables']]]> + tableType->value . 'Tables']]]> + tableType->value . 'Tables'][$this->serverId]]]> + tableType->value . 'Tables'][$this->serverId]]]> + tableType->value . 'Tables'][$this->serverId]]]> + + + $table + + + array{db:string, table:string}[] + + + json_decode($value, true) + + + getPmaTable()]]> + getPmaTable()]]> + + + bool|Message + + Config::getInstance() @@ -10548,76 +10576,6 @@ - - - Config::getInstance() - Config::getInstance() - Config::getInstance() - DatabaseInterface::getInstance() - DatabaseInterface::getInstance() - DatabaseInterface::getInstance() - DatabaseInterface::getInstance() - DatabaseInterface::getInstance() - - - - - - - - - tableType . 'Tables']]]> - tableType . 'Tables'][$serverId]]]> - - - - - - - - - - - - - - - - - - - tableType . 'Tables']]]> - tableType . 'Tables'][$serverId]]]> - - - $table - $table - $tbl - tables]]> - $value - - - mixed[] - - - - - - - json_decode($value, true) - - - getPmaTable()]]> - getPmaTable()]]> - - - bool - bool|Message - - - tables =& $_SESSION['tmpval'][$this->tableType . 'Tables'][$serverId]]]> - - @@ -13227,17 +13185,6 @@ Config::getInstance() - - - $json - - - - - - $json - - Config::getInstance() diff --git a/src/Controllers/Database/DesignerController.php b/src/Controllers/Database/DesignerController.php index da1a2cfe87..6584833c91 100644 --- a/src/Controllers/Database/DesignerController.php +++ b/src/Controllers/Database/DesignerController.php @@ -159,7 +159,7 @@ class DesignerController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/EventsController.php b/src/Controllers/Database/EventsController.php index 3f7abf0674..4017618d7d 100644 --- a/src/Controllers/Database/EventsController.php +++ b/src/Controllers/Database/EventsController.php @@ -57,7 +57,7 @@ final class EventsController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; diff --git a/src/Controllers/Database/ExportController.php b/src/Controllers/Database/ExportController.php index bda3b1e2f0..15e63b7135 100644 --- a/src/Controllers/Database/ExportController.php +++ b/src/Controllers/Database/ExportController.php @@ -61,7 +61,7 @@ final class ExportController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/ImportController.php b/src/Controllers/Database/ImportController.php index 92c4b41a02..1b016a1b25 100644 --- a/src/Controllers/Database/ImportController.php +++ b/src/Controllers/Database/ImportController.php @@ -59,7 +59,7 @@ final class ImportController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/RoutinesController.php b/src/Controllers/Database/RoutinesController.php index 80048b1fcb..4768b29042 100644 --- a/src/Controllers/Database/RoutinesController.php +++ b/src/Controllers/Database/RoutinesController.php @@ -77,7 +77,7 @@ class RoutinesController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; @@ -103,7 +103,7 @@ class RoutinesController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; diff --git a/src/Controllers/Database/SearchController.php b/src/Controllers/Database/SearchController.php index 51d534171e..21ee4746b2 100644 --- a/src/Controllers/Database/SearchController.php +++ b/src/Controllers/Database/SearchController.php @@ -47,7 +47,7 @@ class SearchController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/SqlController.php b/src/Controllers/Database/SqlController.php index b2a3da72bb..997c9dc726 100644 --- a/src/Controllers/Database/SqlController.php +++ b/src/Controllers/Database/SqlController.php @@ -58,7 +58,7 @@ class SqlController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/Structure/FavoriteTableController.php b/src/Controllers/Database/Structure/FavoriteTableController.php index c08e5fcd25..ffa375f7b6 100644 --- a/src/Controllers/Database/Structure/FavoriteTableController.php +++ b/src/Controllers/Database/Structure/FavoriteTableController.php @@ -8,16 +8,20 @@ use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\AbstractController; use PhpMyAdmin\DbTableExists; +use PhpMyAdmin\Favorites\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; +use PhpMyAdmin\Identifiers\TableName; use PhpMyAdmin\Message; -use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Template; use PhpMyAdmin\Url; use PhpMyAdmin\Util; use function __; +use function array_map; use function count; use function json_decode; use function json_encode; @@ -51,7 +55,7 @@ final class FavoriteTableController extends AbstractController return; } - $favoriteInstance = RecentFavoriteTable::getInstance('favorite'); + $favoriteInstance = RecentFavoriteTables::getInstance(TableType::Favorite); $favoriteTables = $request->getParam('favoriteTables'); $favoriteTables = $favoriteTables !== null ? json_decode($favoriteTables, true) : []; @@ -74,7 +78,7 @@ final class FavoriteTableController extends AbstractController } $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); @@ -82,13 +86,19 @@ final class FavoriteTableController extends AbstractController } $changes = true; - $favoriteTable = $request->getParam('favorite_table', ''); - $alreadyFavorite = $this->checkFavoriteTable($favoriteTable); + /** @var string $favoriteTableName */ + $favoriteTableName = $request->getParam('favorite_table', ''); + // TODO: Why is this $GLOBALS['db'] instead of $databaseName + $favoriteTable = new RecentFavoriteTable( + DatabaseName::from($GLOBALS['db']), + TableName::from($favoriteTableName), + ); + $alreadyFavorite = $favoriteInstance->contains($favoriteTable); if (isset($_REQUEST['remove_favorite'])) { if ($alreadyFavorite) { // If already in favorite list, remove it. - $favoriteInstance->remove($GLOBALS['db'], $favoriteTable); + $favoriteInstance->remove($favoriteTable); $alreadyFavorite = false; // for favorite_anchor template } } elseif (isset($_REQUEST['add_favorite'])) { @@ -98,13 +108,16 @@ final class FavoriteTableController extends AbstractController $changes = false; } else { // Otherwise add to favorite list. - $favoriteInstance->add($GLOBALS['db'], $favoriteTable); + $favoriteInstance->add($favoriteTable); $alreadyFavorite = true; // for favorite_anchor template } } } - $favoriteTables[$user] = $favoriteInstance->getTables(); + $favoriteTables[$user] = array_map( + static fn (RecentFavoriteTable $table) => $table->toArray(), + $favoriteInstance->getTables(), + ); $json = []; $json['changes'] = $changes; @@ -121,7 +134,7 @@ final class FavoriteTableController extends AbstractController $favoriteParams = [ 'db' => $GLOBALS['db'], 'ajax_request' => true, - 'favorite_table' => $favoriteTable, + 'favorite_table' => $favoriteTableName, ($alreadyFavorite ? 'remove' : 'add') . '_favorite' => true, ]; @@ -129,8 +142,8 @@ final class FavoriteTableController extends AbstractController $json['favoriteTables'] = json_encode($favoriteTables); $json['list'] = $favoriteInstance->getHtmlList(); $json['anchor'] = $this->template->render('database/structure/favorite_anchor', [ - 'table_name_hash' => md5($favoriteTable), - 'db_table_name_hash' => md5($GLOBALS['db'] . '.' . $favoriteTable), + 'table_name_hash' => md5($favoriteTableName), + 'db_table_name_hash' => md5($GLOBALS['db'] . '.' . $favoriteTableName), 'fav_params' => $favoriteParams, 'already_favorite' => $alreadyFavorite, ]); @@ -141,47 +154,34 @@ final class FavoriteTableController extends AbstractController /** * Synchronize favorite tables * - * @param RecentFavoriteTable $favoriteInstance Instance of this class - * @param string $user The user hash - * @param mixed[] $favoriteTables Existing favorites + * @param RecentFavoriteTables $favoriteInstance Instance of this class + * @param string $user The user hash + * @param mixed[] $favoriteTables Existing favorites * * @return mixed[] */ private function synchronizeFavoriteTables( - RecentFavoriteTable $favoriteInstance, + RecentFavoriteTables $favoriteInstance, string $user, array $favoriteTables, ): array { - $favoriteInstanceTables = $favoriteInstance->getTables(); - - if ($favoriteInstanceTables === [] && isset($favoriteTables[$user])) { + if ($favoriteInstance->getTables() === [] && isset($favoriteTables[$user])) { foreach ($favoriteTables[$user] as $value) { - $favoriteInstance->add($value['db'], $value['table']); + $favoriteInstance->add(new RecentFavoriteTable( + DatabaseName::from($value['db']), + TableName::from($value['table']), + )); } } - $favoriteTables[$user] = $favoriteInstance->getTables(); + $favoriteTables[$user] = array_map( + static fn (RecentFavoriteTable $table) => $table->toArray(), + $favoriteInstance->getTables(), + ); // Set flag when localStorage and pmadb(if present) are in sync. $_SESSION['tmpval']['favorites_synced'][$GLOBALS['server']] = true; return ['favoriteTables' => json_encode($favoriteTables), 'list' => $favoriteInstance->getHtmlList()]; } - - /** - * Function to check if a table is already in favorite list. - * - * @param string $currentTable current table - */ - private function checkFavoriteTable(string $currentTable): bool - { - $recentFavoriteTables = RecentFavoriteTable::getInstance('favorite'); - foreach ($recentFavoriteTables->getTables() as $value) { - if ($value['db'] == $GLOBALS['db'] && $value['table'] == $currentTable) { - return true; - } - } - - return false; - } } diff --git a/src/Controllers/Database/Structure/RealRowCountController.php b/src/Controllers/Database/Structure/RealRowCountController.php index c6a3fbd47e..74c0ef5735 100644 --- a/src/Controllers/Database/Structure/RealRowCountController.php +++ b/src/Controllers/Database/Structure/RealRowCountController.php @@ -56,7 +56,7 @@ final class RealRowCountController extends AbstractController } $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Database/StructureController.php b/src/Controllers/Database/StructureController.php index ba86d39716..0fc4a4767f 100644 --- a/src/Controllers/Database/StructureController.php +++ b/src/Controllers/Database/StructureController.php @@ -12,12 +12,15 @@ use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\AbstractController; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\DbTableExists; +use PhpMyAdmin\Favorites\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; +use PhpMyAdmin\Identifiers\TableName; use PhpMyAdmin\Message; use PhpMyAdmin\Query\Utilities; -use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\Replication\Replication; use PhpMyAdmin\Replication\ReplicationInfo; use PhpMyAdmin\ResponseRenderer; @@ -134,7 +137,7 @@ class StructureController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); @@ -235,6 +238,7 @@ class StructureController extends AbstractController $overallApproxRows = false; $structureTableRows = []; $trackedTables = $this->trackingChecker->getTrackedTables($GLOBALS['db']); + $recentFavoriteTables = RecentFavoriteTables::getInstance(TableType::Favorite); foreach ($this->tables as $currentTable) { // Get valid statistics whatever is the table type @@ -429,7 +433,12 @@ class StructureController extends AbstractController 'do' => $do, 'approx_rows' => $approxRows, 'show_superscript' => $showSuperscript, - 'already_favorite' => $this->checkFavoriteTable($currentTable['TABLE_NAME']), + 'already_favorite' => $recentFavoriteTables->contains( + new RecentFavoriteTable( + DatabaseName::from($GLOBALS['db']), + TableName::from($currentTable['TABLE_NAME']), + ), + ), 'num_favorite_tables' => $config->settings['NumFavoriteTables'], 'properties_num_columns' => $config->settings['PropertiesNumColumns'], 'limit_chars' => $config->settings['LimitChars'], @@ -611,23 +620,6 @@ class StructureController extends AbstractController return [$do, $ignored]; } - /** - * Function to check if a table is already in favorite list. - * - * @param string $currentTable current table - */ - protected function checkFavoriteTable(string $currentTable): bool - { - $recentFavoriteTables = RecentFavoriteTable::getInstance('favorite'); - foreach ($recentFavoriteTables->getTables() as $value) { - if ($value['db'] == $GLOBALS['db'] && $value['table'] == $currentTable) { - return true; - } - } - - return false; - } - /** * Find table with truename * diff --git a/src/Controllers/Database/TrackingController.php b/src/Controllers/Database/TrackingController.php index 4fc895b38a..75e570cd20 100644 --- a/src/Controllers/Database/TrackingController.php +++ b/src/Controllers/Database/TrackingController.php @@ -56,7 +56,7 @@ class TrackingController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/HomeController.php b/src/Controllers/HomeController.php index 171938b506..25cdc328e8 100644 --- a/src/Controllers/HomeController.php +++ b/src/Controllers/HomeController.php @@ -11,6 +11,8 @@ use PhpMyAdmin\CheckUserPrivileges; use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Git; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\Factory\ResponseFactory; @@ -20,7 +22,6 @@ use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Identifiers\TableName; use PhpMyAdmin\LanguageManager; use PhpMyAdmin\Message; -use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Server\Select; use PhpMyAdmin\Template; @@ -104,7 +105,7 @@ class HomeController extends AbstractController unset($_SESSION['partial_logout']); } - $syncFavoriteTables = RecentFavoriteTable::getInstance('favorite') + $syncFavoriteTables = RecentFavoriteTables::getInstance(TableType::Favorite) ->getHtmlSyncFavoriteTables(); $config = Config::getInstance(); diff --git a/src/Controllers/Operations/Database/CollationController.php b/src/Controllers/Operations/Database/CollationController.php index 95e6593b57..aeaca88709 100644 --- a/src/Controllers/Operations/Database/CollationController.php +++ b/src/Controllers/Operations/Database/CollationController.php @@ -58,7 +58,7 @@ final class CollationController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Operations/DatabaseController.php b/src/Controllers/Operations/DatabaseController.php index 6b6ca0b0fc..86f9ad9861 100644 --- a/src/Controllers/Operations/DatabaseController.php +++ b/src/Controllers/Operations/DatabaseController.php @@ -226,7 +226,7 @@ class DatabaseController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Operations/TableController.php b/src/Controllers/Operations/TableController.php index cd44115a24..39cd46c6c2 100644 --- a/src/Controllers/Operations/TableController.php +++ b/src/Controllers/Operations/TableController.php @@ -81,7 +81,7 @@ class TableController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Operations/ViewController.php b/src/Controllers/Operations/ViewController.php index a3cf4a4978..3af3b1f742 100644 --- a/src/Controllers/Operations/ViewController.php +++ b/src/Controllers/Operations/ViewController.php @@ -57,7 +57,7 @@ class ViewController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/RecentTablesListController.php b/src/Controllers/RecentTablesListController.php index d40d3d01b0..0304f2ad45 100644 --- a/src/Controllers/RecentTablesListController.php +++ b/src/Controllers/RecentTablesListController.php @@ -4,8 +4,9 @@ declare(strict_types=1); namespace PhpMyAdmin\Controllers; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Http\ServerRequest; -use PhpMyAdmin\RecentFavoriteTable; final class RecentTablesListController extends AbstractController { @@ -15,6 +16,6 @@ final class RecentTablesListController extends AbstractController return; } - $this->response->addJSON(['list' => RecentFavoriteTable::getInstance('recent')->getHtmlList()]); + $this->response->addJSON(['list' => RecentFavoriteTables::getInstance(TableType::Recent)->getHtmlList()]); } } diff --git a/src/Controllers/Table/AddFieldController.php b/src/Controllers/Table/AddFieldController.php index d0b1d979f2..a2cec48275 100644 --- a/src/Controllers/Table/AddFieldController.php +++ b/src/Controllers/Table/AddFieldController.php @@ -152,7 +152,7 @@ class AddFieldController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($urlParams, '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/ChangeController.php b/src/Controllers/Table/ChangeController.php index abe9293a02..b52ee691bc 100644 --- a/src/Controllers/Table/ChangeController.php +++ b/src/Controllers/Table/ChangeController.php @@ -63,7 +63,7 @@ class ChangeController extends AbstractController $this->response->addHTML($this->pageSettings->getHTML()); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/ChartController.php b/src/Controllers/Table/ChartController.php index 77c212d0e9..6f497f8b59 100644 --- a/src/Controllers/Table/ChartController.php +++ b/src/Controllers/Table/ChartController.php @@ -100,7 +100,7 @@ class ChartController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($urlParams, '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); @@ -142,7 +142,7 @@ class ChartController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); @@ -228,7 +228,7 @@ class ChartController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/DeleteConfirmController.php b/src/Controllers/Table/DeleteConfirmController.php index 75ac0ddace..e2f53b7d51 100644 --- a/src/Controllers/Table/DeleteConfirmController.php +++ b/src/Controllers/Table/DeleteConfirmController.php @@ -56,7 +56,7 @@ final class DeleteConfirmController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/DropColumnConfirmationController.php b/src/Controllers/Table/DropColumnConfirmationController.php index 29c1b84aeb..7185658404 100644 --- a/src/Controllers/Table/DropColumnConfirmationController.php +++ b/src/Controllers/Table/DropColumnConfirmationController.php @@ -45,7 +45,7 @@ final class DropColumnConfirmationController extends AbstractController return; } - if (! $this->dbTableExists->hasDatabase($db)) { + if (! $this->dbTableExists->selectDatabase($db)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/FindReplaceController.php b/src/Controllers/Table/FindReplaceController.php index c232b1f758..00b3801c24 100644 --- a/src/Controllers/Table/FindReplaceController.php +++ b/src/Controllers/Table/FindReplaceController.php @@ -71,7 +71,7 @@ class FindReplaceController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/GisVisualizationController.php b/src/Controllers/Table/GisVisualizationController.php index c9c5ea0d25..ea91c99932 100644 --- a/src/Controllers/Table/GisVisualizationController.php +++ b/src/Controllers/Table/GisVisualizationController.php @@ -52,7 +52,7 @@ final class GisVisualizationController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/ImportController.php b/src/Controllers/Table/ImportController.php index d418f7d027..f2a50adebc 100644 --- a/src/Controllers/Table/ImportController.php +++ b/src/Controllers/Table/ImportController.php @@ -62,7 +62,7 @@ final class ImportController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/IndexRenameController.php b/src/Controllers/Table/IndexRenameController.php index e0e9c3a08e..74f98773bc 100644 --- a/src/Controllers/Table/IndexRenameController.php +++ b/src/Controllers/Table/IndexRenameController.php @@ -52,7 +52,7 @@ final class IndexRenameController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/IndexesController.php b/src/Controllers/Table/IndexesController.php index 5105d4086f..77a76699f6 100644 --- a/src/Controllers/Table/IndexesController.php +++ b/src/Controllers/Table/IndexesController.php @@ -59,7 +59,7 @@ class IndexesController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/RecentFavoriteController.php b/src/Controllers/Table/RecentFavoriteController.php index edfa15e37f..1cd0aa1269 100644 --- a/src/Controllers/Table/RecentFavoriteController.php +++ b/src/Controllers/Table/RecentFavoriteController.php @@ -5,11 +5,13 @@ declare(strict_types=1); namespace PhpMyAdmin\Controllers\Table; use PhpMyAdmin\Controllers\AbstractController; +use PhpMyAdmin\Favorites\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Identifiers\InvalidIdentifier; use PhpMyAdmin\Identifiers\TableName; -use PhpMyAdmin\RecentFavoriteTable; use function __; @@ -29,8 +31,9 @@ final class RecentFavoriteController extends AbstractController return; } - RecentFavoriteTable::getInstance('recent')->removeIfInvalid($db->getName(), $table->getName()); - RecentFavoriteTable::getInstance('favorite')->removeIfInvalid($db->getName(), $table->getName()); + $favoriteTable = new RecentFavoriteTable($db, $table); + RecentFavoriteTables::getInstance(TableType::Recent)->removeIfInvalid($favoriteTable); + RecentFavoriteTables::getInstance(TableType::Favorite)->removeIfInvalid($favoriteTable); $this->redirect('/sql', ['db' => $db->getName(), 'table' => $table->getName()]); } diff --git a/src/Controllers/Table/SearchController.php b/src/Controllers/Table/SearchController.php index 82b0a72955..1981253828 100644 --- a/src/Controllers/Table/SearchController.php +++ b/src/Controllers/Table/SearchController.php @@ -171,7 +171,7 @@ class SearchController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/SqlController.php b/src/Controllers/Table/SqlController.php index 17c95583b6..5573906a07 100644 --- a/src/Controllers/Table/SqlController.php +++ b/src/Controllers/Table/SqlController.php @@ -60,7 +60,7 @@ class SqlController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($urlParams, '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/Structure/PrimaryController.php b/src/Controllers/Table/Structure/PrimaryController.php index 2b2de18f6e..c8fa8377f7 100644 --- a/src/Controllers/Table/Structure/PrimaryController.php +++ b/src/Controllers/Table/Structure/PrimaryController.php @@ -69,7 +69,7 @@ final class PrimaryController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/StructureController.php b/src/Controllers/Table/StructureController.php index 9770a9da90..e4652c84fd 100644 --- a/src/Controllers/Table/StructureController.php +++ b/src/Controllers/Table/StructureController.php @@ -96,7 +96,7 @@ class StructureController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($urlParams, '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/TrackingController.php b/src/Controllers/Table/TrackingController.php index f51b1eb77a..b999610ddb 100644 --- a/src/Controllers/Table/TrackingController.php +++ b/src/Controllers/Table/TrackingController.php @@ -65,7 +65,7 @@ final class TrackingController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Table/ZoomSearchController.php b/src/Controllers/Table/ZoomSearchController.php index 02d6d08348..09c22865c3 100644 --- a/src/Controllers/Table/ZoomSearchController.php +++ b/src/Controllers/Table/ZoomSearchController.php @@ -96,7 +96,7 @@ class ZoomSearchController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/Controllers/Triggers/IndexController.php b/src/Controllers/Triggers/IndexController.php index 004467e4a0..f1db58cea5 100644 --- a/src/Controllers/Triggers/IndexController.php +++ b/src/Controllers/Triggers/IndexController.php @@ -70,7 +70,7 @@ final class IndexController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; @@ -96,7 +96,7 @@ final class IndexController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; diff --git a/src/Controllers/View/CreateController.php b/src/Controllers/View/CreateController.php index b424e0a30a..9ebe9f83b0 100644 --- a/src/Controllers/View/CreateController.php +++ b/src/Controllers/View/CreateController.php @@ -69,7 +69,7 @@ class CreateController extends AbstractController $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); - if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { + if ($databaseName === null || ! $this->dbTableExists->selectDatabase($databaseName)) { if ($request->isAjax()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', Message::error(__('No databases selected.'))); diff --git a/src/DbTableExists.php b/src/DbTableExists.php index 92efaf8b17..7b321630cf 100644 --- a/src/DbTableExists.php +++ b/src/DbTableExists.php @@ -12,9 +12,6 @@ use function sprintf; final class DbTableExists { - /** @psalm-var list */ - private array $databases = []; - /** @psalm-var list */ private array $tables = []; @@ -22,32 +19,22 @@ final class DbTableExists { } - public function hasDatabase(DatabaseName $databaseName): bool + public function selectDatabase(DatabaseName $databaseName): bool { - if (in_array($databaseName->getName(), $this->databases, true)) { - return true; - } - - if ($this->dbi->selectDb($databaseName)) { - $this->databases[] = $databaseName->getName(); - - return true; - } - - return false; + return $this->dbi->selectDb($databaseName); } + /** + * Check if a table exists in the given database. + * It will return true if the table exists, regardless if it's temporary or permanent. + */ public function hasTable(DatabaseName $database, TableName $table): bool { if (in_array($database->getName() . '.' . $table->getName(), $this->tables, true)) { return true; } - if ( - $this->hasCachedTableContent($database, $table) - || $this->isPermanentTable($table) - || $this->isTemporaryTable($table) - ) { + if ($this->tableExists($database, $table)) { $this->tables[] = $database->getName() . '.' . $table->getName(); return true; @@ -56,24 +43,13 @@ final class DbTableExists return false; } - private function hasCachedTableContent(DatabaseName $database, TableName $table): bool + private function tableExists(DatabaseName $database, TableName $table): bool { - return (bool) $this->dbi->getCache()->getCachedTableContent([$database->getName(), $table->getName()]); - } - - private function isPermanentTable(TableName $table): bool - { - $result = $this->dbi->tryQuery(sprintf('SHOW TABLES LIKE %s;', $this->dbi->quoteString($table->getName()))); - - return $result !== false && $result->numRows() > 0; - } - - /** - * SHOW TABLES doesn't show temporary tables, so try select - * as it can happen just in case temporary table. It should be fast. - */ - private function isTemporaryTable(TableName $table): bool - { - return $this->dbi->tryQuery(sprintf('SELECT 1 FROM %s LIMIT 1;', Util::backquote($table))) !== false; + // SHOW TABLES doesn't show temporary tables, so try select. + return $this->dbi->tryQuery(sprintf( + 'SELECT 1 FROM %s.%s LIMIT 1;', + Util::backquote($database), + Util::backquote($table), + )) !== false; } } diff --git a/src/Favorites/RecentFavoriteTable.php b/src/Favorites/RecentFavoriteTable.php new file mode 100644 index 0000000000..8277a62224 --- /dev/null +++ b/src/Favorites/RecentFavoriteTable.php @@ -0,0 +1,27 @@ + $this->db->getName(), 'table' => $this->table->getName()]; + } +} diff --git a/src/RecentFavoriteTable.php b/src/Favorites/RecentFavoriteTables.php similarity index 56% rename from src/RecentFavoriteTable.php rename to src/Favorites/RecentFavoriteTables.php index 28b0d3c897..6792f95ae0 100644 --- a/src/RecentFavoriteTable.php +++ b/src/Favorites/RecentFavoriteTables.php @@ -5,18 +5,26 @@ declare(strict_types=1); -namespace PhpMyAdmin; +namespace PhpMyAdmin\Favorites; +use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Dbal\Connection; +use PhpMyAdmin\DbTableExists; +use PhpMyAdmin\Message; +use PhpMyAdmin\Template; +use PhpMyAdmin\Url; +use PhpMyAdmin\Util; use function __; use function array_key_exists; -use function array_merge; use function array_pop; use function array_unique; use function array_unshift; +use function array_values; use function count; +use function in_array; use function is_string; use function json_decode; use function json_encode; @@ -32,65 +40,75 @@ use const SORT_REGULAR; * @TODO Change the release version in table pma_recent * (#recent in documentation) */ -class RecentFavoriteTable +class RecentFavoriteTables { - /** - * Reference to session variable containing recently used or favorite tables. - * - * @var mixed[] - */ + /** @var RecentFavoriteTable[] */ private array $tables = []; /** * RecentFavoriteTable instances. * - * @var array + * @var array */ private static array $instances = []; - private Relation $relation; - /** * Creates a new instance of RecentFavoriteTable - * - * @param string $tableType Defines type of action, Favorite or Recent table. - * @phpstan-param 'favorite'|'recent' $tableType */ - private function __construct(public Template $template, private string $tableType) - { - $this->relation = new Relation(DatabaseInterface::getInstance()); - $serverId = $GLOBALS['server']; + private function __construct( + public Template $template, + private readonly TableType $tableType, + private readonly string $serverId, + private readonly DatabaseInterface $dbi, + private readonly Relation $relation, + private readonly DbTableExists $dbTableExists, + ) { // Code search hint: recentTables // Code search hint: favoriteTables - if (! isset($_SESSION['tmpval'][$this->tableType . 'Tables'][$serverId])) { - $_SESSION['tmpval'][$this->tableType . 'Tables'][$serverId] = $this->getPmaTable() + if (! isset($_SESSION['tmpval'][$this->tableType->value . 'Tables'][$this->serverId])) { + $_SESSION['tmpval'][$this->tableType->value . 'Tables'][$this->serverId] = $this->getPmaTable() !== null ? $this->getFromDb() : []; } - $this->tables =& $_SESSION['tmpval'][$this->tableType . 'Tables'][$serverId]; + foreach ($_SESSION['tmpval'][$this->tableType->value . 'Tables'][$this->serverId] as $table) { + $this->tables[] = RecentFavoriteTable::fromArray($table); + } + } + + public function __destruct() + { + $_SESSION['tmpval'][$this->tableType->value . 'Tables'][$this->serverId] = []; + foreach ($this->tables as $table) { + $_SESSION['tmpval'][$this->tableType->value . 'Tables'][$this->serverId][] = $table->toArray(); + } } /** * Returns class instance. - * - * @param string $type the table type - * @psalm-param 'favorite'|'recent' $type */ - public static function getInstance(string $type): RecentFavoriteTable + public static function getInstance(TableType $type): RecentFavoriteTables { - if (! array_key_exists($type, self::$instances)) { + if (! array_key_exists($type->value, self::$instances)) { $template = new Template(); - self::$instances[$type] = new RecentFavoriteTable($template, $type); + $dbi = DatabaseInterface::getInstance(); + self::$instances[$type->value] = new RecentFavoriteTables( + $template, + $type, + (string) $GLOBALS['server'], + $dbi, + new Relation($dbi), + new DbTableExists($dbi), + ); } - return self::$instances[$type]; + return self::$instances[$type->value]; } /** * Returns the recent/favorite tables array * - * @return mixed[] + * @return RecentFavoriteTable[] */ public function getTables(): array { @@ -100,18 +118,17 @@ class RecentFavoriteTable /** * Returns recently used tables or favorite from phpMyAdmin database. * - * @return mixed[] + * @return array{db:string, table:string}[] */ - public function getFromDb(): array + private function getFromDb(): array { // Read from phpMyAdmin database, if recent tables is not in session - $dbi = DatabaseInterface::getInstance(); $sqlQuery = ' SELECT `tables` FROM ' . $this->getPmaTable() . ' WHERE `username` = ' - . $dbi->quoteString(Config::getInstance()->selectedServer['user'], Connection::TYPE_CONTROL); + . $this->dbi->quoteString(Config::getInstance()->selectedServer['user'], Connection::TYPE_CONTROL); - $result = $dbi->tryQueryAsControlUser($sqlQuery); - if ($result) { + $result = $this->dbi->tryQueryAsControlUser($sqlQuery); + if ($result !== false) { $value = $result->fetchValue(); if (is_string($value)) { return json_decode($value, true); @@ -126,25 +143,23 @@ class RecentFavoriteTable * * @return true|Message */ - public function saveToDb(): bool|Message + private function saveToDb(): bool|Message { $username = Config::getInstance()->selectedServer['user']; - $dbi = DatabaseInterface::getInstance(); $sqlQuery = ' REPLACE INTO ' . $this->getPmaTable() . ' (`username`, `tables`)' - . ' VALUES (' . $dbi->quoteString($username) . ', ' - . $dbi->quoteString(json_encode($this->tables)) . ')'; + . ' VALUES (' . $this->dbi->quoteString($username) . ', ' + . $this->dbi->quoteString(json_encode($this->tables)) . ')'; - $success = $dbi->tryQuery($sqlQuery, Connection::TYPE_CONTROL); + $success = $this->dbi->tryQuery($sqlQuery, Connection::TYPE_CONTROL); - if (! $success) { - $errorMsg = match ($this->tableType) { - 'recent' => __('Could not save recent table!'), - 'favorite' => __('Could not save favorite table!'), - }; + if ($success === false) { + $message = Message::error(match ($this->tableType) { + TableType::Recent => __('Could not save recent table!'), + TableType::Favorite => __('Could not save favorite table!'), + }); - $message = Message::error($errorMsg); $message->addMessage( - Message::rawError($dbi->getError(Connection::TYPE_CONTROL)), + Message::rawError($this->dbi->getError(Connection::TYPE_CONTROL)), '

', ); @@ -155,21 +170,19 @@ class RecentFavoriteTable } /** - * Trim recent.favorite table according to the + * Trim recent/favorite table according to the * NumRecentTables/NumFavoriteTables configuration. */ - public function trim(): bool + private function trim(): void { $max = max( - Config::getInstance()->settings['Num' . ucfirst($this->tableType) . 'Tables'], + Config::getInstance()->settings['Num' . ucfirst($this->tableType->value) . 'Tables'], 0, ); - $trimmingOccurred = count($this->tables) > $max; + while (count($this->tables) > $max) { array_pop($this->tables); } - - return $trimmingOccurred; } /** @@ -178,10 +191,10 @@ class RecentFavoriteTable public function getHtmlList(): string { if ($this->tables !== []) { - if ($this->tableType === 'recent') { + if ($this->tableType === TableType::Recent) { $tables = []; foreach ($this->tables as $table) { - $tables[] = ['db' => $table['db'], 'table' => $table['table']]; + $tables[] = $table->toArray(); } return $this->template->render('recent_favorite_table_recent', ['tables' => $tables]); @@ -190,15 +203,15 @@ class RecentFavoriteTable $tables = []; foreach ($this->tables as $table) { $removeParameters = [ - 'db' => $table['db'], + 'db' => $table->db, 'ajax_request' => true, - 'favorite_table' => $table['table'], + 'favorite_table' => $table->table, 'remove_favorite' => true, ]; $tableParameters = [ - 'db' => $table['db'], - 'table' => $table['table'], - 'md5' => md5($table['db'] . '.' . $table['table']), + 'db' => $table->db, + 'table' => $table->table, + 'md5' => md5($table->db . '.' . $table->table), ]; $tables[] = ['remove_parameters' => $removeParameters, 'table_parameters' => $tableParameters]; @@ -208,14 +221,14 @@ class RecentFavoriteTable } return $this->template->render('recent_favorite_table_no_tables', [ - 'is_recent' => $this->tableType === 'recent', + 'is_recent' => $this->tableType === TableType::Recent, ]); } public function getHtml(): string { $html = '
'; - if ($this->tableType === 'recent') { + if ($this->tableType === TableType::Recent) { $html .= '
    '; @@ -234,28 +247,20 @@ class RecentFavoriteTable /** * Add recently used or favorite tables. * - * @param string $db database name where the table is located - * @param string $table table name - * * @return true|Message True if success, Message if not */ - public function add(string $db, string $table): bool|Message + public function add(RecentFavoriteTable $newTable): bool|Message { - // If table does not exist, do not add._getPmaTable() - if (DatabaseInterface::getInstance()->getColumns($db, $table) === []) { + if (! $this->dbTableExists->hasTable($newTable->db, $newTable->table)) { return true; } - $tableArr = []; - $tableArr['db'] = $db; - $tableArr['table'] = $table; - // add only if this is new table - if (! isset($this->tables[0]) || $this->tables[0] != $tableArr) { - array_unshift($this->tables, $tableArr); - $this->tables = array_merge(array_unique($this->tables, SORT_REGULAR)); + if (! isset($this->tables[0]) || $this->tables[0] != $newTable) { + array_unshift($this->tables, $newTable); + $this->tables = array_values(array_unique($this->tables, SORT_REGULAR)); $this->trim(); - if ($this->getPmaTable()) { + if ($this->getPmaTable() !== null) { return $this->saveToDb(); } } @@ -266,22 +271,21 @@ class RecentFavoriteTable /** * Removes recent/favorite tables that don't exist. * - * @param string $db database - * @param string $table table - * * @return bool|Message True if invalid and removed, False if not invalid, * Message if error while removing */ - public function removeIfInvalid(string $db, string $table): bool|Message + public function removeIfInvalid(RecentFavoriteTable $tableToRemove): bool|Message { - foreach ($this->tables as $tbl) { - if ($tbl['db'] != $db || $tbl['table'] != $table) { + foreach ($this->tables as $table) { + if ( + $table->db->getName() !== $tableToRemove->db->getName() + || $table->table->getName() !== $tableToRemove->table->getName() + ) { continue; } - // TODO Figure out a better way to find the existence of a table - if (DatabaseInterface::getInstance()->getColumns($tbl['db'], $tbl['table']) === []) { - return $this->remove($tbl['db'], $tbl['table']); + if (! $this->dbTableExists->hasTable($table->db, $table->table)) { + return $this->remove($tableToRemove); } } @@ -291,28 +295,38 @@ class RecentFavoriteTable /** * Remove favorite tables. * - * @param string $db database name where the table is located - * @param string $table table name - * * @return true|Message True if success, Message if not */ - public function remove(string $db, string $table): bool|Message + public function remove(RecentFavoriteTable $tableToRemove): bool|Message { - foreach ($this->tables as $key => $value) { - if ($value['db'] != $db || $value['table'] != $table) { + foreach ($this->tables as $key => $table) { + if ( + $table->db->getName() !== $tableToRemove->db->getName() + || $table->table->getName() !== $tableToRemove->table->getName() + ) { continue; } unset($this->tables[$key]); } - if ($this->getPmaTable()) { + if ($this->getPmaTable() !== null) { return $this->saveToDb(); } return true; } + /** + * Function to check if a table is already in favorite list. + */ + public function contains(RecentFavoriteTable $currentTable): bool + { + // When looking for the value we are looking for a similar object with + // the same public properties, not the same instance. The in_array must be loose comparison. + return in_array($currentTable, $this->tables, false); + } + /** * Generate Html for sync Favorite tables anchor. (from localStorage to pmadb) */ @@ -360,12 +374,12 @@ class RecentFavoriteTable private function getPmaTable(): string|null { $relationParameters = $this->relation->getRelationParameters(); - if ($this->tableType === 'recent' && $relationParameters->recentlyUsedTablesFeature !== null) { + if ($this->tableType === TableType::Recent && $relationParameters->recentlyUsedTablesFeature !== null) { return Util::backquote($relationParameters->recentlyUsedTablesFeature->database) . '.' . Util::backquote($relationParameters->recentlyUsedTablesFeature->recent); } - if ($this->tableType === 'favorite' && $relationParameters->favoriteTablesFeature !== null) { + if ($this->tableType === TableType::Favorite && $relationParameters->favoriteTablesFeature !== null) { return Util::backquote($relationParameters->favoriteTablesFeature->database) . '.' . Util::backquote($relationParameters->favoriteTablesFeature->favorite); } diff --git a/src/Favorites/TableType.php b/src/Favorites/TableType.php new file mode 100644 index 0000000000..75120f6dda --- /dev/null +++ b/src/Favorites/TableType.php @@ -0,0 +1,11 @@ +addRecentTable($GLOBALS['db'], $GLOBALS['table']); + if (empty($_REQUEST['recent_table']) && $GLOBALS['table'] !== '') { + $recentTable = $this->addRecentTable( + DatabaseName::from($GLOBALS['db']), + TableName::from($GLOBALS['table']), + ); } if ($this->isAjax) { @@ -588,16 +596,14 @@ class Header /** * Add recently used table and reload the navigation. - * - * @param string $db Database name where the table is located. - * @param string $table The table name */ - private function addRecentTable(string $db, string $table): string + private function addRecentTable(DatabaseName $db, TableName $table): string { - if ($this->menuEnabled && $table !== '' && Config::getInstance()->settings['NumRecentTables'] > 0) { - $error = RecentFavoriteTable::getInstance('recent')->add($db, $table); + if ($this->menuEnabled && Config::getInstance()->settings['NumRecentTables'] > 0) { + $favoriteTable = new RecentFavoriteTable($db, $table); + $error = RecentFavoriteTables::getInstance(TableType::Recent)->add($favoriteTable); if ($error === true) { - return RecentFavoriteTable::getHtmlUpdateRecentTables(); + return RecentFavoriteTables::getHtmlUpdateRecentTables(); } return $error->getDisplay(); diff --git a/src/Navigation/NavigationTree.php b/src/Navigation/NavigationTree.php index b98c382af7..389f1c43f7 100644 --- a/src/Navigation/NavigationTree.php +++ b/src/Navigation/NavigationTree.php @@ -12,6 +12,8 @@ use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Navigation\Nodes\Node; use PhpMyAdmin\Navigation\Nodes\NodeColumn; @@ -32,7 +34,6 @@ use PhpMyAdmin\Navigation\Nodes\NodeTrigger; use PhpMyAdmin\Navigation\Nodes\NodeTriggerContainer; use PhpMyAdmin\Navigation\Nodes\NodeView; use PhpMyAdmin\Navigation\Nodes\NodeViewContainer; -use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Template; use PhpMyAdmin\Url; @@ -1383,11 +1384,11 @@ class NavigationTree $renderDetails = []; $config = Config::getInstance(); if ($config->settings['NumRecentTables'] > 0) { - $renderDetails['recent'] = RecentFavoriteTable::getInstance('recent')->getHtml(); + $renderDetails['recent'] = RecentFavoriteTables::getInstance(TableType::Recent)->getHtml(); } if ($config->settings['NumFavoriteTables'] > 0) { - $renderDetails['favorite'] = RecentFavoriteTable::getInstance('favorite')->getHtml(); + $renderDetails['favorite'] = RecentFavoriteTables::getInstance(TableType::Favorite)->getHtml(); } return $this->template->render('navigation/tree/quick_warp', $renderDetails); diff --git a/tests/classes/ConfigStorage/RelationTest.php b/tests/classes/ConfigStorage/RelationTest.php index 871ea6e195..e49911338d 100644 --- a/tests/classes/ConfigStorage/RelationTest.php +++ b/tests/classes/ConfigStorage/RelationTest.php @@ -9,7 +9,7 @@ use PhpMyAdmin\Config; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\DummyResult; use PHPUnit\Framework\Attributes\CoversClass; @@ -1908,7 +1908,7 @@ class RelationTest extends AbstractTestCase $_SESSION['tmpval'] = []; (new ReflectionProperty(Relation::class, 'cache'))->setValue(null, null); - (new ReflectionProperty(RecentFavoriteTable::class, 'instances'))->setValue(null, []); + (new ReflectionProperty(RecentFavoriteTables::class, 'instances'))->setValue(null, []); $relation = new Relation($dbi); $relation->initRelationParamsCache(); diff --git a/tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php b/tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php index c21fd381b2..ff34f66087 100644 --- a/tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php +++ b/tests/classes/Controllers/Database/Structure/FavoriteTableControllerTest.php @@ -8,62 +8,58 @@ use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Database\Structure\FavoriteTableController; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\DbTableExists; -use PhpMyAdmin\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; -use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub; use PHPUnit\Framework\Attributes\CoversClass; -use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; use function json_encode; #[CoversClass(FavoriteTableController::class)] -class FavoriteTableControllerTest extends AbstractTestCase +final class FavoriteTableControllerTest extends AbstractTestCase { - protected DatabaseInterface $dbi; - - protected DbiDummy $dummyDbi; - - protected function setUp(): void - { - parent::setUp(); - - $this->dummyDbi = $this->createDbiDummy(); - $this->dbi = $this->createDatabaseInterface($this->dummyDbi); - DatabaseInterface::$instance = $this->dbi; - } - public function testSynchronizeFavoriteTables(): void { $GLOBALS['server'] = 1; - $GLOBALS['text_dir'] = 'ltr'; - $GLOBALS['db'] = 'db'; - $favoriteInstance = $this->getMockBuilder(RecentFavoriteTable::class) - ->disableOriginalConstructor() - ->getMock(); - $favoriteInstance->expects($this->exactly(2)) - ->method('getTables') - ->willReturn([[]], [['db' => 'db', 'table' => 'table']]); + $dbiDummy = $this->createDbiDummy(); + $dbi = $this->createDatabaseInterface($dbiDummy); + DatabaseInterface::$instance = $dbi; - $class = new ReflectionClass(FavoriteTableController::class); - $method = $class->getMethod('synchronizeFavoriteTables'); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); + + (new ReflectionProperty(RecentFavoriteTables::class, 'instances'))->setValue(null, []); + $favoriteInstance = RecentFavoriteTables::getInstance(TableType::Favorite); $controller = new FavoriteTableController( new ResponseStub(), new Template(), - new Relation($this->dbi), - new DbTableExists($this->dbi), + new Relation($dbi), + new DbTableExists($dbi), ); // The user hash for test $user = 'abcdefg'; - $favoriteTable = [$user => [['db' => 'db', 'table' => 'table']]]; + $favoriteTable = [$user => [['db' => 'test_db', 'table' => 'test_table']]]; + $_SESSION['tmpval'] = ['favorites_synced' => [$GLOBALS['server'] => null]]; + + $method = new ReflectionMethod(FavoriteTableController::class, 'synchronizeFavoriteTables'); $json = $method->invokeArgs($controller, [$favoriteInstance, $user, $favoriteTable]); - $this->assertEquals(json_encode($favoriteTable), $json['favoriteTables'] ?? ''); - $this->assertArrayHasKey('list', $json); + self::assertIsArray($json); + self::assertEquals(json_encode($favoriteTable), $json['favoriteTables'] ?? ''); + self::assertArrayHasKey('list', $json); + /** + * @psalm-suppress TypeDoesNotContainType + * @phpstan-ignore-next-line + */ + self::assertTrue($_SESSION['tmpval']['favorites_synced'][$GLOBALS['server']]); + + $dbiDummy->assertAllQueriesConsumed(); } } diff --git a/tests/classes/Controllers/Database/StructureControllerTest.php b/tests/classes/Controllers/Database/StructureControllerTest.php index ca80348945..50698b45b9 100644 --- a/tests/classes/Controllers/Database/StructureControllerTest.php +++ b/tests/classes/Controllers/Database/StructureControllerTest.php @@ -12,7 +12,6 @@ use PhpMyAdmin\Core; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\DbTableExists; use PhpMyAdmin\Http\ServerRequest; -use PhpMyAdmin\RecentFavoriteTable; use PhpMyAdmin\Replication\Replication; use PhpMyAdmin\Table\Table; use PhpMyAdmin\Template; @@ -252,65 +251,6 @@ class StructureControllerTest extends AbstractTestCase ); } - /** - * Tests for checkFavoriteTable() - */ - public function testCheckFavoriteTable(): void - { - $class = new ReflectionClass(StructureController::class); - $method = $class->getMethod('checkFavoriteTable'); - - $dbiDummy = $this->createDbiDummy(); - $dbi = $this->createDatabaseInterface($dbiDummy); - - $GLOBALS['db'] = 'sakila'; - DatabaseInterface::$instance = $dbi; - - $dbiDummy->removeDefaultResults(); - $dbiDummy->addResult( - 'SHOW COLUMNS FROM `sakila`.`country`', - [ - ['country_id', 'smallint(5) unsigned', 'NO', 'PRI', null, 'auto_increment'], - ], - ['Field', 'Type', 'Null', 'Key', 'Default', 'Extra'], - ); - $dbiDummy->addResult( - 'SHOW INDEXES FROM `sakila`.`country`', - [], - ['Table', 'Non_unique', 'Key_name', 'Column_name'], - ); - - $controller = new StructureController( - $this->response, - $this->template, - $this->relation, - $this->replication, - $dbi, - $this->createStub(TrackingChecker::class), - $this->createStub(PageSettings::class), - new DbTableExists($dbi), - ); - - $recentFavoriteTables = RecentFavoriteTable::getInstance('favorite'); - $this->assertSame([], $recentFavoriteTables->getTables()); - $recentFavoriteTables->remove('sakila', 'country'); - $recentFavoriteTables->add('sakila', 'country'); - $this->assertSame([ - [ - 'db' => 'sakila', - 'table' => 'country', - ], - ], $recentFavoriteTables->getTables()); - - $this->assertFalse( - $method->invokeArgs($controller, ['']), - ); - - $this->assertTrue( - $method->invokeArgs($controller, ['country']), - ); - } - /** @throws ReflectionException */ public function testDisplayTableList(): void { diff --git a/tests/classes/Controllers/Operations/TableControllerTest.php b/tests/classes/Controllers/Operations/TableControllerTest.php index 5007159c5a..4e36a336d6 100644 --- a/tests/classes/Controllers/Operations/TableControllerTest.php +++ b/tests/classes/Controllers/Operations/TableControllerTest.php @@ -55,7 +55,7 @@ class TableControllerTest extends AbstractTestCase $this->dummyDbi->addSelectDb('test_db'); $this->dummyDbi->addSelectDb('test_db'); // phpcs:disable Generic.Files.LineLength.TooLong - $this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']], ['Tables_in_test_db (test_table)']); + $this->dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $this->dummyDbi->addResult( 'SELECT *, `TABLE_SCHEMA` AS `Db`, `TABLE_NAME` AS `Name`, `TABLE_TYPE` AS `TABLE_TYPE`, `ENGINE` AS `Engine`, `ENGINE` AS `Type`, `VERSION` AS `Version`, `ROW_FORMAT` AS `Row_format`, `TABLE_ROWS` AS `Rows`, `AVG_ROW_LENGTH` AS `Avg_row_length`, `DATA_LENGTH` AS `Data_length`, `MAX_DATA_LENGTH` AS `Max_data_length`, `INDEX_LENGTH` AS `Index_length`, `DATA_FREE` AS `Data_free`, `AUTO_INCREMENT` AS `Auto_increment`, `CREATE_TIME` AS `Create_time`, `UPDATE_TIME` AS `Update_time`, `CHECK_TIME` AS `Check_time`, `TABLE_COLLATION` AS `Collation`, `CHECKSUM` AS `Checksum`, `CREATE_OPTIONS` AS `Create_options`, `TABLE_COMMENT` AS `Comment` FROM `information_schema`.`TABLES` t WHERE `TABLE_SCHEMA` COLLATE utf8_bin IN (\'test_db\') AND t.`TABLE_NAME` COLLATE utf8_bin = \'test_table\' ORDER BY Name ASC', [['ref', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '49152', '0', '4', '2021-11-07 15:21:00', null, null, 'utf8mb4_general_ci', null, '', '', '0', 'N', 'test_db', 'test_table', 'BASE TABLE', 'InnoDB', 'InnoDB', '10', 'Dynamic', '3', '5461', '16384', '0', '49152', '0', '4', '2021-11-07 15:21:00', null, null, 'utf8mb4_general_ci', null, '', '']], diff --git a/tests/classes/Controllers/Table/AddFieldControllerTest.php b/tests/classes/Controllers/Table/AddFieldControllerTest.php index f2266cf27b..bbd2811fc0 100644 --- a/tests/classes/Controllers/Table/AddFieldControllerTest.php +++ b/tests/classes/Controllers/Table/AddFieldControllerTest.php @@ -35,7 +35,7 @@ class AddFieldControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; diff --git a/tests/classes/Controllers/Table/ChangeControllerTest.php b/tests/classes/Controllers/Table/ChangeControllerTest.php index e65073219b..803fa163dd 100644 --- a/tests/classes/Controllers/Table/ChangeControllerTest.php +++ b/tests/classes/Controllers/Table/ChangeControllerTest.php @@ -30,7 +30,7 @@ final class ChangeControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dummyDbi->addResult( 'SELECT * FROM `test_db`.`test_table` LIMIT 1;', [['1', 'abcd', '2011-01-20 02:00:02']], @@ -125,7 +125,7 @@ final class ChangeControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dummyDbi->addResult( 'SELECT * FROM `test_db`.`test_table` LIMIT 1;', [['1', 'abcd', '2011-01-20 02:00:02']], diff --git a/tests/classes/Controllers/Table/ChartControllerTest.php b/tests/classes/Controllers/Table/ChartControllerTest.php index f1583b5b29..6c11e6c908 100644 --- a/tests/classes/Controllers/Table/ChartControllerTest.php +++ b/tests/classes/Controllers/Table/ChartControllerTest.php @@ -62,7 +62,7 @@ class ChartControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'table_for_chart\';', [['table_for_chart']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`table_for_chart` LIMIT 1;', [['1']]); $dummyDbi->addSelectDb('test_db'); $dummyDbi->addResult( 'SELECT * FROM `test_db`.`table_for_chart`;', diff --git a/tests/classes/Controllers/Table/DeleteConfirmControllerTest.php b/tests/classes/Controllers/Table/DeleteConfirmControllerTest.php index b1cc3ae286..1d7c1f06be 100644 --- a/tests/classes/Controllers/Table/DeleteConfirmControllerTest.php +++ b/tests/classes/Controllers/Table/DeleteConfirmControllerTest.php @@ -30,7 +30,7 @@ class DeleteConfirmControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; diff --git a/tests/classes/Controllers/Table/DropColumnConfirmationControllerTest.php b/tests/classes/Controllers/Table/DropColumnConfirmationControllerTest.php index 54aa1ed5ab..f533ec0bb7 100644 --- a/tests/classes/Controllers/Table/DropColumnConfirmationControllerTest.php +++ b/tests/classes/Controllers/Table/DropColumnConfirmationControllerTest.php @@ -34,7 +34,7 @@ class DropColumnConfirmationControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; diff --git a/tests/classes/Controllers/Table/ImportControllerTest.php b/tests/classes/Controllers/Table/ImportControllerTest.php index 31d9307ba7..859b135da0 100644 --- a/tests/classes/Controllers/Table/ImportControllerTest.php +++ b/tests/classes/Controllers/Table/ImportControllerTest.php @@ -40,7 +40,7 @@ class ImportControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dummyDbi->addResult('SELECT @@local_infile;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; diff --git a/tests/classes/Controllers/Table/IndexRenameControllerTest.php b/tests/classes/Controllers/Table/IndexRenameControllerTest.php index 99090b503a..b126f7fa0a 100644 --- a/tests/classes/Controllers/Table/IndexRenameControllerTest.php +++ b/tests/classes/Controllers/Table/IndexRenameControllerTest.php @@ -29,7 +29,7 @@ class IndexRenameControllerTest extends AbstractTestCase $dummyDbi = $this->createDbiDummy(); $dummyDbi->addSelectDb('test_db'); $dummyDbi->addSelectDb('test_db'); - $dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dbi = $this->createDatabaseInterface($dummyDbi); DatabaseInterface::$instance = $dbi; diff --git a/tests/classes/Controllers/Table/RecentFavoriteControllerTest.php b/tests/classes/Controllers/Table/RecentFavoriteControllerTest.php index 4c5233c2b5..2c7687f8c9 100644 --- a/tests/classes/Controllers/Table/RecentFavoriteControllerTest.php +++ b/tests/classes/Controllers/Table/RecentFavoriteControllerTest.php @@ -7,8 +7,12 @@ namespace PhpMyAdmin\Tests\Controllers\Table; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Controllers\Table\RecentFavoriteController; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Favorites\RecentFavoriteTable; +use PhpMyAdmin\Favorites\RecentFavoriteTables; +use PhpMyAdmin\Favorites\TableType; use PhpMyAdmin\Http\Factory\ServerRequestFactory; -use PhpMyAdmin\RecentFavoriteTable; +use PhpMyAdmin\Identifiers\DatabaseName; +use PhpMyAdmin\Identifiers\TableName; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; @@ -33,13 +37,17 @@ class RecentFavoriteControllerTest extends AbstractTestCase 'favoriteTables' => [2 => [['db' => 'test_db', 'table' => 'test_table']]], ]; - DatabaseInterface::$instance = $this->createDatabaseInterface(); + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); + DatabaseInterface::$instance = $this->createDatabaseInterface($dbiDummy); - $recent = RecentFavoriteTable::getInstance('recent'); - $favorite = RecentFavoriteTable::getInstance('favorite'); + $recent = RecentFavoriteTables::getInstance(TableType::Recent); + $favorite = RecentFavoriteTables::getInstance(TableType::Favorite); - self::assertSame([['db' => 'test_db', 'table' => 'test_table']], $recent->getTables()); - self::assertSame([['db' => 'test_db', 'table' => 'test_table']], $favorite->getTables()); + $table = new RecentFavoriteTable(DatabaseName::from('test_db'), TableName::from('test_table')); + self::assertEquals([$table], $recent->getTables()); + self::assertEquals([$table], $favorite->getTables()); $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']); @@ -54,8 +62,8 @@ class RecentFavoriteControllerTest extends AbstractTestCase $response->getHeaderLine('Location'), ); - self::assertSame([['db' => 'test_db', 'table' => 'test_table']], $recent->getTables()); - self::assertSame([['db' => 'test_db', 'table' => 'test_table']], $favorite->getTables()); + self::assertEquals([$table], $recent->getTables()); + self::assertEquals([$table], $favorite->getTables()); } public function testRecentFavoriteControllerWithInvalidDbAndTable(): void @@ -70,15 +78,16 @@ class RecentFavoriteControllerTest extends AbstractTestCase ]; $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addResult('SELECT 1 FROM `invalid_db`.`invalid_table` LIMIT 1;', false); + $dbiDummy->addResult('SELECT 1 FROM `invalid_db`.`invalid_table` LIMIT 1;', false); DatabaseInterface::$instance = $this->createDatabaseInterface($dbiDummy); - $dbiDummy->addResult('SHOW COLUMNS FROM `invalid_db`.`invalid_table`', false); - $dbiDummy->addResult('SHOW COLUMNS FROM `invalid_db`.`invalid_table`', false); - $recent = RecentFavoriteTable::getInstance('recent'); - $favorite = RecentFavoriteTable::getInstance('favorite'); + $recent = RecentFavoriteTables::getInstance(TableType::Recent); + $favorite = RecentFavoriteTables::getInstance(TableType::Favorite); - self::assertSame([['db' => 'invalid_db', 'table' => 'invalid_table']], $recent->getTables()); - self::assertSame([['db' => 'invalid_db', 'table' => 'invalid_table']], $favorite->getTables()); + $table = new RecentFavoriteTable(DatabaseName::from('invalid_db'), TableName::from('invalid_table')); + self::assertEquals([$table], $recent->getTables()); + self::assertEquals([$table], $favorite->getTables()); $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') ->withQueryParams(['db' => 'invalid_db', 'table' => 'invalid_table']); @@ -95,6 +104,7 @@ class RecentFavoriteControllerTest extends AbstractTestCase self::assertSame([], $recent->getTables()); self::assertSame([], $favorite->getTables()); + $dbiDummy->assertAllQueriesConsumed(); } public function testRecentFavoriteControllerWithInvalidDbAndTableName(): void diff --git a/tests/classes/Controllers/Table/SqlControllerTest.php b/tests/classes/Controllers/Table/SqlControllerTest.php index ca261a724a..d91f88e7a0 100644 --- a/tests/classes/Controllers/Table/SqlControllerTest.php +++ b/tests/classes/Controllers/Table/SqlControllerTest.php @@ -49,7 +49,7 @@ class SqlControllerTest extends AbstractTestCase $config->selectedServer = $config->getSettings()->Servers[1]->asArray(); $this->dummyDbi->addSelectDb('test_db'); - $this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $this->dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $pageSettings = new PageSettings( new UserPreferences($this->dbi, new Relation($this->dbi), new Template()), diff --git a/tests/classes/Controllers/Table/StructureControllerTest.php b/tests/classes/Controllers/Table/StructureControllerTest.php index d7b8321169..8bddfb49fb 100644 --- a/tests/classes/Controllers/Table/StructureControllerTest.php +++ b/tests/classes/Controllers/Table/StructureControllerTest.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Tests\Controllers\Table; +use PhpMyAdmin\Charsets; use PhpMyAdmin\Config; use PhpMyAdmin\Config\PageSettings; use PhpMyAdmin\ConfigStorage\Relation; @@ -52,9 +53,11 @@ class StructureControllerTest extends AbstractTestCase $config->settings['ShowPropertyComments'] = false; (new ReflectionProperty(Relation::class, 'cache'))->setValue(null, null); (new ReflectionProperty(Template::class, 'twig'))->setValue(null, null); + (new ReflectionProperty(Charsets::class, 'collations'))->setValue(null, []); $this->dummyDbi->addSelectDb('test_db'); $this->dummyDbi->addSelectDb('test_db'); + $this->dummyDbi->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [[1]]); $this->dummyDbi->addResult( 'SHOW COLLATION', [ @@ -160,5 +163,8 @@ class StructureControllerTest extends AbstractTestCase ]); $this->assertSame($expected, $response->getHTMLResult()); + + $this->dummyDbi->assertAllSelectsConsumed(); + $this->dummyDbi->assertAllQueriesConsumed(); } } diff --git a/tests/classes/Controllers/Table/ZoomSearchControllerTest.php b/tests/classes/Controllers/Table/ZoomSearchControllerTest.php index 2998b68e8c..e00e2487d9 100644 --- a/tests/classes/Controllers/Table/ZoomSearchControllerTest.php +++ b/tests/classes/Controllers/Table/ZoomSearchControllerTest.php @@ -30,7 +30,7 @@ final class ZoomSearchControllerTest extends AbstractTestCase $dbi = $this->createDatabaseInterface($dbiDummy); $dbiDummy->addSelectDb('test_db'); - $dbiDummy->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']); @@ -76,7 +76,7 @@ final class ZoomSearchControllerTest extends AbstractTestCase $dbi = $this->createDatabaseInterface($dbiDummy); $dbiDummy->addSelectDb('test_db'); - $dbiDummy->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']) diff --git a/tests/classes/DbTableExistsTest.php b/tests/classes/DbTableExistsTest.php index a9dcbf5ed0..09eceb4f6b 100644 --- a/tests/classes/DbTableExistsTest.php +++ b/tests/classes/DbTableExistsTest.php @@ -20,9 +20,7 @@ final class DbTableExistsTest extends AbstractTestCase $dbiDummy->addSelectDb('test_db'); $dbi = $this->createDatabaseInterface($dbiDummy); $dbTableExists = new DbTableExists($dbi); - $this->assertTrue($dbTableExists->hasDatabase(DatabaseName::from('test_db'))); - // cached result - $this->assertTrue($dbTableExists->hasDatabase(DatabaseName::from('test_db'))); + $this->assertTrue($dbTableExists->selectDatabase(DatabaseName::from('test_db'))); $dbiDummy->assertAllSelectsConsumed(); } @@ -32,19 +30,17 @@ final class DbTableExistsTest extends AbstractTestCase $dbi = $this->createMock(DatabaseInterface::class); $dbi->expects($this->once())->method('selectDb')->with($db)->willReturn(false); $dbTableExists = new DbTableExists($dbi); - $this->assertFalse($dbTableExists->hasDatabase($db)); + $this->assertFalse($dbTableExists->selectDatabase($db)); } public function testHasTable(): void { $dbiDummy = $this->createDbiDummy(); $dbiDummy->removeDefaultResults(); - $dbiDummy->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']], ['Tables_in_test_db (test_table)']); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); $dbi = $this->createDatabaseInterface($dbiDummy); - $dbi->getCache()->clearTableCache(); $dbTableExists = new DbTableExists($dbi); $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); - $dbi->getCache()->clearTableCache(); // cached result $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); $dbiDummy->assertAllQueriesConsumed(); @@ -54,39 +50,21 @@ final class DbTableExistsTest extends AbstractTestCase { $dbiDummy = $this->createDbiDummy(); $dbiDummy->removeDefaultResults(); - $dbiDummy->addResult('SHOW TABLES LIKE \'test_table\';', [], ['Tables_in_test_db (test_table)']); - $dbiDummy->addResult('SELECT 1 FROM `test_table` LIMIT 1;', [['1']], ['1']); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']], ['1']); $dbi = $this->createDatabaseInterface($dbiDummy); - $dbi->getCache()->clearTableCache(); $dbTableExists = new DbTableExists($dbi); $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); - $dbi->getCache()->clearTableCache(); // cached result $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); $dbiDummy->assertAllQueriesConsumed(); } - public function testHasTableWithDbiCache(): void - { - $dbiDummy = $this->createDbiDummy(); - $dbiDummy->removeDefaultResults(); - $dbi = $this->createDatabaseInterface($dbiDummy); - $dbi->getCache()->cacheTableContent(['test_db', 'test_table'], ['test_table']); - $dbTableExists = new DbTableExists($dbi); - $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); - $dbi->getCache()->clearTableCache(); - // cached result - $this->assertTrue($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); - } - public function testHasTableWithNoTable(): void { $dbiDummy = $this->createDbiDummy(); $dbiDummy->removeDefaultResults(); - $dbiDummy->addResult('SHOW TABLES LIKE \'test_table\';', false); - $dbiDummy->addResult('SELECT 1 FROM `test_table` LIMIT 1;', false); + $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', false); $dbi = $this->createDatabaseInterface($dbiDummy); - $dbi->getCache()->clearTableCache(); $dbTableExists = new DbTableExists($dbi); $this->assertFalse($dbTableExists->hasTable(DatabaseName::from('test_db'), TableName::from('test_table'))); $dbiDummy->assertAllQueriesConsumed();