Merge PR #16500 Add paging to Routines page
Closes #16500 Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
commit
32db9bf052
@ -1664,6 +1664,14 @@ Generic settings
|
||||
The maximum number of table names to be displayed in the main panel's
|
||||
list (except on the Export page).
|
||||
|
||||
.. config:option:: $cfg['MaxRoutineList']
|
||||
|
||||
:type: integer
|
||||
:default: 250
|
||||
|
||||
The maximum number of routine names to be displayed in the main panel's
|
||||
routine list.
|
||||
|
||||
.. config:option:: $cfg['ShowHint']
|
||||
|
||||
:type: boolean
|
||||
|
||||
@ -1122,7 +1122,7 @@ parameters:
|
||||
-
|
||||
message: '#^Cannot cast mixed to int\.$#'
|
||||
identifier: cast.int
|
||||
count: 35
|
||||
count: 36
|
||||
path: src/Config/Settings.php
|
||||
|
||||
-
|
||||
@ -2028,6 +2028,12 @@ parameters:
|
||||
count: 4
|
||||
path: src/Controllers/Database/RoutinesController.php
|
||||
|
||||
-
|
||||
message: '#^Cannot cast mixed to int\.$#'
|
||||
identifier: cast.int
|
||||
count: 1
|
||||
path: src/Controllers/Database/RoutinesController.php
|
||||
|
||||
-
|
||||
message: '#^Cannot use \+\+ on mixed\.$#'
|
||||
identifier: postInc.type
|
||||
|
||||
@ -38,6 +38,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%- if has_any_routines -%}
|
||||
{{ list_navigator_html|raw }}
|
||||
{%- endif -%}
|
||||
|
||||
<form id="rteListForm" class="ajax" action="{{ url('/database/routines') }}">
|
||||
{{ get_hidden_inputs(db, table) }}
|
||||
|
||||
@ -63,6 +67,10 @@
|
||||
</table>
|
||||
</form>
|
||||
|
||||
{%- if has_any_routines -%}
|
||||
{{ list_navigator_html|raw }}
|
||||
{%- endif -%}
|
||||
|
||||
<div class="modal fade" id="routinesEditorModal" tabindex="-1" aria-labelledby="routinesEditorModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
|
||||
@ -785,6 +785,7 @@ class ConfigFile
|
||||
'MaxSizeForInputField' => 'validatePositiveNumber',
|
||||
'MinSizeForInputField' => 'validateNonNegativeNumber',
|
||||
'MaxTableList' => 'validatePositiveNumber',
|
||||
'MaxRoutineList' => 'validatePositiveNumber',
|
||||
'MemoryLimit' => [['validateByRegex', '/^(-1|(\d+(?:[kmg])?))$/i']],
|
||||
'NavigationTreeDisplayItemFilterMinimum' => 'validatePositiveNumber',
|
||||
'NavigationTreeTableLevel' => 'validatePositiveNumber',
|
||||
@ -806,6 +807,7 @@ class ConfigFile
|
||||
'_userValidators' => [
|
||||
'MaxDbList' => [['validateUpperBound', 'value:MaxDbList']],
|
||||
'MaxTableList' => [['validateUpperBound', 'value:MaxTableList']],
|
||||
'MaxRoutineList' => [['validateUpperBound', 'value:MaxRoutineList']],
|
||||
'QueryHistoryMax' => [['validateUpperBound', 'value:QueryHistoryMax']],
|
||||
],
|
||||
];
|
||||
|
||||
@ -59,6 +59,7 @@ use const VERSION_CHECK_DEFAULT;
|
||||
* ProxyPass: string,
|
||||
* MaxDbList: int<1, max>,
|
||||
* MaxTableList: int<1, max>,
|
||||
* MaxRoutineList: int<1, max>,
|
||||
* ShowHint: bool,
|
||||
* MaxCharactersInDisplayedSQL: int<1, max>,
|
||||
* PersistentConnections: bool,
|
||||
@ -479,6 +480,19 @@ final class Settings
|
||||
*/
|
||||
public int $MaxTableList;
|
||||
|
||||
/**
|
||||
* maximum number of routines displayed in routine list
|
||||
*
|
||||
* ```php
|
||||
* $cfg['MaxRoutineList'] = 250;
|
||||
* ```
|
||||
*
|
||||
* @link https://docs.phpmyadmin.net/en/latest/config.html#cfg_MaxRoutineList
|
||||
*
|
||||
* @psalm-var positive-int
|
||||
*/
|
||||
public int $MaxRoutineList;
|
||||
|
||||
/**
|
||||
* whether to show hint or not
|
||||
*
|
||||
@ -2630,6 +2644,7 @@ final class Settings
|
||||
$this->ProxyPass = $this->setProxyPass($settings);
|
||||
$this->MaxDbList = $this->setMaxDbList($settings);
|
||||
$this->MaxTableList = $this->setMaxTableList($settings);
|
||||
$this->MaxRoutineList = $this->setMaxRoutineList($settings);
|
||||
$this->ShowHint = $this->setShowHint($settings);
|
||||
$this->MaxCharactersInDisplayedSQL = $this->setMaxCharactersInDisplayedSQL($settings);
|
||||
$this->PersistentConnections = $this->setPersistentConnections($settings);
|
||||
@ -2827,6 +2842,7 @@ final class Settings
|
||||
'ProxyPass' => $this->ProxyPass,
|
||||
'MaxDbList' => $this->MaxDbList,
|
||||
'MaxTableList' => $this->MaxTableList,
|
||||
'MaxRoutineList' => $this->MaxRoutineList,
|
||||
'ShowHint' => $this->ShowHint,
|
||||
'MaxCharactersInDisplayedSQL' => $this->MaxCharactersInDisplayedSQL,
|
||||
'PersistentConnections' => $this->PersistentConnections,
|
||||
@ -3250,6 +3266,22 @@ final class Settings
|
||||
return $maxTableList >= 1 ? $maxTableList : 250;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int|string, mixed> $settings
|
||||
*
|
||||
* @psalm-return positive-int
|
||||
*/
|
||||
private function setMaxRoutineList(array $settings): int
|
||||
{
|
||||
if (! isset($settings['MaxRoutineList'])) {
|
||||
return 250;
|
||||
}
|
||||
|
||||
$maxRoutineList = (int) $settings['MaxRoutineList'];
|
||||
|
||||
return $maxRoutineList >= 1 ? $maxRoutineList : 250;
|
||||
}
|
||||
|
||||
/** @param array<int|string, mixed> $settings */
|
||||
private function setShowHint(array $settings): bool
|
||||
{
|
||||
|
||||
@ -11,6 +11,7 @@ use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\Database\Routines;
|
||||
use PhpMyAdmin\Dbal\DatabaseInterface;
|
||||
use PhpMyAdmin\DbTableExists;
|
||||
use PhpMyAdmin\Html\Generator;
|
||||
use PhpMyAdmin\Http\Response;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Identifiers\DatabaseName;
|
||||
@ -18,14 +19,18 @@ use PhpMyAdmin\Identifiers\TableName;
|
||||
use PhpMyAdmin\Message;
|
||||
use PhpMyAdmin\ResponseRenderer;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Url;
|
||||
use PhpMyAdmin\UrlParams;
|
||||
use PhpMyAdmin\UserPrivilegesFactory;
|
||||
use PhpMyAdmin\Util;
|
||||
|
||||
use function __;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function htmlentities;
|
||||
use function htmlspecialchars;
|
||||
use function in_array;
|
||||
use function max;
|
||||
use function mb_strtoupper;
|
||||
use function sprintf;
|
||||
use function trim;
|
||||
@ -453,6 +458,31 @@ final class RoutinesController implements InvocableController
|
||||
}
|
||||
|
||||
$items = Routines::getDetails($this->dbi, Current::$database, $type);
|
||||
$totalNumRoutines = count($items);
|
||||
$pageSize = $config->settings['MaxRoutineList'];
|
||||
$pos = (int) $request->getParam('pos');
|
||||
|
||||
// Checks if there are any routines to be shown on current page.
|
||||
// If there are no routines, the user is redirected to the last page
|
||||
// having any.
|
||||
if ($totalNumRoutines > 0 && $pos >= $totalNumRoutines) {
|
||||
$redirParams = [
|
||||
'db' => Current::$database,
|
||||
'pos' => max(0, $totalNumRoutines - $pageSize),
|
||||
'reload' => 1,
|
||||
];
|
||||
if ($this->response->isAjax()) {
|
||||
$redirParams['ajax_request'] = 'true';
|
||||
$redirParams['ajax_page_request'] = 'true';
|
||||
}
|
||||
|
||||
$this->response->redirectToRoute('/database/routines', $redirParams);
|
||||
|
||||
return $this->response->response();
|
||||
}
|
||||
|
||||
$items = array_slice($items, $pos, $pageSize);
|
||||
|
||||
$isAjax = $request->isAjax() && empty($_REQUEST['ajax_page_request']);
|
||||
|
||||
$rows = '';
|
||||
@ -463,12 +493,24 @@ final class RoutinesController implements InvocableController
|
||||
);
|
||||
}
|
||||
|
||||
$urlParams = ['pos' => $pos, 'db' => Current::$database];
|
||||
|
||||
$listNavigator = Generator::getListNavigator(
|
||||
$totalNumRoutines,
|
||||
$pos,
|
||||
$urlParams,
|
||||
Url::getFromRoute('/database/routines'),
|
||||
'frame_content',
|
||||
$pageSize,
|
||||
);
|
||||
|
||||
$this->response->render('database/routines/index', [
|
||||
'db' => Current::$database,
|
||||
'table' => Current::$table,
|
||||
'has_any_routines' => $items !== [],
|
||||
'rows' => $rows,
|
||||
'has_privilege' => Util::currentUserHasPrivilege('CREATE ROUTINE', Current::$database, Current::$table),
|
||||
'list_navigator_html' => $listNavigator,
|
||||
]);
|
||||
|
||||
return $this->response->response();
|
||||
|
||||
@ -149,9 +149,7 @@ final class RoutinesControllerTest extends AbstractTestCase
|
||||
<span class="text-nowrap"><img src="themes/dot.gif" title="Create new routine" alt="Create new routine" class="icon ic_b_routine_add"> Create new routine</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="rteListForm" class="ajax" action="index.php?route=/database/routines&server=2&lang=en">
|
||||
</div><form id="rteListForm" class="ajax" action="index.php?route=/database/routines&server=2&lang=en">
|
||||
<input type="hidden" name="db" value="test_db"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token">
|
||||
|
||||
<div id="nothing2display" class="hide">
|
||||
@ -233,9 +231,7 @@ final class RoutinesControllerTest extends AbstractTestCase
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<div class="modal fade" id="routinesEditorModal" tabindex="-1" aria-labelledby="routinesEditorModalLabel" aria-hidden="true">
|
||||
</form><div class="modal fade" id="routinesEditorModal" tabindex="-1" aria-labelledby="routinesEditorModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -354,9 +350,7 @@ HTML;
|
||||
<span class="text-nowrap"><img src="themes/dot.gif" title="Create new routine" alt="Create new routine" class="icon ic_b_routine_add"> Create new routine</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="rteListForm" class="ajax" action="index.php?route=/database/routines&server=2&lang=en">
|
||||
</div><form id="rteListForm" class="ajax" action="index.php?route=/database/routines&server=2&lang=en">
|
||||
<input type="hidden" name="db" value="test_db"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token">
|
||||
|
||||
<div id="nothing2display">
|
||||
@ -380,9 +374,7 @@ HTML;
|
||||
<tr class="hide"><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<div class="modal fade" id="routinesEditorModal" tabindex="-1" aria-labelledby="routinesEditorModalLabel" aria-hidden="true">
|
||||
</form><div class="modal fade" id="routinesEditorModal" tabindex="-1" aria-labelledby="routinesEditorModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user