Merge pull request #18259 from kamil-tekiela/Tracking

Refactor and optimize Tracking
This commit is contained in:
Maurício Meneghini Fauth 2023-03-18 04:58:03 -03:00 committed by GitHub
commit 3f125939c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 403 additions and 495 deletions

View File

@ -19,6 +19,7 @@ use PhpMyAdmin\Plugins\AuthenticationPlugin;
use PhpMyAdmin\Plugins\AuthenticationPluginFactory;
use PhpMyAdmin\SqlParser\Lexer;
use PhpMyAdmin\Theme\ThemeManager;
use PhpMyAdmin\Tracking\Tracker;
use RuntimeException;
use Symfony\Component\DependencyInjection\ContainerInterface;

View File

@ -20,7 +20,9 @@ use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\StorageEngine;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking\TrackedTable;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Tracking\TrackingChecker;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
@ -74,6 +76,7 @@ class StructureController extends AbstractController
private Relation $relation,
private Replication $replication,
private DatabaseInterface $dbi,
private TrackingChecker $trackingChecker,
) {
parent::__construct($response, $template);
@ -221,6 +224,7 @@ class StructureController extends AbstractController
$hiddenFields = [];
$overallApproxRows = false;
$structureTableRows = [];
$trackedTables = $this->trackingChecker->getTrackedTables($GLOBALS['db']);
foreach ($this->tables as $currentTable) {
// Get valid statistics whatever is the table type
@ -396,7 +400,7 @@ class StructureController extends AbstractController
),
),
),
'tracking_icon' => $this->getTrackingIcon($truename),
'tracking_icon' => $this->getTrackingIcon($truename, $trackedTables[$truename] ?? null),
'server_replica_status' => $replicaInfo['status'],
'table_url_params' => $tableUrlParams,
'db_is_system_schema' => $this->dbIsSystemSchema,
@ -500,20 +504,17 @@ class StructureController extends AbstractController
/**
* Returns the tracking icon if the table is tracked
*
* @param string $table table name
*
* @return string HTML for tracking icon
*/
protected function getTrackingIcon(string $table): string
protected function getTrackingIcon(string $table, TrackedTable|null $trackedTable): string
{
$trackingIcon = '';
if (Tracker::isActive()) {
$isTracked = Tracker::isTracked($GLOBALS['db'], $table);
if ($isTracked || Tracker::getVersion($GLOBALS['db'], $table) > 0) {
if ($trackedTable !== null) {
$trackingIcon = $this->template->render('database/structure/tracking_icon', [
'db' => $GLOBALS['db'],
'table' => $table,
'is_tracked' => $isTracked,
'is_tracked' => $trackedTable->active,
]);
}
}

View File

@ -13,8 +13,8 @@ use PhpMyAdmin\Message;
use PhpMyAdmin\Query\Utilities;
use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Tracking\Tracking;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;

View File

@ -23,7 +23,7 @@ use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\StorageEngine;
use PhpMyAdmin\Table;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Transformations;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;

View File

@ -12,8 +12,9 @@ use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Message;
use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Tracking\Tracking;
use PhpMyAdmin\Tracking\TrackingChecker;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
use Throwable;
@ -35,6 +36,7 @@ final class TrackingController extends AbstractController
ResponseRenderer $response,
Template $template,
private Tracking $tracking,
private TrackingChecker $trackingChecker,
) {
parent::__construct($response, $template);
}
@ -64,9 +66,11 @@ final class TrackingController extends AbstractController
$toggleActivation = $request->getParsedBodyParam('toggle_activation');
$reportExport = $request->getParsedBodyParam('report_export');
$trackedTables = $this->trackingChecker->getTrackedTables($GLOBALS['db']);
if (
Tracker::isActive()
&& Tracker::isTracked($GLOBALS['db'], $GLOBALS['table'])
&& isset($trackedTables[$GLOBALS['table']])
&& $trackedTables[$GLOBALS['table']]->active
&& $toggleActivation !== 'deactivate_now'
&& $reportExport !== 'sqldumpfile'
) {
@ -209,7 +213,7 @@ final class TrackingController extends AbstractController
$message = $GLOBALS['msg']->getDisplay();
} elseif ($reportExport === 'sqldump') {
$this->addScriptFiles(['sql.js']);
$sqlDump = $this->tracking->exportAsSqlDump($GLOBALS['db'], $GLOBALS['table'], $GLOBALS['entries']);
$sqlDump = $this->tracking->exportAsSqlDump($GLOBALS['entries']);
}
$schemaSnapshot = '';

View File

@ -20,6 +20,7 @@ use PhpMyAdmin\Query\Compatibility;
use PhpMyAdmin\Query\Generator as QueryGenerator;
use PhpMyAdmin\Query\Utilities;
use PhpMyAdmin\SqlParser\Context;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Utils\SessionCache;
use stdClass;

View File

@ -10,6 +10,7 @@ namespace PhpMyAdmin;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Query\Utilities;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Utils\SessionCache;
use function __;

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tracking;
use PhpMyAdmin\Dbal\TableName;
final class TrackedTable
{
public function __construct(public readonly TableName $name, public readonly bool $active)
{
}
}

View File

@ -5,10 +5,12 @@
declare(strict_types=1);
namespace PhpMyAdmin;
namespace PhpMyAdmin\Tracking;
use PhpMyAdmin\Cache;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\Export\ExportSql;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\AlterStatement;
@ -19,6 +21,7 @@ use PhpMyAdmin\SqlParser\Statements\InsertStatement;
use PhpMyAdmin\SqlParser\Statements\RenameStatement;
use PhpMyAdmin\SqlParser\Statements\TruncateStatement;
use PhpMyAdmin\SqlParser\Statements\UpdateStatement;
use PhpMyAdmin\Util;
use function array_values;
use function count;
@ -478,7 +481,7 @@ class Tracker
*
* @return int (-1 if no version exists | > 0 if a version exists)
*/
public static function getVersion(string $dbname, string $tablename, string|null $statement = null): int
private static function getVersion(string $dbname, string $tablename, string|null $statement = null): int
{
$relation = new Relation($GLOBALS['dbi']);
$trackingFeature = $relation->getRelationParameters()->trackingFeature;
@ -800,8 +803,6 @@ class Tracker
*/
public static function handleQuery(string $query): void
{
$relation = new Relation($GLOBALS['dbi']);
// If query is marked as untouchable, leave
if (mb_strstr($query, '/*NOTRACK*/')) {
return;
@ -881,6 +882,7 @@ class Tracker
// Add log information
$query = self::getLogComment() . $query;
$relation = new Relation($GLOBALS['dbi']);
$trackingFeature = $relation->getRelationParameters()->trackingFeature;
if ($trackingFeature === null) {
return;

View File

@ -5,15 +5,21 @@
declare(strict_types=1);
namespace PhpMyAdmin;
namespace PhpMyAdmin\Tracking;
use DateTimeImmutable;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Dbal\ResultInterface;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Message;
use PhpMyAdmin\SqlQueryForm;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
use function __;
use function array_key_exists;
use function array_merge;
use function array_multisort;
use function count;
@ -21,7 +27,6 @@ use function date;
use function htmlspecialchars;
use function in_array;
use function ini_set;
use function is_array;
use function json_encode;
use function mb_strstr;
use function preg_replace;
@ -32,7 +37,7 @@ use function strtotime;
use const SORT_ASC;
/**
* PhpMyAdmin\Tracking class
* PhpMyAdmin\Tracking\Tracking class
*/
class Tracking
{
@ -41,6 +46,7 @@ class Tracking
public Template $template,
protected Relation $relation,
private DatabaseInterface $dbi,
private TrackingChecker $trackingChecker,
) {
}
@ -117,18 +123,6 @@ class Tracking
string $textDir,
int|null $lastVersion = null,
): string {
$selectableTablesSqlResult = $this->getSqlResultForSelectableTables($db);
$selectableTablesEntries = [];
$selectableTablesNumRows = 0;
if ($selectableTablesSqlResult !== false) {
foreach ($selectableTablesSqlResult as $entry) {
$entry['is_tracked'] = Tracker::isTracked($entry['db_name'], $entry['table_name']);
$selectableTablesEntries[] = $entry;
}
$selectableTablesNumRows = $selectableTablesSqlResult->numRows();
}
$versionSqlResult = $this->getListOfVersionsOfTable($db, $table);
if ($lastVersion === null && $versionSqlResult !== false) {
$lastVersion = $this->getTableLastVersionNumber($versionSqlResult);
@ -145,8 +139,7 @@ class Tracking
'url_params' => $urlParams,
'db' => $db,
'table' => $table,
'selectable_tables_num_rows' => $selectableTablesNumRows,
'selectable_tables_entries' => $selectableTablesEntries,
'selectable_tables_entries' => $this->trackingChecker->getTrackedTables($db),
'selected_table' => $_POST['table'] ?? null,
'last_version' => $lastVersion,
'versions' => $versions,
@ -164,24 +157,6 @@ class Tracking
return (int) $result->fetchValue('version');
}
/**
* Function to get sql results for selectable tables
*/
public function getSqlResultForSelectableTables(string $db): ResultInterface|false
{
$trackingFeature = $this->relation->getRelationParameters()->trackingFeature;
if ($trackingFeature === null) {
return false;
}
$sql_query = ' SELECT DISTINCT db_name, table_name FROM '
. Util::backquote($trackingFeature->database) . '.' . Util::backquote($trackingFeature->tracking)
. " WHERE db_name = '" . $this->dbi->escapeString($db) . "' "
. ' ORDER BY db_name, table_name';
return $this->dbi->queryAsControlUser($sql_query);
}
/**
* Function to get html for tracking report and tracking report export
*
@ -774,7 +749,7 @@ class Tracking
*
* @return string HTML SQL query form
*/
public function exportAsSqlDump(string $db, string $table, array $entries): string
public function exportAsSqlDump(array $entries): string
{
$html = '';
$new_query = '# '
@ -1082,7 +1057,7 @@ class Tracking
. '\' GROUP BY table_name ORDER BY table_name ASC';
$allTablesResult = $this->dbi->queryAsControlUser($allTablesQuery);
$untrackedTables = $this->getUntrackedTables($db);
$untrackedTables = $this->trackingChecker->getUntrackedTableNames($db);
// If a HEAD version exists
$versions = [];
@ -1107,44 +1082,4 @@ class Tracking
'untracked_tables' => $untrackedTables,
]);
}
/**
* Helper function: Recursive function for getting table names from $table_list
*
* @param array $table_list Table list
* @param string $db Current database
*
* @return array
*/
public function extractTableNames(array $table_list, string $db): array
{
$untracked_tables = [];
$sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
foreach ($table_list as $value) {
if (is_array($value) && array_key_exists('is' . $sep . 'group', $value) && $value['is' . $sep . 'group']) {
// Recursion step
$untracked_tables = array_merge($this->extractTableNames($value, $db), $untracked_tables);
} elseif (is_array($value) && (Tracker::getVersion($db, $value['Name']) == -1)) {
$untracked_tables[] = $value['Name'];
}
}
return $untracked_tables;
}
/**
* Get untracked tables
*
* @param string $db current database
*
* @return array
*/
public function getUntrackedTables(string $db): array
{
$table_list = Util::getTableList($db);
//Use helper function to get table list recursively.
return $this->extractTableNames($table_list, $db);
}
}

View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tracking;
use PhpMyAdmin\Cache;
use PhpMyAdmin\ConfigStorage\Features\TrackingFeature;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Dbal\TableName;
use PhpMyAdmin\Util;
use function array_column;
use function array_diff;
use function array_values;
use function sprintf;
class TrackingChecker
{
private TrackingFeature|null $trackingFeature;
public function __construct(
private DatabaseInterface $dbi,
Relation $relation,
) {
$this->trackingFeature = $relation->getRelationParameters()->trackingFeature;
}
/**
* Get a list of untracked tables.
* Deactivated tracked tables are not included in the list.
*
* @return array<int, string|TableName>
*/
public function getUntrackedTableNames(string $dbName): array
{
$tableList = $this->dbi->getTables($dbName, Connection::TYPE_CONTROL);
if ($this->trackingFeature === null) {
return $tableList;
}
$trackedTables = array_column($this->getTrackedTables($dbName), 'name');
return array_values(array_diff($tableList, $trackedTables));
}
/** @return TrackedTable[] */
public function getTrackedTables(string $dbName): array
{
$trackingEnabled = Cache::get(Tracker::TRACKER_ENABLED_CACHE_KEY, false);
if (! $trackingEnabled) {
return [];
}
if ($this->trackingFeature === null) {
return [];
}
$sqlQuery = sprintf(
"SELECT table_name, tracking_active
FROM (
SELECT table_name, MAX(version) version
FROM %s.%s WHERE db_name = %s AND table_name <> ''
GROUP BY table_name
) filtered_tables
JOIN %s.%s USING(table_name, version)",
Util::backquote($this->trackingFeature->database),
Util::backquote($this->trackingFeature->tracking),
$this->dbi->quoteString($dbName, Connection::TYPE_CONTROL),
Util::backquote($this->trackingFeature->database),
Util::backquote($this->trackingFeature->tracking),
);
$trackedTables = [];
foreach ($this->dbi->queryAsControlUser($sqlQuery) as $row) {
$trackedTable = new TrackedTable(TableName::fromValue($row['table_name']), (bool) $row['tracking_active']);
$trackedTables[$trackedTable->name->getName()] = $trackedTable;
}
return $trackedTables;
}
}

View File

@ -8,7 +8,6 @@ use PhpMyAdmin\Dbal\ResultInterface;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Query\Compatibility;
use PhpMyAdmin\Query\Utilities;
use PhpMyAdmin\SqlParser\Components\Expression;
use PhpMyAdmin\SqlParser\Context;
use PhpMyAdmin\SqlParser\Token;
@ -20,7 +19,6 @@ use function _pgettext;
use function abs;
use function array_key_exists;
use function array_map;
use function array_merge;
use function array_shift;
use function array_unique;
use function bin2hex;
@ -53,7 +51,6 @@ use function mb_detect_encoding;
use function mb_strlen;
use function mb_strpos;
use function mb_strrpos;
use function mb_strstr;
use function mb_strtolower;
use function mb_substr;
use function number_format;
@ -222,121 +219,6 @@ class Util
return self::getMySQLDocuURL('');
}
/**
* Check the correct row count
*
* @param string $db the db name
* @param array $table the table infos
*
* @return int the possibly modified row count
*/
private static function checkRowCount(string $db, array $table): int
{
$rowCount = 0;
if ($table['Rows'] === null) {
// Do not check exact row count here,
// if row count is invalid possibly the table is defect
// and this would break the navigation panel;
// but we can check row count if this is a view or the
// information_schema database
// since Table::countRecords() returns a limited row count
// in this case.
// set this because Table::countRecords() can use it
$tableIsView = $table['TABLE_TYPE'] === 'VIEW';
if ($tableIsView || Utilities::isSystemSchema($db)) {
$rowCount = $GLOBALS['dbi']
->getTable($db, $table['Name'])
->countRecords();
}
}
return $rowCount;
}
/**
* returns array with tables of given db with extended information and grouped
*
* @return array (recursive) grouped table list
*/
public static function getTableList(string $db): array
{
$sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
$tables = $GLOBALS['dbi']->getTablesFull($db);
if ($GLOBALS['cfg']['NaturalOrder']) {
uksort($tables, 'strnatcasecmp');
}
if (count($tables) < 1) {
return $tables;
}
$default = [
'Name' => '',
'Rows' => 0,
'Comment' => '',
'disp_name' => '',
];
$tableGroups = [];
foreach ($tables as $table) {
/** @var string $tableName */
$tableName = $table['TABLE_NAME'];
$table['Rows'] = self::checkRowCount($db, $table);
// in $group we save the reference to the place in $table_groups
// where to store the table info
if ($GLOBALS['cfg']['NavigationTreeEnableGrouping'] && $sep && mb_strstr($tableName, $sep)) {
$parts = explode($sep, $tableName);
$group =& $tableGroups;
$i = 0;
$groupNameFull = '';
$partsCount = count($parts) - 1;
while (($i < $partsCount) && ($i < $GLOBALS['cfg']['NavigationTreeTableLevel'])) {
$groupName = $parts[$i] . $sep;
$groupNameFull .= $groupName;
if (! isset($group[$groupName])) {
$group[$groupName] = [];
$group[$groupName]['is' . $sep . 'group'] = true;
$group[$groupName]['tab' . $sep . 'count'] = 1;
$group[$groupName]['tab' . $sep . 'group'] = $groupNameFull;
} elseif (! isset($group[$groupName]['is' . $sep . 'group'])) {
$table = $group[$groupName];
$group[$groupName] = [];
$group[$groupName][$groupName] = $table;
$group[$groupName]['is' . $sep . 'group'] = true;
$group[$groupName]['tab' . $sep . 'count'] = 1;
$group[$groupName]['tab' . $sep . 'group'] = $groupNameFull;
} else {
$group[$groupName]['tab' . $sep . 'count']++;
}
$group =& $group[$groupName];
$i++;
}
} else {
if (! isset($tableGroups[$tableName])) {
$tableGroups[$tableName] = [];
}
$group =& $tableGroups;
}
$table['disp_name'] = $table['Name'];
$group[$tableName] = array_merge($default, $table);
}
return $tableGroups;
}
/* ----------------------- Set of misc functions ----------------------- */
/**

View File

@ -236,12 +236,20 @@ return [
'arguments' => ['$config' => '@config'],
],
'tracking' => [
'class' => PhpMyAdmin\Tracking::class,
'class' => PhpMyAdmin\Tracking\Tracking::class,
'arguments' => [
'$sqlQueryForm' => '@sql_query_form',
'$template' => '@template',
'$relation' => '@relation',
'$dbi' => '@dbi',
'$trackingChecker' => '@tracking_checker',
],
],
'tracking_checker' => [
'class' => PhpMyAdmin\Tracking\TrackingChecker::class,
'arguments' => [
'$dbi' => '@dbi',
'$relation' => '@relation',
],
],
'transformations' => [

View File

@ -422,6 +422,7 @@ return [
'$relation' => '@relation',
'$replication' => '@replication',
'$dbi' => '@dbi',
'$trackingChecker' => '@tracking_checker',
],
],
Database\TrackingController::class => [
@ -1614,6 +1615,7 @@ return [
'$response' => '@response',
'$template' => '@template',
'$tracking' => '@tracking',
'$trackingChecker' => '@tracking_checker',
],
],
Table\TriggersController::class => [

View File

@ -1591,17 +1591,17 @@ parameters:
path: libraries/classes/Controllers/Database/TrackingController.php
-
message: "#^Parameter \\#2 \\$selected of method PhpMyAdmin\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) expects array, mixed given\\.$#"
message: "#^Parameter \\#2 \\$selected of method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) expects array, mixed given\\.$#"
count: 1
path: libraries/classes/Controllers/Database/TrackingController.php
-
message: "#^Parameter \\#2 \\$tableName of static method PhpMyAdmin\\\\Tracker\\:\\:deleteTracking\\(\\) expects string, mixed given\\.$#"
message: "#^Parameter \\#2 \\$tableName of static method PhpMyAdmin\\\\Tracking\\\\Tracker\\:\\:deleteTracking\\(\\) expects string, mixed given\\.$#"
count: 2
path: libraries/classes/Controllers/Database/TrackingController.php
-
message: "#^Parameter \\#3 \\$version of method PhpMyAdmin\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) expects string, mixed given\\.$#"
message: "#^Parameter \\#3 \\$version of method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) expects string, mixed given\\.$#"
count: 1
path: libraries/classes/Controllers/Database/TrackingController.php
@ -8458,307 +8458,282 @@ parameters:
-
message: "#^Cannot access property \\$dest on PhpMyAdmin\\\\SqlParser\\\\Components\\\\IntoKeyword\\|null\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Cannot access property \\$table on PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression\\|null\\.$#"
count: 4
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Cannot access property \\$table on PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression\\|string\\|null\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Cannot access property \\$tokens on PhpMyAdmin\\\\SqlParser\\\\TokensList\\|null\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Cannot access property \\$value on PhpMyAdmin\\\\SqlParser\\\\Token\\|string\\.$#"
count: 3
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Foreach overwrites \\$logEntry with its value variable\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Method PhpMyAdmin\\\\Tracker\\:\\:changeTrackingData\\(\\) has parameter \\$newData with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracker\\:\\:changeTrackingData\\(\\) has parameter \\$newData with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Method PhpMyAdmin\\\\Tracker\\:\\:parseQuery\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracker\\:\\:parseQuery\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Offset 0 does not exist on array\\<PhpMyAdmin\\\\SqlParser\\\\Components\\\\Expression\\>\\|null\\.$#"
count: 4
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Offset 0 does not exist on array\\<PhpMyAdmin\\\\SqlParser\\\\Components\\\\RenameOperation\\>\\|null\\.$#"
count: 2
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Only numeric types are allowed in \\-, int\\<0, max\\>\\|false given on the left side\\.$#"
count: 2
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Property PhpMyAdmin\\\\Tracker\\:\\:\\$trackingCache type has no value type specified in iterable type array\\.$#"
message: "#^Property PhpMyAdmin\\\\Tracking\\\\Tracker\\:\\:\\$trackingCache type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracker.php
path: libraries/classes/Tracking/Tracker.php
-
message: "#^Cannot access offset 'COLUMNS' on mixed\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Cannot access offset 'INDEXES' on mixed\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) has parameter \\$selected with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:createTrackingForMultipleTables\\(\\) has parameter \\$selected with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:deleteFromTrackingReportLog\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:deleteFromTrackingReportLog\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:deleteTrackingReportRows\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:deleteTrackingReportRows\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:exportAsSqlDump\\(\\) has parameter \\$entries with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:exportAsSqlDump\\(\\) has parameter \\$entries with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:exportAsSqlExecution\\(\\) has parameter \\$entries with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:exportAsSqlExecution\\(\\) has parameter \\$entries with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:extractTableNames\\(\\) has parameter \\$table_list with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:filter\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:extractTableNames\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:filter\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:filter\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:filter\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:filter\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getEntries\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:filter\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getEntries\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getEntries\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getEntries\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getEntries\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForColumns\\(\\) has parameter \\$columns with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getEntries\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForColumns\\(\\) has parameter \\$columns with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataDefinitionStatements\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataManipulationStatements\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$filterUsers with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$filterUsers with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForDbTrackingTables\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDataStatements\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForIndexes\\(\\) has parameter \\$indexes with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForDbTrackingTables\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForMainPage\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForIndexes\\(\\) has parameter \\$indexes with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForSchemaSnapshot\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForMainPage\\(\\) has parameter \\$urlParams with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForSchemaSnapshot\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReport\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$filter_users with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm2\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm1\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForTrackingReportExportForm2\\(\\) has parameter \\$url_params with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
-
message: "#^Method PhpMyAdmin\\\\Tracking\\:\\:getUntrackedTables\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Offset 'statement' does not exist on array\\{date\\: string, username\\: string, statement\\: string\\}\\|string\\.$#"
count: 4
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Offset 0 does not exist on array\\<int, array\\{date\\: string, username\\: string, statement\\: string\\}\\>\\|string\\|null\\.$#"
count: 3
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Offset 1 does not exist on array\\<int, array\\{date\\: string, username\\: string, statement\\: string\\}\\>\\|string\\|null\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Parameter \\#1 \\$columns of method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForColumns\\(\\) expects array, mixed given\\.$#"
message: "#^Parameter \\#1 \\$columns of method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForColumns\\(\\) expects array, mixed given\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Parameter \\#1 \\$data of static method PhpMyAdmin\\\\Core\\:\\:safeUnserialize\\(\\) expects string, array\\<int, array\\<string, string\\>\\>\\|string\\|null given\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Parameter \\#1 \\$dbName of static method PhpMyAdmin\\\\Tracker\\:\\:isTracked\\(\\) expects string, string\\|null given\\.$#"
message: "#^Parameter \\#1 \\$indexes of method PhpMyAdmin\\\\Tracking\\\\Tracking\\:\\:getHtmlForIndexes\\(\\) expects array, mixed given\\.$#"
count: 1
path: libraries/classes/Tracking.php
-
message: "#^Parameter \\#1 \\$indexes of method PhpMyAdmin\\\\Tracking\\:\\:getHtmlForIndexes\\(\\) expects array, mixed given\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:escapeString\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, mixed given\\.$#"
count: 1
path: libraries/classes/Tracking.php
-
message: "#^Parameter \\#2 \\$tableName of static method PhpMyAdmin\\\\Tracker\\:\\:isTracked\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: libraries/classes/Tracking.php
path: libraries/classes/Tracking/Tracking.php
-
message: "#^Foreach overwrites \\$file with its value variable\\.$#"
@ -8870,11 +8845,6 @@ parameters:
count: 1
path: libraries/classes/Util.php
-
message: "#^Method PhpMyAdmin\\\\Util\\:\\:checkRowCount\\(\\) has parameter \\$table with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Util.php
-
message: "#^Method PhpMyAdmin\\\\Util\\:\\:extractColumnSpec\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
@ -8900,11 +8870,6 @@ parameters:
count: 1
path: libraries/classes/Util.php
-
message: "#^Method PhpMyAdmin\\\\Util\\:\\:getTableList\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/Util.php
-
message: "#^Method PhpMyAdmin\\\\Util\\:\\:getTablesWhenOpen\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
@ -10846,29 +10811,29 @@ parameters:
path: test/classes/Theme/ThemeTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TrackerTest\\:\\:getTableNameData\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tests\\\\Tracking\\\\TrackerTest\\:\\:getTableNameData\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: test/classes/TrackerTest.php
path: test/classes/Tracking/TrackerTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TrackerTest\\:\\:getTrackedDataProvider\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tests\\\\Tracking\\\\TrackerTest\\:\\:getTrackedDataProvider\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: test/classes/TrackerTest.php
path: test/classes/Tracking/TrackerTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TrackerTest\\:\\:parseQueryData\\(\\) return type has no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tests\\\\Tracking\\\\TrackerTest\\:\\:parseQueryData\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: test/classes/TrackerTest.php
path: test/classes/Tracking/TrackerTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TrackerTest\\:\\:testGetTrackedData\\(\\) has parameter \\$expectedArray with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tests\\\\Tracking\\\\TrackerTest\\:\\:testGetTrackedData\\(\\) has parameter \\$expectedArray with no value type specified in iterable type array\\.$#"
count: 1
path: test/classes/TrackerTest.php
path: test/classes/Tracking/TrackerTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TrackerTest\\:\\:testGetTrackedData\\(\\) has parameter \\$fetchArrayReturn with no value type specified in iterable type array\\.$#"
message: "#^Method PhpMyAdmin\\\\Tests\\\\Tracking\\\\TrackerTest\\:\\:testGetTrackedData\\(\\) has parameter \\$fetchArrayReturn with no value type specified in iterable type array\\.$#"
count: 1
path: test/classes/TrackerTest.php
path: test/classes/Tracking/TrackerTest.php
-
message: "#^Method PhpMyAdmin\\\\Tests\\\\TransformationsTest\\:\\:fixupData\\(\\) return type has no value type specified in iterable type array\\.$#"

View File

@ -13644,7 +13644,7 @@
<code>return false;</code>
</UnevaluatedCode>
</file>
<file src="libraries/classes/Tracker.php">
<file src="libraries/classes/Tracking/Tracker.php">
<DeprecatedMethod>
<code>escapeString</code>
<code>escapeString</code>
@ -13770,14 +13770,13 @@
<code>getTableName</code>
</PossiblyUnusedMethod>
</file>
<file src="libraries/classes/Tracking.php">
<file src="libraries/classes/Tracking/Tracking.php">
<DeprecatedMethod>
<code>escapeString</code>
<code>escapeString</code>
<code>escapeString</code>
<code>escapeString</code>
<code>escapeString</code>
<code>escapeString</code>
</DeprecatedMethod>
<MixedArgument>
<code>$columns</code>
@ -13797,7 +13796,6 @@
<code>$indexes</code>
<code>$selected_table</code>
<code>$selected_table</code>
<code><![CDATA[$value['Name']]]></code>
</MixedArgument>
<MixedArgumentTypeCoercion>
<code><![CDATA[$urlParams + [
@ -13843,9 +13841,7 @@
<code>$statements[$key]</code>
<code>$temp</code>
<code>$timestamps[$key]</code>
<code>$untracked_tables[]</code>
<code>$usernames[$key]</code>
<code>$value</code>
</MixedAssignment>
<MixedInferredReturnType>
<code>string</code>
@ -13858,18 +13854,8 @@
<MixedReturnStatement>
<code>$html</code>
</MixedReturnStatement>
<PossiblyFalseOperand>
<code>$sep</code>
<code>$sep</code>
</PossiblyFalseOperand>
<PossiblyInvalidOperand>
<code>$sep</code>
<code>$sep</code>
</PossiblyInvalidOperand>
<PossiblyNullArgument>
<code><![CDATA[$data['schema_snapshot']]]></code>
<code><![CDATA[$entry['db_name']]]></code>
<code><![CDATA[$entry['table_name']]]></code>
<code>$tableName</code>
</PossiblyNullArgument>
<PossiblyNullOperand>
@ -13879,14 +13865,15 @@
<code><![CDATA[$data['ddlog']]]></code>
<code><![CDATA[$data['schema_snapshot']]]></code>
</PossiblyUndefinedArrayOffset>
<PossiblyUnusedParam>
<code>$db</code>
<code>$table</code>
</PossiblyUnusedParam>
<RiskyCast>
<code>$delete_id</code>
</RiskyCast>
</file>
<file src="libraries/classes/Tracking/TrackingChecker.php">
<MixedAssignment>
<code>$trackingEnabled</code>
</MixedAssignment>
</file>
<file src="libraries/classes/Transformations.php">
<DeprecatedMethod>
<code>escapeString</code>
@ -14033,27 +14020,18 @@
<code>$byteUnits[$d]</code>
<code>$units[$d]</code>
</InvalidArrayOffset>
<InvalidReturnStatement>
<code>$tableGroups</code>
</InvalidReturnStatement>
<MixedArgument>
<code>$maxSize</code>
<code>$maxUnit</code>
<code>$row[$i] ?? null</code>
<code>$table</code>
<code>$table</code>
<code><![CDATA[$table['Name']]]></code>
</MixedArgument>
<MixedArgumentTypeCoercion>
<code>$columnNames</code>
<code><![CDATA[uksort($tables, 'strnatcasecmp')]]></code>
<code><![CDATA[uksort($tables, 'strnatcasecmp')]]></code>
</MixedArgumentTypeCoercion>
<MixedArrayAccess>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset']]]></code>
<code>$array[$p]</code>
<code>$group[$groupName]</code>
<code><![CDATA[$group[$groupName]['tab' . $sep . 'count']]]></code>
<code><![CDATA[$row['Cardinality']]]></code>
<code><![CDATA[$row['Column_name']]]></code>
<code><![CDATA[$row['Column_name']]]></code>
@ -14073,27 +14051,11 @@
<code><![CDATA[$row['Seq_in_index']]]></code>
<code><![CDATA[$row['Seq_in_index']]]></code>
<code><![CDATA[$row['Sub_part']]]></code>
<code><![CDATA[$table['Name']]]></code>
<code><![CDATA[$table['TABLE_NAME']]]></code>
</MixedArrayAccess>
<MixedArrayAssignment>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset']]]></code>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset']]]></code>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset_db']]]></code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code><![CDATA[$group[$groupName]['tab' . $sep . 'count']]]></code>
<code>$group[$tableName]</code>
<code>$tableGroups[$tableName]</code>
<code><![CDATA[$table['disp_name']]]></code>
</MixedArrayAssignment>
<MixedArrayOffset>
<code>$array[$p]</code>
@ -14112,8 +14074,6 @@
<code>$array</code>
<code>$columnNames[]</code>
<code>$columnNames[]</code>
<code>$group[$groupName][$groupName]</code>
<code><![CDATA[$group[$groupName]['tab' . $sep . 'count']]]></code>
<code><![CDATA[$indexesData[$row['Key_name']][$row['Seq_in_index']]['Column_name']]]></code>
<code><![CDATA[$indexesData[$row['Key_name']][$row['Seq_in_index']]['Sub_part']]]></code>
<code><![CDATA[$indexesInfo[$row['Key_name']]['Cardinality']]]></code>
@ -14124,18 +14084,13 @@
<code>$p</code>
<code>$p</code>
<code>$row</code>
<code>$table</code>
<code>$table</code>
<code><![CDATA[$table['disp_name']]]></code>
<code>$unit</code>
<code>$value</code>
</MixedAssignment>
<MixedInferredReturnType>
<code>array</code>
<code>int</code>
</MixedInferredReturnType>
<MixedOperand>
<code><![CDATA[$group[$groupName]['tab' . $sep . 'count']]]></code>
<code><![CDATA[$row['Column_name']]]></code>
<code>$unit</code>
<code>$unit</code>
@ -14143,7 +14098,6 @@
<MixedReturnStatement>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset']]]></code>
<code><![CDATA[$_SESSION['tmpval']['table_limit_offset']]]></code>
<code>$tableGroups</code>
</MixedReturnStatement>
<PossiblyFalseOperand>
<code><![CDATA[$GLOBALS['cfg']['NavigationTreeTableSeparator']]]></code>
@ -14151,34 +14105,9 @@
<code><![CDATA[mb_strpos($value, '.')]]></code>
<code><![CDATA[mb_strrpos($columnSpecification, ')')]]></code>
</PossiblyFalseOperand>
<PossiblyInvalidArgument>
<code>$sep</code>
<code>$sep</code>
</PossiblyInvalidArgument>
<PossiblyInvalidArrayOffset>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$groupName]</code>
<code>$group[$tableName]</code>
<code>$tableGroups[$tableName]</code>
</PossiblyInvalidArrayOffset>
<PossiblyInvalidCast>
<code>$sep</code>
<code>$sep</code>
</PossiblyInvalidCast>
<PossiblyInvalidOperand>
<code><![CDATA[$GLOBALS['cfg']['NavigationTreeTableSeparator']]]></code>
<code><![CDATA[$GLOBALS['cfg']['NavigationTreeTableSeparator']]]></code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
<code>$sep</code>
</PossiblyInvalidOperand>
<PossiblyNullArgument>
<code>$maxSize</code>
@ -15849,7 +15778,7 @@
<code>array</code>
</MixedInferredReturnType>
</file>
<file src="test/classes/TrackerTest.php">
<file src="test/classes/Tracking/TrackerTest.php">
<MixedInferredReturnType>
<code>array</code>
<code>array</code>
@ -15860,7 +15789,7 @@
<code>$fetchArrayReturn[0]</code>
</PossiblyUndefinedArrayOffset>
</file>
<file src="test/classes/TrackingTest.php">
<file src="test/classes/Tracking/TrackingTest.php">
<MixedArgument>
<code>$html</code>
</MixedArgument>

View File

@ -1,12 +1,12 @@
{% if selectable_tables_num_rows > 0 %}
{% if selectable_tables_entries|length > 0 %}
<form method="post" action="{{ url('/table/tracking', url_params) }}">
{{ get_hidden_inputs(db, table) }}
<select name="table" class="autosubmit">
{% for entry in selectable_tables_entries %}
<option value="{{ entry.table_name }}"
{{- entry.table_name == selected_table ? ' selected' }}>
{{ entry.db_name }}.{{ entry.table_name }}
{% if entry.is_tracked %}
<option value="{{ entry.name }}"
{{- entry.name == selected_table ? ' selected' }}>
{{ db }}.{{ entry.name }}
{% if entry.active %}
({% trans 'active' %})
{% else %}
({% trans 'not active' %})

View File

@ -13,6 +13,7 @@ use PhpMyAdmin\Table;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tests\Stubs\ResponseRenderer as ResponseStub;
use PhpMyAdmin\Tracking\TrackingChecker;
use ReflectionClass;
use ReflectionException;
@ -78,6 +79,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
// Showing statistics
$property = $class->getProperty('isShowStats');
@ -121,6 +123,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
$currentTable['ENGINE'] = 'InnoDB';
@ -148,6 +151,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
// Showing statistics
$property = $class->getProperty('isShowStats');
@ -198,6 +202,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
[$currentTable, , , , , , $sumSize] = $method->invokeArgs(
$controller,
@ -219,6 +224,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
[$currentTable] = $method->invokeArgs(
$controller,
@ -249,6 +255,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
// When parameter $db is empty
@ -283,6 +290,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
$_SESSION['tmpval']['favoriteTables'][$GLOBALS['server']] = [
@ -313,6 +321,7 @@ class StructureControllerTest extends AbstractTestCase
$this->relation,
$this->replication,
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
// Showing statistics
$class = new ReflectionClass(StructureController::class);

View File

@ -13,7 +13,8 @@ use PhpMyAdmin\Template;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tests\Stubs\DbiDummy;
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Tracking\Tracking;
use PhpMyAdmin\Tracking\TrackingChecker;
/** @covers \PhpMyAdmin\Controllers\Table\TrackingController */
class TrackingControllerTest extends AbstractTestCase
@ -44,10 +45,18 @@ class TrackingControllerTest extends AbstractTestCase
$response = new ResponseRenderer();
$template = new Template();
$trackingChecker = $this->createStub(TrackingChecker::class);
(new TrackingController(
$response,
$template,
new Tracking(new SqlQueryForm($template, $this->dbi), $template, new Relation($this->dbi), $this->dbi),
new Tracking(
new SqlQueryForm($template, $this->dbi),
$template,
new Relation($this->dbi),
$this->dbi,
$trackingChecker,
),
$trackingChecker,
))($this->createStub(ServerRequest::class));
$main = $template->render('table/tracking/main', [
@ -59,7 +68,6 @@ class TrackingControllerTest extends AbstractTestCase
],
'db' => $GLOBALS['db'],
'table' => $GLOBALS['table'],
'selectable_tables_num_rows' => 0,
'selectable_tables_entries' => [],
'selected_table' => null,
'last_version' => 0,

View File

@ -2339,12 +2339,6 @@ class DbiDummy implements DbiExtension
'columns' => ['version'],
'result' => [['10']],
],
[
'query' => 'SELECT DISTINCT db_name, table_name FROM `pmadb`.`tracking`'
. ' WHERE db_name = \'PMA_db\' ORDER BY db_name, table_name',
'columns' => ['db_name', 'table_name', 'version'],
'result' => [['PMA_db', 'PMA_table', '10']],
],
[
'query' => 'SELECT * FROM `pmadb`.`tracking` WHERE db_name = \'PMA_db\''
. ' AND table_name = \'PMA_table\' ORDER BY version DESC',
@ -2360,6 +2354,22 @@ class DbiDummy implements DbiExtension
'columns' => ['tracking_active'],
'result' => [['1']],
],
[
'query' => 'SELECT table_name, tracking_active '
. 'FROM ( '
. 'SELECT table_name, MAX(version) version '
. "FROM `pmadb`.`tracking` WHERE db_name = 'dummyDb' AND table_name <> '' "
. 'GROUP BY table_name '
. ') filtered_tables '
. 'JOIN `pmadb`.`tracking` USING(table_name, version)',
'columns' => ['table_name', 'tracking_active'],
'result' => [['0', '1'],['actor', '0']],
],
[
'query' => 'SHOW TABLES FROM `dummyDb`;',
'columns' => ['Tables_in_dummyDb'],
'result' => [['0'], ['actor'], ['untrackedTable']],
],
[
'query' => 'SHOW TABLE STATUS FROM `PMA_db` WHERE `Name` LIKE \'PMA\\\\_table%\'',
'columns' => ['Name', 'Engine'],

View File

@ -2,18 +2,19 @@
declare(strict_types=1);
namespace PhpMyAdmin\Tests;
namespace PhpMyAdmin\Tests\Tracking;
use PhpMyAdmin\Cache;
use PhpMyAdmin\ConfigStorage\RelationParameters;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tests\Stubs\DummyResult;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Util;
use ReflectionMethod;
/** @covers \PhpMyAdmin\Tracker */
/** @covers \PhpMyAdmin\Tracking\Tracker */
class TrackerTest extends AbstractTestCase
{
/**

View File

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tests\Tracking;
use PhpMyAdmin\Cache;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\ConfigStorage\RelationParameters;
use PhpMyAdmin\Dbal\TableName;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tracking\TrackedTable;
use PhpMyAdmin\Tracking\Tracker;
use PhpMyAdmin\Tracking\TrackingChecker;
/** @covers \PhpMyAdmin\Tracking\TrackingChecker */
class TrackingCheckerTest extends AbstractTestCase
{
private TrackingChecker $trackingChecker;
/**
* Setup function for test cases
*/
protected function setUp(): void
{
parent::setUp();
$GLOBALS['dbi'] = $this->createDatabaseInterface();
$_SESSION['relation'] = [];
$_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([
'db' => 'pmadb',
'tracking' => 'tracking',
'trackingwork' => true,
])->toArray();
$this->trackingChecker = new TrackingChecker(
$GLOBALS['dbi'],
new Relation($GLOBALS['dbi']),
);
}
public function testGetTrackedTables(): void
{
$this->assertFalse(
Cache::has(Tracker::TRACKER_ENABLED_CACHE_KEY),
);
$actual = $this->trackingChecker->getTrackedTables('dummyDb');
$this->assertEquals([], $actual);
Tracker::enable();
$expectation = [
0 => new TrackedTable(TableName::fromValue('0'), true),
'actor' => new TrackedTable(TableName::fromValue('actor'), false),
];
$actual = $this->trackingChecker->getTrackedTables('dummyDb');
$this->assertEquals($expectation, $actual);
}
public function testGetUntrackedTableNames(): void
{
$this->assertFalse(
Cache::has(Tracker::TRACKER_ENABLED_CACHE_KEY),
);
$expectation = ['0', 'actor', 'untrackedTable'];
$actual = $this->trackingChecker->getUntrackedTableNames('dummyDb');
$this->assertEquals($expectation, $actual);
Tracker::enable();
$expectation = ['untrackedTable'];
$actual = $this->trackingChecker->getUntrackedTableNames('dummyDb');
$this->assertEquals($expectation, $actual);
}
}

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace PhpMyAdmin\Tests;
namespace PhpMyAdmin\Tests\Tracking;
use DateTimeImmutable;
use PhpMyAdmin\ConfigStorage\Relation;
@ -10,7 +10,9 @@ use PhpMyAdmin\ConfigStorage\RelationParameters;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\SqlQueryForm;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tracking\Tracking;
use PhpMyAdmin\Tracking\TrackingChecker;
use PhpMyAdmin\Url;
use function __;
@ -22,7 +24,7 @@ use function ini_restore;
use function ini_set;
use function sprintf;
/** @covers \PhpMyAdmin\Tracking */
/** @covers \PhpMyAdmin\Tracking\Tracking */
class TrackingTest extends AbstractTestCase
{
private Tracking $tracking;
@ -59,6 +61,7 @@ class TrackingTest extends AbstractTestCase
$template,
new Relation($GLOBALS['dbi']),
$GLOBALS['dbi'],
$this->createStub(TrackingChecker::class),
);
}
@ -92,30 +95,6 @@ class TrackingTest extends AbstractTestCase
$this->assertEquals('statement1', $ret[0]['statement']);
}
/**
* Tests for extractTableNames() method from nested table_list.
*/
public function testExtractTableNames(): void
{
$GLOBALS['cfg']['NavigationTreeTableSeparator'] = '_';
$table_list = [
'hello_' => [
'is_group' => 1,
'lovely_' => [
'is_group' => 1,
'hello_lovely_world' => ['Name' => 'hello_lovely_world'],
'hello_lovely_world2' => ['Name' => 'hello_lovely_world2'],
],
'hello_world' => ['Name' => 'hello_world'],
],
];
$untracked_tables = $this->tracking->extractTableNames($table_list, 'db');
$this->assertContains('hello_world', $untracked_tables);
$this->assertContains('hello_lovely_world', $untracked_tables);
$this->assertNotContains('hello_lovely_world2', $untracked_tables);
}
public function testGetHtmlForMain(): void
{
$html = $this->tracking->getHtmlForMainPage('PMA_db', 'PMA_table', [], 'ltr');
@ -150,21 +129,11 @@ class TrackingTest extends AbstractTestCase
*/
public function testGetTableLastVersionNumber(): void
{
$sql_result = $this->tracking->getSqlResultForSelectableTables('PMA_db');
$sql_result = $this->tracking->getListOfVersionsOfTable('PMA_db', 'PMA_table');
$this->assertNotFalse($sql_result);
$last_version = $this->tracking->getTableLastVersionNumber($sql_result);
$this->assertSame(10, $last_version);
}
/**
* Tests for getSqlResultForSelectableTables() method.
*/
public function testGetSQLResultForSelectableTables(): void
{
$ret = $this->tracking->getSqlResultForSelectableTables('PMA_db');
$this->assertNotFalse($ret);
$this->assertSame(1, $last_version);
}
/**
@ -595,6 +564,7 @@ class TrackingTest extends AbstractTestCase
$this->createStub(Template::class),
$this->createStub(Relation::class),
$this->createStub(DatabaseInterface::class),
$this->createStub(TrackingChecker::class),
);
ini_set('url_rewriter.tags', 'a=href,area=href,frame=src,form=,fieldset=');
$entries = [['statement' => 'first statement'], ['statement' => 'second statement']];