Remove RteList class

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
Maurício Meneghini Fauth 2020-04-10 20:19:28 -03:00
parent 39e567f59f
commit aa00a60f62
4 changed files with 150 additions and 214 deletions

View File

@ -1,7 +1,5 @@
<?php
/**
* Functions for event management.
*/
declare(strict_types=1);
namespace PhpMyAdmin\Rte;
@ -25,7 +23,7 @@ use function sprintf;
use const ENT_QUOTES;
/**
* PhpMyAdmin\Rte\Events class
* Functions for event management.
*/
class Events
{
@ -35,9 +33,6 @@ class Events
/** @var General */
private $general;
/** @var RteList */
private $rteList;
/** @var Words */
private $words;
@ -55,7 +50,6 @@ class Events
$this->dbi = $dbi;
$this->export = new Export($this->dbi);
$this->general = new General($this->dbi);
$this->rteList = new RteList($this->dbi);
$this->words = new Words();
$this->template = new Template();
}
@ -122,14 +116,23 @@ class Events
$items = $this->dbi->getEvents($db);
$response = Response::getInstance();
$hasPrivilege = Util::currentUserHasPrivilege('EVENT', $db);
$isAjax = $response->isAjax() && empty($_REQUEST['ajax_page_request']);
$rows = '';
foreach ($items as $item) {
$rows .= $this->rteList->getEventRow(
$item,
$isAjax ? 'ajaxInsert hide' : ''
$sqlDrop = sprintf(
'DROP EVENT IF EXISTS %s',
Util::backquote($item['name'])
);
$rows .= $this->template->render('rte/events/row', [
'db' => $db,
'table' => $table,
'event' => $item,
'has_privilege' => $hasPrivilege,
'sql_drop' => $sqlDrop,
'row_class' => $isAjax ? 'ajaxInsert hide' : '',
]);
}
echo $this->template->render('rte/events/list', [
@ -155,7 +158,7 @@ class Events
*/
public function handleEditor()
{
global $db, $errors, $message;
global $db, $table, $errors, $message;
if (! empty($_POST['editor_process_add'])
|| ! empty($_POST['editor_process_edit'])
@ -264,7 +267,21 @@ class Events
)
);
if (! empty($event)) {
$response->addJSON('new_row', $this->rteList->getEventRow($event));
$sqlDrop = sprintf(
'DROP EVENT IF EXISTS %s',
Util::backquote($event['name'])
);
$response->addJSON(
'new_row',
$this->template->render('rte/events/row', [
'db' => $db,
'table' => $table,
'event' => $event,
'has_privilege' => Util::currentUserHasPrivilege('EVENT', $db),
'sql_drop' => $sqlDrop,
'row_class' => '',
])
);
}
$response->addJSON('insert', ! empty($event));
$response->addJSON('message', $output);

View File

@ -1,7 +1,5 @@
<?php
/**
* Functions for routine management.
*/
declare(strict_types=1);
namespace PhpMyAdmin\Rte;
@ -42,7 +40,7 @@ use const E_USER_WARNING;
use const ENT_QUOTES;
/**
* PhpMyAdmin\Rte\Routines class
* Functions for routine management.
*/
class Routines
{
@ -52,9 +50,6 @@ class Routines
/** @var General */
private $general;
/** @var RteList */
private $rteList;
/** @var Words */
private $words;
@ -72,7 +67,6 @@ class Routines
$this->dbi = $dbi;
$this->export = new Export($this->dbi);
$this->general = new General($this->dbi);
$this->rteList = new RteList($this->dbi);
$this->words = new Words();
$this->template = new Template();
}
@ -137,7 +131,7 @@ class Routines
$rows = '';
foreach ($items as $item) {
$rows .= $this->rteList->getRoutineRow(
$rows .= $this->getRow(
$item,
$isAjax ? 'ajaxInsert hide' : ''
);
@ -399,7 +393,7 @@ class Routines
mb_strtoupper($_POST['item_name'])
)
);
$response->addJSON('new_row', $this->rteList->getRoutineRow($routine));
$response->addJSON('new_row', $this->getRow($routine));
$response->addJSON('insert', ! empty($routine));
$response->addJSON('message', $output);
exit;
@ -1763,4 +1757,97 @@ class Routines
return $retval;
}
/**
* Creates the contents for a row in the list of routines
*
* @param array $routine An array of routine data
* @param string $rowClass Additional class
*
* @return string HTML code of a row for the list of routines
*/
private function getRow(array $routine, $rowClass = '')
{
global $db, $table;
$sqlDrop = sprintf(
'DROP %s IF EXISTS %s',
$routine['type'],
Util::backquote($routine['name'])
);
// this is for our purpose to decide whether to
// show the edit link or not, so we need the DEFINER for the routine
$where = 'ROUTINE_SCHEMA ' . Util::getCollateForIS() . '='
. "'" . $this->dbi->escapeString($db) . "' "
. "AND SPECIFIC_NAME='" . $this->dbi->escapeString($routine['name']) . "'"
. "AND ROUTINE_TYPE='" . $this->dbi->escapeString($routine['type']) . "'";
$query = 'SELECT `DEFINER` FROM INFORMATION_SCHEMA.ROUTINES WHERE ' . $where . ';';
$routineDefiner = $this->dbi->fetchValue($query);
$currentUser = $this->dbi->getCurrentUser();
// Since editing a procedure involved dropping and recreating, check also for
// CREATE ROUTINE privilege to avoid lost procedures.
$hasEditPrivilege = (Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $currentUser == $routineDefiner) || $this->dbi->isSuperuser();
// There is a problem with Util::currentUserHasPrivilege():
// it does not detect all kinds of privileges, for example
// a direct privilege on a specific routine. So, at this point,
// we show the Execute link, hoping that the user has the correct rights.
// Also, information_schema might be hiding the ROUTINE_DEFINITION
// but a routine with no input parameters can be nonetheless executed.
// Check if the routine has any input parameters. If it does,
// we will show a dialog to get values for these parameters,
// otherwise we can execute it directly.
$definition = $this->dbi->getDefinition(
$db,
$routine['type'],
$routine['name']
);
$hasExecutePrivilege = Util::currentUserHasPrivilege('EXECUTE', $db);
$executeAction = '';
if ($definition !== null) {
$parser = new Parser($definition);
/**
* @var CreateStatement $stmt
*/
$stmt = $parser->statements[0];
$params = Routine::getParameters($stmt);
if ($hasExecutePrivilege) {
$executeAction = 'execute_routine';
for ($i = 0; $i < $params['num']; $i++) {
if ($routine['type'] == 'PROCEDURE'
&& $params['dir'][$i] == 'OUT'
) {
continue;
}
$executeAction = 'execute_dialog';
break;
}
}
}
$hasExportPrivilege = (Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $currentUser == $routineDefiner) || $this->dbi->isSuperuser();
return $this->template->render('rte/routines/row', [
'db' => $db,
'table' => $table,
'sql_drop' => $sqlDrop,
'routine' => $routine,
'row_class' => $rowClass,
'has_edit_privilege' => $hasEditPrivilege,
'has_export_privilege' => $hasExportPrivilege,
'has_execute_privilege' => $hasExecutePrivilege,
'execute_action' => $executeAction,
]);
}
}

View File

@ -1,178 +0,0 @@
<?php
/**
* Common functions for generating lists of Routines, Triggers and Events.
*/
declare(strict_types=1);
namespace PhpMyAdmin\Rte;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\CreateStatement;
use PhpMyAdmin\SqlParser\Utils\Routine;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
use function sprintf;
/**
* PhpMyAdmin\Rte\RteList class
*/
class RteList
{
/** @var Template */
public $template;
/** @var DatabaseInterface */
private $dbi;
/**
* @param DatabaseInterface $dbi DatabaseInterface object
*/
public function __construct(DatabaseInterface $dbi)
{
$this->dbi = $dbi;
$this->template = new Template();
}
/**
* Creates the contents for a row in the list of routines
*
* @param array $routine An array of routine data
* @param string $rowClass Additional class
*
* @return string HTML code of a row for the list of routines
*/
public function getRoutineRow(array $routine, $rowClass = '')
{
global $db, $table;
$sqlDrop = sprintf(
'DROP %s IF EXISTS %s',
$routine['type'],
Util::backquote($routine['name'])
);
// this is for our purpose to decide whether to
// show the edit link or not, so we need the DEFINER for the routine
$where = 'ROUTINE_SCHEMA ' . Util::getCollateForIS() . '='
. "'" . $this->dbi->escapeString($db) . "' "
. "AND SPECIFIC_NAME='" . $this->dbi->escapeString($routine['name']) . "'"
. "AND ROUTINE_TYPE='" . $this->dbi->escapeString($routine['type']) . "'";
$query = 'SELECT `DEFINER` FROM INFORMATION_SCHEMA.ROUTINES WHERE ' . $where . ';';
$routineDefiner = $this->dbi->fetchValue($query);
$currentUser = $this->dbi->getCurrentUser();
// Since editing a procedure involved dropping and recreating, check also for
// CREATE ROUTINE privilege to avoid lost procedures.
$hasEditPrivilege = (Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $currentUser == $routineDefiner) || $this->dbi->isSuperuser();
// There is a problem with Util::currentUserHasPrivilege():
// it does not detect all kinds of privileges, for example
// a direct privilege on a specific routine. So, at this point,
// we show the Execute link, hoping that the user has the correct rights.
// Also, information_schema might be hiding the ROUTINE_DEFINITION
// but a routine with no input parameters can be nonetheless executed.
// Check if the routine has any input parameters. If it does,
// we will show a dialog to get values for these parameters,
// otherwise we can execute it directly.
$definition = $this->dbi->getDefinition(
$db,
$routine['type'],
$routine['name']
);
$hasExecutePrivilege = Util::currentUserHasPrivilege('EXECUTE', $db);
$executeAction = '';
if ($definition !== null) {
$parser = new Parser($definition);
/**
* @var CreateStatement $stmt
*/
$stmt = $parser->statements[0];
$params = Routine::getParameters($stmt);
if ($hasExecutePrivilege) {
$executeAction = 'execute_routine';
for ($i = 0; $i < $params['num']; $i++) {
if ($routine['type'] == 'PROCEDURE'
&& $params['dir'][$i] == 'OUT'
) {
continue;
}
$executeAction = 'execute_dialog';
break;
}
}
}
$hasExportPrivilege = (Util::currentUserHasPrivilege('CREATE ROUTINE', $db)
&& $currentUser == $routineDefiner) || $this->dbi->isSuperuser();
return $this->template->render('rte/routines/row', [
'db' => $db,
'table' => $table,
'sql_drop' => $sqlDrop,
'routine' => $routine,
'row_class' => $rowClass,
'has_edit_privilege' => $hasEditPrivilege,
'has_export_privilege' => $hasExportPrivilege,
'has_execute_privilege' => $hasExecutePrivilege,
'execute_action' => $executeAction,
]);
}
/**
* Creates the contents for a row in the list of triggers
*
* @param array $trigger An array of routine data
* @param string $rowClass Additional class
*
* @return string HTML code of a cell for the list of triggers
*/
public function getTriggerRow(array $trigger, $rowClass = '')
{
global $db, $table;
return $this->template->render('rte/triggers/row', [
'db' => $db,
'table' => $table,
'trigger' => $trigger,
'has_drop_privilege' => Util::currentUserHasPrivilege('TRIGGER', $db),
'has_edit_privilege' => Util::currentUserHasPrivilege('TRIGGER', $db, $table),
'row_class' => $rowClass,
]);
}
/**
* Creates the contents for a row in the list of events
*
* @param array $event An array of routine data
* @param string $rowClass Additional class
*
* @return string HTML code of a cell for the list of events
*/
public function getEventRow(array $event, $rowClass = '')
{
global $db, $table;
$sqlDrop = sprintf(
'DROP EVENT IF EXISTS %s',
Util::backquote($event['name'])
);
return $this->template->render('rte/events/row', [
'db' => $db,
'table' => $table,
'event' => $event,
'has_privilege' => Util::currentUserHasPrivilege('EVENT', $db),
'sql_drop' => $sqlDrop,
'row_class' => $rowClass,
]);
}
}

View File

@ -1,7 +1,5 @@
<?php
/**
* Functions for trigger management.
*/
declare(strict_types=1);
namespace PhpMyAdmin\Rte;
@ -24,7 +22,7 @@ use function sprintf;
use const ENT_QUOTES;
/**
* PhpMyAdmin\Rte\Triggers class
* Functions for trigger management.
*/
class Triggers
{
@ -34,9 +32,6 @@ class Triggers
/** @var General */
private $general;
/** @var RteList */
private $rteList;
/** @var Words */
private $words;
@ -54,7 +49,6 @@ class Triggers
$this->dbi = $dbi;
$this->export = new Export($this->dbi);
$this->general = new General($this->dbi);
$this->rteList = new RteList($this->dbi);
$this->words = new Words();
$this->template = new Template();
}
@ -98,14 +92,20 @@ class Triggers
$items = $this->dbi->getTriggers($db, $table);
$response = Response::getInstance();
$hasDropPrivilege = Util::currentUserHasPrivilege('TRIGGER', $db);
$hasEditPrivilege = Util::currentUserHasPrivilege('TRIGGER', $db, $table);
$isAjax = $response->isAjax() && empty($_REQUEST['ajax_page_request']);
$rows = '';
foreach ($items as $item) {
$rows .= $this->rteList->getTriggerRow(
$item,
$isAjax ? 'ajaxInsert hide' : ''
);
$rows .= $this->template->render('rte/triggers/row', [
'db' => $db,
'table' => $table,
'trigger' => $item,
'has_drop_privilege' => $hasDropPrivilege,
'has_edit_privilege' => $hasEditPrivilege,
'row_class' => $isAjax ? 'ajaxInsert hide' : '',
]);
}
echo $this->template->render('rte/triggers/list', [
@ -238,7 +238,17 @@ class Triggers
|| ($trigger !== false && $table == $trigger['table'])
) {
$insert = true;
$response->addJSON('new_row', $this->rteList->getTriggerRow($trigger));
$response->addJSON(
'new_row',
$this->template->render('rte/triggers/row', [
'db' => $db,
'table' => $table,
'trigger' => $trigger,
'has_drop_privilege' => Util::currentUserHasPrivilege('TRIGGER', $db),
'has_edit_privilege' => Util::currentUserHasPrivilege('TRIGGER', $db, $table),
'row_class' => '',
])
);
$response->addJSON(
'name',
htmlspecialchars(