Fix bookmarks not being properly saved

Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.com.br>
This commit is contained in:
Maurício Meneghini Fauth 2026-05-22 19:32:03 -03:00
parent 28778d272a
commit f6d656b6a3
No known key found for this signature in database
GPG Key ID: 6A16FD38AFC89CC8
26 changed files with 139 additions and 192 deletions

View File

@ -385,7 +385,7 @@ return [
VersionInformation::class => ['class' => VersionInformation::class], VersionInformation::class => ['class' => VersionInformation::class],
BookmarkRepository::class => [ BookmarkRepository::class => [
'class' => BookmarkRepository::class, 'class' => BookmarkRepository::class,
'arguments' => [DatabaseInterface::class, Relation::class], 'arguments' => [DatabaseInterface::class, Relation::class, Config::class],
], ],
Console::class => [ Console::class => [
'class' => Console::class, 'class' => Console::class,

View File

@ -186,27 +186,12 @@ parameters:
count: 2 count: 2
path: src/Bookmarks/Bookmark.php path: src/Bookmarks/Bookmark.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 1
path: src/Bookmarks/BookmarkRepository.php
- -
message: '#^Parameter \#1 \$row of method PhpMyAdmin\\Bookmarks\\BookmarkRepository\:\:createFromRow\(\) expects array\<string\>, array\<string\|null\> given\.$#' message: '#^Parameter \#1 \$row of method PhpMyAdmin\\Bookmarks\\BookmarkRepository\:\:createFromRow\(\) expects array\<string\>, array\<string\|null\> given\.$#'
identifier: argument.type identifier: argument.type
count: 3 count: 3
path: src/Bookmarks/BookmarkRepository.php path: src/Bookmarks/BookmarkRepository.php
-
message: '#^Parameter \#2 \$bookmarkFeature of class PhpMyAdmin\\Bookmarks\\Bookmark constructor expects PhpMyAdmin\\ConfigStorage\\Features\\BookmarkFeature, PhpMyAdmin\\ConfigStorage\\Features\\BookmarkFeature\|null given\.$#'
identifier: argument.type
count: 1
path: src/Bookmarks/BookmarkRepository.php
- -
message: '#^Loose comparison via "\=\=" is not allowed\.$#' message: '#^Loose comparison via "\=\=" is not allowed\.$#'
identifier: equal.notAllowed identifier: equal.notAllowed
@ -2505,18 +2490,6 @@ parameters:
count: 1 count: 1
path: src/Controllers/Sql/RelationalValuesController.php path: src/Controllers/Sql/RelationalValuesController.php
-
message: '#^Loose comparison via "\!\=" is not allowed\.$#'
identifier: notEqual.notAllowed
count: 3
path: src/Controllers/Sql/SqlController.php
-
message: '#^Only booleans are allowed in an if condition, bool\|null given\.$#'
identifier: if.condNotBoolean
count: 1
path: src/Controllers/Sql/SqlController.php
- -
message: '#^Parameter \#2 \$signature of static method PhpMyAdmin\\Core\:\:checkSqlQuerySignature\(\) expects string, mixed given\.$#' message: '#^Parameter \#2 \$signature of static method PhpMyAdmin\\Core\:\:checkSqlQuerySignature\(\) expects string, mixed given\.$#'
identifier: argument.type identifier: argument.type
@ -13770,24 +13743,6 @@ parameters:
count: 1 count: 1
path: tests/unit/Advisory/RulesTest.php path: tests/unit/Advisory/RulesTest.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 2
path: tests/unit/Bookmarks/BookmarkTest.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Dbal\\DatabaseInterface\:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 3
path: tests/unit/Bookmarks/BookmarkTest.php
- -
message: '#^Parameter \#2 \$haystack of static method PHPUnit\\Framework\\Assert\:\:assertStringContainsString\(\) expects string, mixed given\.$#' message: '#^Parameter \#2 \$haystack of static method PHPUnit\\Framework\\Assert\:\:assertStringContainsString\(\) expects string, mixed given\.$#'
identifier: argument.type identifier: argument.type
@ -14280,15 +14235,6 @@ parameters:
count: 1 count: 1
path: tests/unit/Controllers/CheckRelationsControllerTest.php path: tests/unit/Controllers/CheckRelationsControllerTest.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 2
path: tests/unit/Controllers/Console/Bookmark/AddControllerTest.php
- -
message: ''' message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\: #^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:

View File

@ -30,17 +30,11 @@
</PossiblyUnusedReturnValue> </PossiblyUnusedReturnValue>
</file> </file>
<file src="src/Bookmarks/BookmarkRepository.php"> <file src="src/Bookmarks/BookmarkRepository.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<InvalidArgument> <InvalidArgument>
<code><![CDATA[$result]]></code> <code><![CDATA[$result]]></code>
<code><![CDATA[$result]]></code> <code><![CDATA[$result]]></code>
<code><![CDATA[$row]]></code> <code><![CDATA[$row]]></code>
</InvalidArgument> </InvalidArgument>
<PossiblyNullArgument>
<code><![CDATA[$this->bookmarkFeature]]></code>
</PossiblyNullArgument>
</file> </file>
<file src="src/Cache.php"> <file src="src/Cache.php">
<MixedAssignment> <MixedAssignment>
@ -8629,15 +8623,6 @@
<code><![CDATA[testAdvisorBytime]]></code> <code><![CDATA[testAdvisorBytime]]></code>
</PossiblyInvalidArgument> </PossiblyInvalidArgument>
</file> </file>
<file src="tests/unit/Bookmarks/BookmarkTest.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
</DeprecatedMethod>
</file>
<file src="tests/unit/BrowseForeignersTest.php"> <file src="tests/unit/BrowseForeignersTest.php">
<MixedArgument> <MixedArgument>
<code><![CDATA[$result]]></code> <code><![CDATA[$result]]></code>
@ -9004,12 +8989,6 @@
<code><![CDATA[Config::getInstance()]]></code> <code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod> </DeprecatedMethod>
</file> </file>
<file src="tests/unit/Controllers/Console/Bookmark/AddControllerTest.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
</file>
<file src="tests/unit/Controllers/Console/Bookmark/RefreshControllerTest.php"> <file src="tests/unit/Controllers/Console/Bookmark/RefreshControllerTest.php">
<DeprecatedMethod> <DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code> <code><![CDATA[Config::getInstance()]]></code>

View File

@ -10,6 +10,7 @@ namespace PhpMyAdmin\Bookmarks;
use PhpMyAdmin\Config; use PhpMyAdmin\Config;
use PhpMyAdmin\ConfigStorage\Features\BookmarkFeature; use PhpMyAdmin\ConfigStorage\Features\BookmarkFeature;
use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\ConfigStorage\RelationParameters;
use PhpMyAdmin\Dbal\ConnectionType; use PhpMyAdmin\Dbal\ConnectionType;
use PhpMyAdmin\Dbal\DatabaseInterface; use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Identifiers\DatabaseName; use PhpMyAdmin\Identifiers\DatabaseName;
@ -20,13 +21,13 @@ use PhpMyAdmin\Util;
*/ */
final class BookmarkRepository final class BookmarkRepository
{ {
private BookmarkFeature|null $bookmarkFeature; private RelationParameters|null $relationParameters = null;
private readonly Config $config;
public function __construct(private DatabaseInterface $dbi, Relation $relation) public function __construct(
{ private readonly DatabaseInterface $dbi,
$this->bookmarkFeature = $relation->getRelationParameters()->bookmarkFeature; private readonly Relation $relation,
$this->config = Config::getInstance(); private readonly Config $config,
) {
} }
/** /**
@ -41,7 +42,8 @@ final class BookmarkRepository
string $database, string $database,
bool $shared = false, bool $shared = false,
): Bookmark|false { ): Bookmark|false {
if ($this->bookmarkFeature === null) { $bookmarkFeature = $this->getBookmarkFeature();
if ($bookmarkFeature === null) {
return false; return false;
} }
@ -57,7 +59,7 @@ final class BookmarkRepository
return false; return false;
} }
return new Bookmark($this->dbi, $this->bookmarkFeature, $database, $shared ? '' : $user, $label, $sqlQuery); return new Bookmark($this->dbi, $bookmarkFeature, $database, $shared ? '' : $user, $label, $sqlQuery);
} }
/** /**
@ -74,14 +76,15 @@ final class BookmarkRepository
string $user, string $user,
string|false $db = false, string|false $db = false,
): array { ): array {
if ($this->bookmarkFeature === null) { $bookmarkFeature = $this->getBookmarkFeature();
if ($bookmarkFeature === null) {
return []; return [];
} }
$exactUserMatch = ! $this->config->config->AllowSharedBookmarks; $exactUserMatch = ! $this->config->config->AllowSharedBookmarks;
$query = 'SELECT * FROM ' . Util::backquote($this->bookmarkFeature->database) $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database)
. '.' . Util::backquote($this->bookmarkFeature->bookmark) . '.' . Util::backquote($bookmarkFeature->bookmark)
. ' WHERE (`user` = ' . $this->dbi->quoteString($user); . ' WHERE (`user` = ' . $this->dbi->quoteString($user);
if (! $exactUserMatch) { if (! $exactUserMatch) {
$query .= " OR `user` = ''"; $query .= " OR `user` = ''";
@ -99,7 +102,7 @@ final class BookmarkRepository
$bookmarks = []; $bookmarks = [];
foreach ($result as $row) { foreach ($result as $row) {
$bookmarks[] = $this->createFromRow($row); $bookmarks[] = $this->createFromRow($row, $bookmarkFeature);
} }
return $bookmarks; return $bookmarks;
@ -112,12 +115,13 @@ final class BookmarkRepository
string|null $user, string|null $user,
int $id, int $id,
): Bookmark|null { ): Bookmark|null {
if ($this->bookmarkFeature === null) { $bookmarkFeature = $this->getBookmarkFeature();
if ($bookmarkFeature === null) {
return null; return null;
} }
$query = 'SELECT * FROM ' . Util::backquote($this->bookmarkFeature->database) $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database)
. '.' . Util::backquote($this->bookmarkFeature->bookmark) . '.' . Util::backquote($bookmarkFeature->bookmark)
. ' WHERE `id` = ' . $id; . ' WHERE `id` = ' . $id;
if ($user !== null) { if ($user !== null) {
@ -135,7 +139,7 @@ final class BookmarkRepository
$result = $this->dbi->fetchSingleRow($query, DatabaseInterface::FETCH_ASSOC, ConnectionType::ControlUser); $result = $this->dbi->fetchSingleRow($query, DatabaseInterface::FETCH_ASSOC, ConnectionType::ControlUser);
if ($result !== []) { if ($result !== []) {
return $this->createFromRow($result); return $this->createFromRow($result, $bookmarkFeature);
} }
return null; return null;
@ -149,12 +153,13 @@ final class BookmarkRepository
DatabaseName $db, DatabaseName $db,
string $label, string $label,
): Bookmark|null { ): Bookmark|null {
if ($this->bookmarkFeature === null) { $bookmarkFeature = $this->getBookmarkFeature();
if ($bookmarkFeature === null) {
return null; return null;
} }
$query = 'SELECT * FROM ' . Util::backquote($this->bookmarkFeature->database) $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database)
. '.' . Util::backquote($this->bookmarkFeature->bookmark) . '.' . Util::backquote($bookmarkFeature->bookmark)
. ' WHERE `label`' . ' WHERE `label`'
. ' = ' . $this->dbi->quoteString($label) . ' = ' . $this->dbi->quoteString($label)
. ' AND dbase = ' . $this->dbi->quoteString($db->getName()) . ' AND dbase = ' . $this->dbi->quoteString($db->getName())
@ -163,18 +168,18 @@ final class BookmarkRepository
$result = $this->dbi->fetchSingleRow($query, DatabaseInterface::FETCH_ASSOC, ConnectionType::ControlUser); $result = $this->dbi->fetchSingleRow($query, DatabaseInterface::FETCH_ASSOC, ConnectionType::ControlUser);
if ($result !== []) { if ($result !== []) {
return $this->createFromRow($result); return $this->createFromRow($result, $bookmarkFeature);
} }
return null; return null;
} }
/** @param string[] $row Resource used to build the bookmark */ /** @param string[] $row Resource used to build the bookmark */
private function createFromRow(array $row): Bookmark private function createFromRow(array $row, BookmarkFeature $bookmarkFeature): Bookmark
{ {
return new Bookmark( return new Bookmark(
$this->dbi, $this->dbi,
$this->bookmarkFeature, $bookmarkFeature,
$row['dbase'], $row['dbase'],
$row['user'], $row['user'],
$row['label'], $row['label'],
@ -182,4 +187,13 @@ final class BookmarkRepository
(int) $row['id'], (int) $row['id'],
); );
} }
private function getBookmarkFeature(): BookmarkFeature|null
{
if ($this->relationParameters === null) {
$this->relationParameters = $this->relation->getRelationParameters();
}
return $this->relationParameters->bookmarkFeature;
}
} }

View File

@ -23,6 +23,7 @@ use PhpMyAdmin\Url;
use PhpMyAdmin\UrlParams; use PhpMyAdmin\UrlParams;
use function __; use function __;
use function is_array;
use function is_string; use function is_string;
use function mb_strpos; use function mb_strpos;
use function str_contains; use function str_contains;
@ -78,13 +79,12 @@ readonly class SqlController implements InvocableController
$errorUrl .= '&amp;table=' . urlencode(Current::$table); $errorUrl .= '&amp;table=' . urlencode(Current::$table);
} }
/** @var array<string>|null $bkmFields */ $bookmarkFields = $this->getBookmarkFields($request->getParsedBodyParam('bkm_fields'));
$bkmFields = $request->getParsedBodyParam('bkm_fields');
$sqlQuery = $request->getParsedBodyParamAsStringOrNull('sql_query'); $sqlQuery = $request->getParsedBodyParamAsStringOrNull('sql_query');
// Coming from a bookmark dialog // Coming from a bookmark dialog
if ($bkmFields !== null && $bkmFields['bkm_sql_query'] != null) { if (isset($bookmarkFields['bkm_sql_query'])) {
Current::$sqlQuery = $bkmFields['bkm_sql_query']; Current::$sqlQuery = $bookmarkFields['bkm_sql_query'];
} elseif ($sqlQuery !== null) { } elseif ($sqlQuery !== null) {
Current::$sqlQuery = $sqlQuery; Current::$sqlQuery = $sqlQuery;
} elseif ($request->hasQueryParam('sql_query') && $request->hasQueryParam('sql_signature')) { } elseif ($request->hasQueryParam('sql_query') && $request->hasQueryParam('sql_signature')) {
@ -98,8 +98,8 @@ readonly class SqlController implements InvocableController
} }
// This one is just to fill $db // This one is just to fill $db
if ($bkmFields !== null && $bkmFields['bkm_database'] != null) { if (isset($bookmarkFields['bkm_database'])) {
Current::$database = $bkmFields['bkm_database']; Current::$database = $bookmarkFields['bkm_database'];
} }
// Default to browse if no query set and we have table // Default to browse if no query set and we have table
@ -122,7 +122,7 @@ readonly class SqlController implements InvocableController
$request->isAjax(), $request->isAjax(),
); );
if (Current::$table != $tableFromSql && $tableFromSql !== '') { if (Current::$table !== $tableFromSql && $tableFromSql !== '') {
Current::$table = $tableFromSql; Current::$table = $tableFromSql;
} }
@ -157,8 +157,8 @@ readonly class SqlController implements InvocableController
*/ */
$storeBkm = $request->hasBodyParam('store_bkm'); $storeBkm = $request->hasBodyParam('store_bkm');
$bkmAllUsers = $request->getParsedBodyParam('bkm_all_users'); // Should this be hasBodyParam? $bkmAllUsers = $request->getParsedBodyParam('bkm_all_users'); // Should this be hasBodyParam?
if ($storeBkm && $bkmFields !== null) { if ($storeBkm) {
return $this->addBookmark(UrlParams::$goto, $bkmFields, (bool) $bkmAllUsers); return $this->addBookmark(UrlParams::$goto, $bookmarkFields, (bool) $bkmAllUsers);
} }
/** /**
@ -192,31 +192,31 @@ readonly class SqlController implements InvocableController
return $this->response->response(); return $this->response->response();
} }
/** @param array<string> $bkmFields */ /** @param array<string> $bookmarkFields */
private function addBookmark(string $goto, array $bkmFields, bool $bkmAllUsers): Response private function addBookmark(string $goto, array $bookmarkFields, bool $bkmAllUsers): Response
{ {
$bookmark = $this->bookmarkRepository->createBookmark( $bookmark = $this->bookmarkRepository->createBookmark(
$bkmFields['bkm_sql_query'], $bookmarkFields['bkm_sql_query'] ?? '',
$bkmFields['bkm_label'], $bookmarkFields['bkm_label'] ?? '',
$bkmFields['bkm_user'], $bookmarkFields['bkm_user'] ?? '',
$bkmFields['bkm_database'], $bookmarkFields['bkm_database'] ?? '',
$bkmAllUsers, $bkmAllUsers,
); );
$result = null; $result = false;
if ($bookmark !== false) { if ($bookmark !== false) {
$result = $bookmark->save(); $result = $bookmark->save();
} }
if (! $this->response->isAjax()) { if (! $this->response->isAjax()) {
$this->response->redirect('./' . $goto . '&label=' . $bkmFields['bkm_label']); $this->response->redirect('./' . $goto . '&label=' . $bookmarkFields['bkm_label']);
return $this->response->response(); return $this->response->response();
} }
if ($result) { if ($result) {
$msg = Message::success(__('Bookmark %s has been created.')); $msg = Message::success(__('Bookmark %s has been created.'));
$msg->addParam($bkmFields['bkm_label']); $msg->addParam($bookmarkFields['bkm_label']);
$this->response->addJSON('message', $msg); $this->response->addJSON('message', $msg);
return $this->response->response(); return $this->response->response();
@ -228,4 +228,23 @@ readonly class SqlController implements InvocableController
return $this->response->response(); return $this->response->response();
} }
/** @return array{bkm_label?: string, bkm_database?: string, bkm_sql_query?: string, bkm_user?: string} */
private function getBookmarkFields(mixed $param): array
{
if (! is_array($param)) {
return [];
}
$fields = [];
foreach (['bkm_label', 'bkm_database', 'bkm_sql_query', 'bkm_user'] as $key) {
if (! isset($param[$key]) || ! is_string($param[$key])) {
continue;
}
$fields[$key] = $param[$key];
}
return $fields;
}
} }

View File

@ -23,8 +23,9 @@ final class BookmarkRepositoryTest extends AbstractTestCase
RelationParameters::BOOKMARK => 'pma_bookmark', RelationParameters::BOOKMARK => 'pma_bookmark',
]); ]);
(new ReflectionProperty(Relation::class, 'cache'))->setValue(null, $relationParameters); (new ReflectionProperty(Relation::class, 'cache'))->setValue(null, $relationParameters);
$config = new Config();
$dbi = $this->createDatabaseInterface(); $dbi = $this->createDatabaseInterface();
$bookmarkRepository = new BookmarkRepository($dbi, new Relation($dbi, new Config())); $bookmarkRepository = new BookmarkRepository($dbi, new Relation($dbi, $config), $config);
$bookmark = $bookmarkRepository->createBookmark('SELECT "phpmyadmin"', 'bookmark1', 'root', 'phpmyadmin'); $bookmark = $bookmarkRepository->createBookmark('SELECT "phpmyadmin"', 'bookmark1', 'root', 'phpmyadmin');
self::assertNotFalse($bookmark); self::assertNotFalse($bookmark);
self::assertSame(0, $bookmark->getId()); self::assertSame(0, $bookmark->getId());

View File

@ -9,19 +9,13 @@ use PhpMyAdmin\Bookmarks\BookmarkRepository;
use PhpMyAdmin\Config; use PhpMyAdmin\Config;
use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\ConfigStorage\RelationParameters; use PhpMyAdmin\ConfigStorage\RelationParameters;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tests\Stubs\DbiDummy;
use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\CoversClass;
use ReflectionProperty; use ReflectionProperty;
#[CoversClass(Bookmark::class)] #[CoversClass(Bookmark::class)]
class BookmarkTest extends AbstractTestCase class BookmarkTest extends AbstractTestCase
{ {
protected DatabaseInterface $dbi;
protected DbiDummy $dummyDbi;
/** /**
* Sets up the fixture, for example, opens a network connection. * Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed. * This method is called before a test is executed.
@ -30,10 +24,6 @@ class BookmarkTest extends AbstractTestCase
{ {
parent::setUp(); parent::setUp();
$this->dummyDbi = $this->createDbiDummy();
$this->dbi = $this->createDatabaseInterface($this->dummyDbi);
DatabaseInterface::$instance = $this->dbi;
$relationParameters = RelationParameters::fromArray([ $relationParameters = RelationParameters::fromArray([
RelationParameters::BOOKMARK_WORK => true, RelationParameters::BOOKMARK_WORK => true,
RelationParameters::DATABASE => 'phpmyadmin', RelationParameters::DATABASE => 'phpmyadmin',
@ -47,19 +37,19 @@ class BookmarkTest extends AbstractTestCase
*/ */
public function testGetList(): void public function testGetList(): void
{ {
$this->dummyDbi->addResult( $dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
'SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE (`user` = \'root\' OR `user` = \'\')' 'SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE (`user` = \'root\' OR `user` = \'\')'
. ' AND dbase = \'sakila\' ORDER BY label ASC', . ' AND dbase = \'sakila\' ORDER BY label ASC',
[['1', 'sakila', 'root', 'label', 'SELECT * FROM `actor` WHERE `actor_id` < 10;']], [['1', 'sakila', 'root', 'label', 'SELECT * FROM `actor` WHERE `actor_id` < 10;']],
['id', 'dbase', 'user', 'label', 'query'], ['id', 'dbase', 'user', 'label', 'query'],
); );
$dbi = DatabaseInterface::getInstance(); $config = new Config();
$actual = (new BookmarkRepository($dbi, new Relation($dbi)))->getList( $dbi = $this->createDatabaseInterface($dbiDummy, $config);
Config::getInstance()->selectedServer['user'], $bookmarkRepository = new BookmarkRepository($dbi, new Relation($dbi, $config), $config);
'sakila', $actual = $bookmarkRepository->getList($config->selectedServer['user'], 'sakila');
);
self::assertContainsOnlyInstancesOf(Bookmark::class, $actual); self::assertContainsOnlyInstancesOf(Bookmark::class, $actual);
$this->dummyDbi->assertAllSelectsConsumed(); $dbiDummy->assertAllSelectsConsumed();
} }
/** /**
@ -67,18 +57,16 @@ class BookmarkTest extends AbstractTestCase
*/ */
public function testGet(): void public function testGet(): void
{ {
$this->dummyDbi->addResult( $dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
"SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE `id` = 1 AND (user = 'root' OR user = '') LIMIT 1", "SELECT * FROM `phpmyadmin`.`pma_bookmark` WHERE `id` = 1 AND (user = 'root' OR user = '') LIMIT 1",
[], [],
['id', 'dbase', 'user', 'label', 'query'], ['id', 'dbase', 'user', 'label', 'query'],
); );
$dbi = DatabaseInterface::getInstance(); $config = new Config();
self::assertNull( $dbi = $this->createDatabaseInterface($dbiDummy, $config);
(new BookmarkRepository($dbi, new Relation($dbi)))->get( $bookmarkRepository = new BookmarkRepository($dbi, new Relation($dbi, $config), $config);
Config::getInstance()->selectedServer['user'], self::assertNull($bookmarkRepository->get($config->selectedServer['user'], 1));
1,
),
);
} }
/** /**
@ -86,18 +74,17 @@ class BookmarkTest extends AbstractTestCase
*/ */
public function testSave(): void public function testSave(): void
{ {
$this->dummyDbi->addResult( $dbiDummy = $this->createDbiDummy();
$dbiDummy->addResult(
'INSERT INTO `phpmyadmin`.`pma_bookmark` (id, dbase, user, query, label)' . 'INSERT INTO `phpmyadmin`.`pma_bookmark` (id, dbase, user, query, label)' .
" VALUES (NULL, 'phpmyadmin', 'root', 'SELECT \\\"phpmyadmin\\\"', 'bookmark1')", " VALUES (NULL, 'phpmyadmin', 'root', 'SELECT \\\"phpmyadmin\\\"', 'bookmark1')",
true, true,
); );
$dbi = DatabaseInterface::getInstance(); $config = new Config();
$bookmark = (new BookmarkRepository($dbi, new Relation($dbi)))->createBookmark( $dbi = $this->createDatabaseInterface($dbiDummy, $config);
'SELECT "phpmyadmin"', $relation = new Relation($dbi, $config);
'bookmark1', $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
'root', $bookmark = $bookmarkRepository->createBookmark('SELECT "phpmyadmin"', 'bookmark1', 'root', 'phpmyadmin');
'phpmyadmin',
);
self::assertNotFalse($bookmark); self::assertNotFalse($bookmark);
self::assertTrue($bookmark->save()); self::assertTrue($bookmark->save());
} }

View File

@ -22,7 +22,7 @@ class ConsoleTest extends AbstractTestCase
$dbi = DatabaseInterface::getInstance(); $dbi = DatabaseInterface::getInstance();
$config = Config::getInstance(); $config = Config::getInstance();
$relation = new Relation($dbi); $relation = new Relation($dbi);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$history = new History($dbi, $relation, $config); $history = new History($dbi, $relation, $config);
$console = new Console($relation, new Template($config), $bookmarkRepository, $history); $console = new Console($relation, new Template($config), $bookmarkRepository, $history);
self::assertSame(['console.js'], $console->getScripts()); self::assertSame(['console.js'], $console->getScripts());

View File

@ -23,6 +23,7 @@ class AddControllerTest extends AbstractTestCase
{ {
public function testWithInvalidParams(): void public function testWithInvalidParams(): void
{ {
$config = new Config();
$dbi = $this->createDatabaseInterface(); $dbi = $this->createDatabaseInterface();
DatabaseInterface::$instance = $dbi; DatabaseInterface::$instance = $dbi;
$response = new ResponseRenderer(); $response = new ResponseRenderer();
@ -33,24 +34,24 @@ class AddControllerTest extends AbstractTestCase
'bookmark_query' => null, 'bookmark_query' => null,
'shared' => null, 'shared' => null,
]); ]);
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$controller = new AddController($response, $bookmarkRepository, new Config()); $controller = new AddController($response, $bookmarkRepository, $config);
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
$controller($request); $controller($request);
} }
public function testWithoutRelationParameters(): void public function testWithoutRelationParameters(): void
{ {
$config = Config::getInstance(); $config = new Config();
$config->selectedServer['user'] = 'user'; $config->selectedServer['user'] = 'user';
(new ReflectionProperty(Relation::class, 'cache'))->setValue(null, null); (new ReflectionProperty(Relation::class, 'cache'))->setValue(null, null);
$dbi = $this->createDatabaseInterface(); $dbi = $this->createDatabaseInterface();
DatabaseInterface::$instance = $dbi; DatabaseInterface::$instance = $dbi;
$response = new ResponseRenderer(); $response = new ResponseRenderer();
$request = self::createStub(ServerRequest::class); $request = self::createStub(ServerRequest::class);
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$controller = new AddController($response, $bookmarkRepository, $config); $controller = new AddController($response, $bookmarkRepository, $config);
$controller($request); $controller($request);
self::assertSame(['message' => 'Failed'], $response->getJSONResult()); self::assertSame(['message' => 'Failed'], $response->getJSONResult());
@ -58,7 +59,7 @@ class AddControllerTest extends AbstractTestCase
public function testWithValidParameters(): void public function testWithValidParameters(): void
{ {
$config = Config::getInstance(); $config = new Config();
$config->selectedServer['user'] = 'test_user'; $config->selectedServer['user'] = 'test_user';
$relationParameters = RelationParameters::fromArray([ $relationParameters = RelationParameters::fromArray([
RelationParameters::USER => 'test_user', RelationParameters::USER => 'test_user',
@ -84,8 +85,8 @@ class AddControllerTest extends AbstractTestCase
'bookmark_query' => 'test_query', 'bookmark_query' => 'test_query',
'shared' => 'true', 'shared' => 'true',
]); ]);
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$controller = new AddController($response, $bookmarkRepository, $config); $controller = new AddController($response, $bookmarkRepository, $config);
$controller($request); $controller($request);
self::assertSame( self::assertSame(

View File

@ -26,8 +26,8 @@ class RefreshControllerTest extends AbstractTestCase
$response = new ResponseRenderer(); $response = new ResponseRenderer();
$dbi = DatabaseInterface::getInstance(); $dbi = DatabaseInterface::getInstance();
$config = Config::getInstance(); $config = Config::getInstance();
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$template = new Template($config); $template = new Template($config);
$history = new History($dbi, $relation, $config); $history = new History($dbi, $relation, $config);
$controller = new RefreshController( $controller = new RefreshController(

View File

@ -75,7 +75,7 @@ final class QueryControllerTest extends AbstractTestCase
new RelationCleanup($dbi, $relation), new RelationCleanup($dbi, $relation),
new Transformations($dbi, $relation), new Transformations($dbi, $relation),
new Template($config), new Template($config),
new BookmarkRepository($dbi, $relation), new BookmarkRepository($dbi, $relation, $config),
$config, $config,
$responseRenderer, $responseRenderer,
); );

View File

@ -56,7 +56,7 @@ final class SqlControllerTest extends AbstractTestCase
return new SqlController( return new SqlController(
$responseRenderer, $responseRenderer,
new SqlQueryForm($template, $dbi, new BookmarkRepository($dbi, $relation)), new SqlQueryForm($template, $dbi, new BookmarkRepository($dbi, $relation, $config)),
new PageSettings(new UserPreferences($dbi, $relation, $template, $config, new Clock()), $responseRenderer), new PageSettings(new UserPreferences($dbi, $relation, $template, $config, new Clock()), $responseRenderer),
new DbTableExists($dbi), new DbTableExists($dbi),
); );

View File

@ -71,7 +71,7 @@ final class TrackingControllerTest extends AbstractTestCase
return new TrackingController( return new TrackingController(
new ResponseRenderer(), new ResponseRenderer(),
new Tracking( new Tracking(
new SqlQueryForm($template, $dbi, new BookmarkRepository($dbi, $relation)), new SqlQueryForm($template, $dbi, new BookmarkRepository($dbi, $relation, $config)),
$template, $template,
$relation, $relation,
$dbi, $dbi,

View File

@ -85,8 +85,8 @@ class ImportControllerTest extends AbstractTestCase
); );
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$template = new Template($config); $template = new Template($config);
$sql = new Sql( $sql = new Sql(
$this->dbi, $this->dbi,

View File

@ -62,8 +62,8 @@ class EnumValuesControllerTest extends AbstractTestCase
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$config = Config::getInstance(); $config = Config::getInstance();
$template = new Template($config); $template = new Template($config);
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$sql = new Sql( $sql = new Sql(
$this->dbi, $this->dbi,
$relation, $relation,
@ -125,8 +125,8 @@ class EnumValuesControllerTest extends AbstractTestCase
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$config = Config::getInstance(); $config = Config::getInstance();
$template = new Template($config); $template = new Template($config);
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$sql = new Sql( $sql = new Sql(
$this->dbi, $this->dbi,
$relation, $relation,

View File

@ -62,8 +62,8 @@ class SetValuesControllerTest extends AbstractTestCase
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$config = Config::getInstance(); $config = Config::getInstance();
$template = new Template($config); $template = new Template($config);
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$sql = new Sql( $sql = new Sql(
$this->dbi, $this->dbi,
$relation, $relation,
@ -125,8 +125,8 @@ class SetValuesControllerTest extends AbstractTestCase
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$config = Config::getInstance(); $config = Config::getInstance();
$template = new Template($config); $template = new Template($config);
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$sql = new Sql( $sql = new Sql(
$this->dbi, $this->dbi,
$relation, $relation,

View File

@ -69,7 +69,7 @@ class DeleteRowsControllerTest extends AbstractTestCase
new RelationCleanup($dbi, $relation), new RelationCleanup($dbi, $relation),
new Transformations($dbi, $relation), new Transformations($dbi, $relation),
new Template($config), new Template($config),
new BookmarkRepository($dbi, $relation), new BookmarkRepository($dbi, $relation, $config),
$config, $config,
$response, $response,
); );

View File

@ -96,13 +96,13 @@ class ReplaceControllerTest extends AbstractTestCase
$dummyDbi = $this->createDbiDummy(); $dummyDbi = $this->createDbiDummy();
$dbi = $this->createDatabaseInterface($dummyDbi); $dbi = $this->createDatabaseInterface($dummyDbi);
$config = Config::getInstance(); $config = Config::getInstance();
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$transformations = new Transformations($dbi, $relation); $transformations = new Transformations($dbi, $relation);
$template = new Template($config); $template = new Template($config);
$response = new ResponseRenderer(); $response = new ResponseRenderer();
$pageSettings = self::createStub(PageSettings::class); $pageSettings = self::createStub(PageSettings::class);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$sqlController = new SqlController( $sqlController = new SqlController(
$response, $response,
new Sql( new Sql(

View File

@ -54,7 +54,7 @@ final class SearchControllerTest extends AbstractTestCase
new RelationCleanup($dbi, $relation), new RelationCleanup($dbi, $relation),
new Transformations($dbi, $relation), new Transformations($dbi, $relation),
$template, $template,
new BookmarkRepository($dbi, $relation), new BookmarkRepository($dbi, $relation, $config),
$config, $config,
$responseRenderer, $responseRenderer,
); );

View File

@ -44,9 +44,10 @@ final class SqlControllerTest extends AbstractTestCase
$dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]); $dbiDummy->addResult('SELECT 1 FROM `test_db`.`test_table` LIMIT 1;', [['1']]);
$template = new Template($config); $template = new Template($config);
$relation = new Relation($dbi, $config);
$userPreferences = new UserPreferences( $userPreferences = new UserPreferences(
$dbi, $dbi,
new Relation($dbi, $config), $relation,
$template, $template,
$config, $config,
new Clock(), new Clock(),
@ -54,8 +55,7 @@ final class SqlControllerTest extends AbstractTestCase
$request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/') $request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/')
->withQueryParams(['db' => 'test_db', 'table' => 'test_table']); ->withQueryParams(['db' => 'test_db', 'table' => 'test_table']);
$relation = new Relation($dbi); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation);
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$response = (new SqlController( $response = (new SqlController(
$responseRenderer, $responseRenderer,

View File

@ -57,8 +57,8 @@ class TrackingControllerTest extends AbstractTestCase
$responseRenderer = new ResponseRenderer(); $responseRenderer = new ResponseRenderer();
$template = new Template($config); $template = new Template($config);
$trackingChecker = self::createStub(TrackingChecker::class); $trackingChecker = self::createStub(TrackingChecker::class);
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi, $config);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$response = (new TrackingController( $response = (new TrackingController(
$responseRenderer, $responseRenderer,
new Tracking( new Tracking(

View File

@ -72,7 +72,7 @@ class HeaderTest extends AbstractTestCase
return new Header( return new Header(
$template, $template,
new Console($relation, $template, new BookmarkRepository($dbi, $relation), $history), new Console($relation, $template, new BookmarkRepository($dbi, $relation, $config), $history),
$config, $config,
$dbi, $dbi,
$relation, $relation,
@ -91,7 +91,7 @@ class HeaderTest extends AbstractTestCase
$relation = new Relation($dbi, $config); $relation = new Relation($dbi, $config);
$template = new Template($config); $template = new Template($config);
$history = new History($dbi, $relation, $config); $history = new History($dbi, $relation, $config);
$console = new Console($relation, $template, new BookmarkRepository($dbi, $relation), $history); $console = new Console($relation, $template, new BookmarkRepository($dbi, $relation, $config), $history);
$userPreferences = new UserPreferences($dbi, $relation, $template, $config, new Clock()); $userPreferences = new UserPreferences($dbi, $relation, $template, $config, new Clock());
$userPreferencesHandler = new UserPreferencesHandler( $userPreferencesHandler = new UserPreferencesHandler(
$config, $config,

View File

@ -56,7 +56,7 @@ class SqlQueryFormTest extends AbstractTestCase
DatabaseInterface::$instance = $this->dbi; DatabaseInterface::$instance = $this->dbi;
$config = Config::getInstance(); $config = Config::getInstance();
$relation = new Relation($this->dbi); $relation = new Relation($this->dbi);
$bookmarkRepository = new BookmarkRepository($this->dbi, $relation); $bookmarkRepository = new BookmarkRepository($this->dbi, $relation, $config);
$this->sqlQueryForm = new SqlQueryForm(new Template($config), $this->dbi, $bookmarkRepository); $this->sqlQueryForm = new SqlQueryForm(new Template($config), $this->dbi, $bookmarkRepository);
Current::$database = 'PMA_db'; Current::$database = 'PMA_db';

View File

@ -60,7 +60,7 @@ class SqlTest extends AbstractTestCase
new RelationCleanup($this->dbi, $relation), new RelationCleanup($this->dbi, $relation),
new Transformations($this->dbi, $relation), new Transformations($this->dbi, $relation),
new Template($config), new Template($config),
new BookmarkRepository($this->dbi, $relation), new BookmarkRepository($this->dbi, $relation, $config),
$config, $config,
new ResponseRenderer(), new ResponseRenderer(),
); );
@ -667,7 +667,7 @@ class SqlTest extends AbstractTestCase
new RelationCleanup($this->dbi, $relation), new RelationCleanup($this->dbi, $relation),
new Transformations($this->dbi, $relation), new Transformations($this->dbi, $relation),
new Template($config), new Template($config),
new BookmarkRepository($this->dbi, $relation), new BookmarkRepository($this->dbi, $relation, $config),
$config, $config,
new ResponseRenderer(), new ResponseRenderer(),
); );

View File

@ -63,7 +63,7 @@ class ResponseRenderer extends \PhpMyAdmin\ResponseRenderer
$dbi = DatabaseInterface::getInstanceForTest($dummyDbi, $config); $dbi = DatabaseInterface::getInstanceForTest($dummyDbi, $config);
$relation = new Relation($dbi, $config); $relation = new Relation($dbi, $config);
$history = new History($dbi, $relation, $config); $history = new History($dbi, $relation, $config);
$console = new Console($relation, $template, new BookmarkRepository($dbi, $relation), $history); $console = new Console($relation, $template, new BookmarkRepository($dbi, $relation, $config), $history);
$userPreferences = new UserPreferences($dbi, $relation, $template, $config, new Clock()); $userPreferences = new UserPreferences($dbi, $relation, $template, $config, new Clock());
$userPreferencesHandler = new UserPreferencesHandler( $userPreferencesHandler = new UserPreferencesHandler(
$config, $config,

View File

@ -65,8 +65,8 @@ final class TrackingTest extends AbstractTestCase
(new ReflectionProperty(Relation::class, 'cache'))->setValue(null, $relationParameters); (new ReflectionProperty(Relation::class, 'cache'))->setValue(null, $relationParameters);
$template = new Template($config); $template = new Template($config);
$relation = new Relation($dbi); $relation = new Relation($dbi, $config);
$bookmarkRepository = new BookmarkRepository($dbi, $relation); $bookmarkRepository = new BookmarkRepository($dbi, $relation, $config);
$this->tracking = new Tracking( $this->tracking = new Tracking(
new SqlQueryForm($template, $dbi, $bookmarkRepository), new SqlQueryForm($template, $dbi, $bookmarkRepository),
$template, $template,