You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
5.6 KiB
226 lines
5.6 KiB
2 years ago
|
<?php
|
||
|
/**
|
||
|
* Contains abstract class to hold table preferences/statistics
|
||
|
*/
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace PhpMyAdmin\Plugins\Schema;
|
||
|
|
||
|
use PhpMyAdmin\ConfigStorage\Relation;
|
||
|
use PhpMyAdmin\Font;
|
||
|
use PhpMyAdmin\Index;
|
||
|
use PhpMyAdmin\Util;
|
||
|
|
||
|
use function array_flip;
|
||
|
use function array_keys;
|
||
|
use function array_merge;
|
||
|
use function is_array;
|
||
|
use function rawurldecode;
|
||
|
use function sprintf;
|
||
|
|
||
|
/**
|
||
|
* Table preferences/statistics
|
||
|
*
|
||
|
* This class preserves the table co-ordinates,fields
|
||
|
* and helps in drawing/generating the tables.
|
||
|
*
|
||
|
* @abstract
|
||
|
*/
|
||
|
abstract class TableStats
|
||
|
{
|
||
|
/** @var Dia\Dia|Eps\Eps|Pdf\Pdf|Svg\Svg */
|
||
|
protected $diagram;
|
||
|
|
||
|
/** @var string */
|
||
|
protected $db;
|
||
|
|
||
|
/** @var int */
|
||
|
protected $pageNumber;
|
||
|
|
||
|
/** @var string */
|
||
|
protected $tableName;
|
||
|
|
||
|
/** @var bool */
|
||
|
protected $showKeys;
|
||
|
|
||
|
/** @var bool */
|
||
|
protected $tableDimension;
|
||
|
|
||
|
/** @var mixed */
|
||
|
public $displayfield;
|
||
|
|
||
|
/** @var array */
|
||
|
public $fields = [];
|
||
|
|
||
|
/** @var array */
|
||
|
public $primary = [];
|
||
|
|
||
|
/** @var int|float */
|
||
|
public $x = 0;
|
||
|
|
||
|
/** @var int|float */
|
||
|
public $y = 0;
|
||
|
|
||
|
/** @var int */
|
||
|
public $width = 0;
|
||
|
|
||
|
/** @var int */
|
||
|
public $heightCell = 0;
|
||
|
|
||
|
/** @var bool */
|
||
|
protected $offline;
|
||
|
|
||
|
/** @var Relation */
|
||
|
protected $relation;
|
||
|
|
||
|
/** @var Font */
|
||
|
protected $font;
|
||
|
|
||
|
/**
|
||
|
* @param Pdf\Pdf|Svg\Svg|Eps\Eps|Dia\Dia $diagram schema diagram
|
||
|
* @param string $db current db name
|
||
|
* @param int $pageNumber current page number (from the
|
||
|
* $cfg['Servers'][$i]['table_coords'] table)
|
||
|
* @param string $tableName table name
|
||
|
* @param bool $showKeys whether to display keys or not
|
||
|
* @param bool $tableDimension whether to display table position or not
|
||
|
* @param bool $offline whether the coordinates are sent from the browser
|
||
|
*/
|
||
|
public function __construct(
|
||
|
$diagram,
|
||
|
$db,
|
||
|
$pageNumber,
|
||
|
$tableName,
|
||
|
$showKeys,
|
||
|
$tableDimension,
|
||
|
$offline
|
||
|
) {
|
||
|
global $dbi;
|
||
|
|
||
|
$this->diagram = $diagram;
|
||
|
$this->db = $db;
|
||
|
$this->pageNumber = $pageNumber;
|
||
|
$this->tableName = $tableName;
|
||
|
|
||
|
$this->showKeys = $showKeys;
|
||
|
$this->tableDimension = $tableDimension;
|
||
|
|
||
|
$this->offline = $offline;
|
||
|
|
||
|
$this->relation = new Relation($dbi);
|
||
|
$this->font = new Font();
|
||
|
|
||
|
// checks whether the table exists
|
||
|
// and loads fields
|
||
|
$this->validateTableAndLoadFields();
|
||
|
// load table coordinates
|
||
|
$this->loadCoordinates();
|
||
|
// loads display field
|
||
|
$this->loadDisplayField();
|
||
|
// loads primary keys
|
||
|
$this->loadPrimaryKey();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate whether the table exists.
|
||
|
*/
|
||
|
protected function validateTableAndLoadFields(): void
|
||
|
{
|
||
|
global $dbi;
|
||
|
|
||
|
$sql = 'DESCRIBE ' . Util::backquote($this->tableName);
|
||
|
$result = $dbi->tryQuery($sql);
|
||
|
if (! $result || ! $result->numRows()) {
|
||
|
$this->showMissingTableError();
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
if ($this->showKeys) {
|
||
|
$indexes = Index::getFromTable($this->tableName, $this->db);
|
||
|
$all_columns = [];
|
||
|
foreach ($indexes as $index) {
|
||
|
$all_columns = array_merge(
|
||
|
$all_columns,
|
||
|
array_flip(array_keys($index->getColumns()))
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$this->fields = array_keys($all_columns);
|
||
|
} else {
|
||
|
$this->fields = $result->fetchAllColumn();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Displays an error when the table cannot be found.
|
||
|
*
|
||
|
* @abstract
|
||
|
*/
|
||
|
abstract protected function showMissingTableError(): void;
|
||
|
|
||
|
/**
|
||
|
* Loads coordinates of a table
|
||
|
*/
|
||
|
protected function loadCoordinates(): void
|
||
|
{
|
||
|
if (! isset($_POST['t_h']) || ! is_array($_POST['t_h'])) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
foreach (array_keys($_POST['t_h']) as $key) {
|
||
|
$db = rawurldecode($_POST['t_db'][$key]);
|
||
|
$tbl = rawurldecode($_POST['t_tbl'][$key]);
|
||
|
if ($this->db . '.' . $this->tableName === $db . '.' . $tbl) {
|
||
|
$this->x = (float) $_POST['t_x'][$key];
|
||
|
$this->y = (float) $_POST['t_y'][$key];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Loads the table's display field
|
||
|
*/
|
||
|
protected function loadDisplayField(): void
|
||
|
{
|
||
|
$this->displayfield = $this->relation->getDisplayField($this->db, $this->tableName);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Loads the PRIMARY key.
|
||
|
*/
|
||
|
protected function loadPrimaryKey(): void
|
||
|
{
|
||
|
global $dbi;
|
||
|
|
||
|
$result = $dbi->query('SHOW INDEX FROM ' . Util::backquote($this->tableName) . ';');
|
||
|
if ($result->numRows() <= 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
while ($row = $result->fetchAssoc()) {
|
||
|
if ($row['Key_name'] !== 'PRIMARY') {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$this->primary[] = $row['Column_name'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns title of the current table,
|
||
|
* title can have the dimensions/co-ordinates of the table
|
||
|
*
|
||
|
* @return string title of the current table
|
||
|
*/
|
||
|
protected function getTitle()
|
||
|
{
|
||
|
return ($this->tableDimension
|
||
|
? sprintf('%.0fx%0.f', $this->width, $this->heightCell)
|
||
|
: ''
|
||
|
)
|
||
|
. ' ' . $this->tableName;
|
||
|
}
|
||
|
}
|