mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
initial commit
This commit is contained in:
826
html/phpmyad/libraries/schema/Dia_Relation_Schema.class.php
Normal file
826
html/phpmyad/libraries/schema/Dia_Relation_Schema.class.php
Normal file
@ -0,0 +1,826 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
require_once "Export_Relation_Schema.class.php";
|
||||
|
||||
/**
|
||||
* This Class inherits the XMLwriter class and
|
||||
* helps in developing structure of DIA Schema Export
|
||||
*
|
||||
* @access public
|
||||
* @see http://php.net/manual/en/book.xmlwriter.php
|
||||
*/
|
||||
class PMA_DIA extends XMLWriter
|
||||
{
|
||||
public $title;
|
||||
public $author;
|
||||
public $font;
|
||||
public $fontSize;
|
||||
|
||||
/**
|
||||
* The "PMA_DIA" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the Dia XML document
|
||||
*
|
||||
* @return void
|
||||
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->openMemory();
|
||||
/*
|
||||
* Set indenting using three spaces,
|
||||
* so output is formatted
|
||||
*/
|
||||
|
||||
$this->setIndent(true);
|
||||
$this->setIndentString(' ');
|
||||
/*
|
||||
* Create the XML document
|
||||
*/
|
||||
|
||||
$this->startDocument('1.0', 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Dia Document
|
||||
*
|
||||
* dia document starts by first initializing dia:diagram tag
|
||||
* then dia:diagramdata contains all the attributes that needed
|
||||
* to define the document, then finally a Layer starts which
|
||||
* holds all the objects.
|
||||
*
|
||||
* @param string $paper the size of the paper/document
|
||||
* @param float $topMargin top margin of the paper/document in cm
|
||||
* @param float $bottomMargin bottom margin of the paper/document in cm
|
||||
* @param float $leftMargin left margin of the paper/document in cm
|
||||
* @param float $rightMargin right margin of the paper/document in cm
|
||||
* @param string $portrait document will be portrait or landscape
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @see XMLWriter::startElement(),XMLWriter::writeAttribute(),XMLWriter::writeRaw()
|
||||
*/
|
||||
function startDiaDoc($paper,$topMargin,$bottomMargin,$leftMargin,$rightMargin,$portrait)
|
||||
{
|
||||
if ($portrait == 'P') {
|
||||
$isPortrait='true';
|
||||
} else {
|
||||
$isPortrait='false';
|
||||
}
|
||||
$this->startElement('dia:diagram');
|
||||
$this->writeAttribute('xmlns:dia', 'http://www.lysator.liu.se/~alla/dia/');
|
||||
$this->startElement('dia:diagramdata');
|
||||
$this->writeRaw(
|
||||
'<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#' . $paper . '#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="' . $topMargin . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="' . $bottomMargin . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="' . $leftMargin . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="' . $rightMargin . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="' . $isPortrait . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>');
|
||||
$this->endElement();
|
||||
$this->startElement('dia:layer');
|
||||
$this->writeAttribute('name', 'Background');
|
||||
$this->writeAttribute('visible', 'true');
|
||||
$this->writeAttribute('active', 'true');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends Dia Document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::endElement(),XMLWriter::endDocument()
|
||||
*/
|
||||
function endDiaDoc()
|
||||
{
|
||||
$this->endElement();
|
||||
$this->endDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Dia Document for download
|
||||
*
|
||||
* @param string $fileName name of the dia document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::flush()
|
||||
*/
|
||||
function showOutput($fileName)
|
||||
{
|
||||
if (ob_get_clean()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
$output = $this->flush();
|
||||
PMA_download_header(
|
||||
$fileName . '.dia', 'application/x-dia-diagram', strlen($output)
|
||||
);
|
||||
print $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Table preferences/statistics
|
||||
*
|
||||
* This class preserves the table co-ordinates,fields
|
||||
* and helps in drawing/generating the Tables in dia XML document.
|
||||
*
|
||||
* @name Table_Stats
|
||||
* @see PMA_DIA
|
||||
*/
|
||||
class Table_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
public $tableName;
|
||||
public $fields = array();
|
||||
public $x, $y;
|
||||
public $primary = array();
|
||||
public $tableId;
|
||||
public $tableColor;
|
||||
|
||||
/**
|
||||
* The "Table_Stats" constructor
|
||||
*
|
||||
* @param string $tableName The table name
|
||||
* @param integer $pageNumber The current page number (from the
|
||||
* $cfg['Servers'][$i]['table_coords'] table)
|
||||
* @param boolean $showKeys Whether to display ONLY keys or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @global object The current dia document
|
||||
* @global array The relations settings
|
||||
* @global string The current db name
|
||||
*
|
||||
* @see PMA_DIA
|
||||
*/
|
||||
function __construct($tableName, $pageNumber, $showKeys = false)
|
||||
{
|
||||
global $dia, $cfgRelation, $db;
|
||||
|
||||
$this->tableName = $tableName;
|
||||
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
|
||||
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
|
||||
if (!$result || !PMA_DBI_num_rows($result)) {
|
||||
$dia->dieSchema(
|
||||
$pageNumber, "DIA",
|
||||
sprintf(__('The %s table doesn\'t exist!'), $tableName)
|
||||
);
|
||||
}
|
||||
/*
|
||||
* load fields
|
||||
* check to see if it will load all fields or only the foreign keys
|
||||
*/
|
||||
if ($showKeys) {
|
||||
$indexes = PMA_Index::getFromTable($this->tableName, $db);
|
||||
$all_columns = array();
|
||||
foreach ($indexes as $index) {
|
||||
$all_columns = array_merge(
|
||||
$all_columns,
|
||||
array_flip(array_keys($index->getColumns()))
|
||||
);
|
||||
}
|
||||
$this->fields = array_keys($all_columns);
|
||||
} else {
|
||||
while ($row = PMA_DBI_fetch_row($result)) {
|
||||
$this->fields[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'SELECT x, y FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($tableName) . '\''
|
||||
. ' AND pdf_page_number = ' . $pageNumber;
|
||||
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
|
||||
if (! $result || ! PMA_DBI_num_rows($result)) {
|
||||
$dia->dieSchema(
|
||||
$pageNumber,
|
||||
"DIA",
|
||||
sprintf(
|
||||
__('Please configure the coordinates for table %s'),
|
||||
$tableName
|
||||
)
|
||||
);
|
||||
}
|
||||
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
|
||||
$this->x = (double) $this->x;
|
||||
$this->y = (double) $this->y;
|
||||
/*
|
||||
* displayfield
|
||||
*/
|
||||
$this->displayfield = PMA_getDisplayField($db, $tableName);
|
||||
/*
|
||||
* index
|
||||
*/
|
||||
$result = PMA_DBI_query(
|
||||
'SHOW INDEX FROM ' . PMA_backquote($tableName) . ';',
|
||||
null,
|
||||
PMA_DBI_QUERY_STORE
|
||||
);
|
||||
if (PMA_DBI_num_rows($result) > 0) {
|
||||
while ($row = PMA_DBI_fetch_assoc($result)) {
|
||||
if ($row['Key_name'] == 'PRIMARY') {
|
||||
$this->primary[] = $row['Column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Every object in Dia document needs an ID to identify
|
||||
* so, we used a static variable to keep the things unique
|
||||
*/
|
||||
PMA_Dia_Relation_Schema::$objectId += 1;
|
||||
$this->tableId = PMA_Dia_Relation_Schema::$objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do draw the table
|
||||
*
|
||||
* Tables are generated using object type Database - Table
|
||||
* primary fields are underlined in tables. Dia object
|
||||
* is used to generate the XML of Dia Document. Database Table
|
||||
* Object and their attributes are involved in the combination
|
||||
* of displaing Database - Table on Dia Document.
|
||||
*
|
||||
* @param boolean $changeColor Whether to show color for tables text or not
|
||||
* if changeColor is true then an array of $listOfColors will be used to choose
|
||||
* the random colors for tables text we can change/add more colors to this array
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @global object The current Dia document
|
||||
*
|
||||
* @access public
|
||||
* @see PMA_DIA
|
||||
*/
|
||||
public function tableDraw($changeColor)
|
||||
{
|
||||
global $dia;
|
||||
|
||||
if ($changeColor) {
|
||||
$listOfColors = array(
|
||||
'FF0000',
|
||||
'000099',
|
||||
'00FF00'
|
||||
);
|
||||
shuffle($listOfColors);
|
||||
$this->tableColor = '#' . $listOfColors[0] . '';
|
||||
} else {
|
||||
$this->tableColor = '#000000';
|
||||
}
|
||||
|
||||
$factor = 0.1;
|
||||
|
||||
$dia->startElement('dia:object');
|
||||
$dia->writeAttribute('type', 'Database - Table');
|
||||
$dia->writeAttribute('version', '0');
|
||||
$dia->writeAttribute('id', '' . $this->tableId . '');
|
||||
$dia->writeRaw(
|
||||
'<dia:attribute name="obj_pos">
|
||||
<dia:point val="'
|
||||
. ($this->x * $factor) . ',' . ($this->y * $factor) . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="'
|
||||
.($this->x * $factor) . ',' . ($this->y * $factor) . ';9.97,9.2"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="meta">
|
||||
<dia:composite type="dict"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="'
|
||||
. ($this->x * $factor) . ',' . ($this->y * $factor) . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="5.9199999999999999"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text_colour">
|
||||
<dia:color val="' . $this->tableColor . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_colour">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fill_colour">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_width">
|
||||
<dia:real val="0.10000000000000001"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#' . $this->tableName . '#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="comment">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_comment">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tagging_comment">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="underline_primary_key">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bold_primary_keys">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="normal_font">
|
||||
<dia:font family="monospace" style="0" name="Courier"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="name_font">
|
||||
<dia:font family="sans" style="80" name="Helvetica-Bold"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="comment_font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="normal_font_height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="name_font_height">
|
||||
<dia:real val="0.69999999999999996"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="comment_font_height">
|
||||
<dia:real val="0.69999999999999996"/>
|
||||
</dia:attribute>'
|
||||
);
|
||||
|
||||
$dia->startElement('dia:attribute');
|
||||
$dia->writeAttribute('name', 'attributes');
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
$dia->writeRaw(
|
||||
'<dia:composite type="table_attribute">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#' . $field . '#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="type">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="comment">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>'
|
||||
);
|
||||
unset($pm);
|
||||
$pm = 'false';
|
||||
if (in_array($field, $this->primary)) {
|
||||
$pm = 'true';
|
||||
}
|
||||
if ($field == $this->displayfield) {
|
||||
$pm = 'false';
|
||||
}
|
||||
$dia->writeRaw(
|
||||
'<dia:attribute name="primary_key">
|
||||
<dia:boolean val="' . $pm . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="nullable">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="unique">
|
||||
<dia:boolean val="' . $pm . '"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>'
|
||||
);
|
||||
}
|
||||
$dia->endElement();
|
||||
$dia->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Relation preferences/statistics
|
||||
*
|
||||
* This class fetches the table master and foreign fields positions
|
||||
* and helps in generating the Table references and then connects
|
||||
* master table's master field to foreign table's foreign key
|
||||
* in dia XML document.
|
||||
*
|
||||
* @name Relation_Stats
|
||||
* @see PMA_DIA
|
||||
*/
|
||||
class Relation_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
public $srcConnPointsRight;
|
||||
public $srcConnPointsLeft;
|
||||
public $destConnPointsRight;
|
||||
public $destConnPointsLeft;
|
||||
public $masterTableId;
|
||||
public $foreignTableId;
|
||||
public $masterTablePos;
|
||||
public $foreignTablePos;
|
||||
public $referenceColor;
|
||||
|
||||
/**
|
||||
* The "Relation_Stats" constructor
|
||||
*
|
||||
* @param string $master_table The master table name
|
||||
* @param string $master_field The relation field in the master table
|
||||
* @param string $foreign_table The foreign table name
|
||||
* @param string $foreign_field The relation field in the foreign table
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see Relation_Stats::_getXy
|
||||
*/
|
||||
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
|
||||
{
|
||||
$src_pos = $this->_getXy($master_table, $master_field);
|
||||
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
|
||||
$this->srcConnPointsLeft = $src_pos[0];
|
||||
$this->srcConnPointsRight = $src_pos[1];
|
||||
$this->destConnPointsLeft = $dest_pos[0];
|
||||
$this->destConnPointsRight = $dest_pos[1];
|
||||
$this->masterTablePos = $src_pos[2];
|
||||
$this->foreignTablePos = $dest_pos[2];
|
||||
$this->masterTableId = $master_table->tableId;
|
||||
$this->foreignTableId = $foreign_table->tableId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each Table object have connection points
|
||||
* which is used to connect to other objects in Dia
|
||||
* we detect the position of key in fields and
|
||||
* then determines its left and right connection
|
||||
* points.
|
||||
*
|
||||
* @param string $table The current table name
|
||||
* @param string $column The relation column name
|
||||
*
|
||||
* @return array Table right,left connection points and key position
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _getXy($table, $column)
|
||||
{
|
||||
$pos = array_search($column, $table->fields);
|
||||
// left, right, position
|
||||
$value = 12;
|
||||
if ($pos != 0) {
|
||||
return array($pos + $value + $pos, $pos + $value + $pos + 1, $pos);
|
||||
}
|
||||
return array($pos + $value , $pos + $value + 1, $pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation references
|
||||
*
|
||||
* connects master table's master field to foreign table's
|
||||
* forein field using Dia object type Database - Reference
|
||||
* Dia object is used to generate the XML of Dia Document.
|
||||
* Database reference Object and their attributes are involved
|
||||
* in the combination of displaing Database - reference on Dia Document.
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
* if changeColor is true then an array of $listOfColors will be used to choose
|
||||
* the random colors for references lines. we can change/add more colors to this
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @global object The current Dia document
|
||||
*
|
||||
* @access public
|
||||
* @see PMA_PDF
|
||||
*/
|
||||
public function relationDraw($changeColor)
|
||||
{
|
||||
global $dia;
|
||||
|
||||
PMA_Dia_Relation_Schema::$objectId += 1;
|
||||
/*
|
||||
* if source connection points and destination connection
|
||||
* points are same then return it false and don't draw that
|
||||
* relation
|
||||
*/
|
||||
if ( $this->srcConnPointsRight == $this->destConnPointsRight) {
|
||||
if ( $this->srcConnPointsLeft == $this->destConnPointsLeft) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($changeColor) {
|
||||
$listOfColors = array(
|
||||
'FF0000',
|
||||
'000099',
|
||||
'00FF00'
|
||||
);
|
||||
shuffle($listOfColors);
|
||||
$this->referenceColor = '#' . $listOfColors[0] . '';
|
||||
} else {
|
||||
$this->referenceColor = '#000000';
|
||||
}
|
||||
|
||||
$dia->writeRaw(
|
||||
'<dia:object type="Database - Reference" version="0" id="'
|
||||
. PMA_Dia_Relation_Schema::$objectId . '">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="3.27,18.9198"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.27,8.7175;17.7679,18.9198"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="meta">
|
||||
<dia:composite type="dict"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="orth_points">
|
||||
<dia:point val="3.27,18.9198"/>
|
||||
<dia:point val="2.27,18.9198"/>
|
||||
<dia:point val="2.27,14.1286"/>
|
||||
<dia:point val="17.7679,14.1286"/>
|
||||
<dia:point val="17.7679,9.3375"/>
|
||||
<dia:point val="16.7679,9.3375"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="orth_orient">
|
||||
<dia:enum val="0"/>
|
||||
<dia:enum val="1"/>
|
||||
<dia:enum val="0"/>
|
||||
<dia:enum val="1"/>
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="orth_autoroute">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text_colour">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_colour">
|
||||
<dia:color val="' . $this->referenceColor . '"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_width">
|
||||
<dia:real val="0.10000000000000001"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="0"/>
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="corner_radius">
|
||||
<dia:real val="0"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow">
|
||||
<dia:enum val="22"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_length">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_width">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="start_point_desc">
|
||||
<dia:string>#1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_point_desc">
|
||||
<dia:string>#n#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="normal_font">
|
||||
<dia:font family="monospace" style="0" name="Courier"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="normal_font_height">
|
||||
<dia:real val="0.59999999999999998"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="'
|
||||
. $this->masterTableId . '" connection="'
|
||||
. $this->srcConnPointsRight . '"/>
|
||||
<dia:connection handle="1" to="'
|
||||
. $this->foreignTableId . '" connection="'
|
||||
. $this->destConnPointsRight . '"/>
|
||||
</dia:connections>
|
||||
</dia:object>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dia Relation Schema Class
|
||||
*
|
||||
* Purpose of this class is to generate the Dia XML Document
|
||||
* which is used for representing the database diagrams in Dia IDE
|
||||
* This class uses Database Table and Reference Objects of Dia and with
|
||||
* the combination of these objects actually helps in preparing Dia XML.
|
||||
*
|
||||
* Dia XML is generated by using XMLWriter php extension and this class
|
||||
* inherits Export_Relation_Schema class has common functionality added
|
||||
* to this class
|
||||
*
|
||||
* @name Dia_Relation_Schema
|
||||
*/
|
||||
class PMA_Dia_Relation_Schema extends PMA_Export_Relation_Schema
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
private $_tables = array();
|
||||
private $_relations = array();
|
||||
private $_topMargin = 2.8222000598907471;
|
||||
private $_bottomMargin = 2.8222000598907471;
|
||||
private $_leftMargin = 2.8222000598907471;
|
||||
private $_rightMargin = 2.8222000598907471;
|
||||
public static $objectId = 0;
|
||||
|
||||
/**
|
||||
* The "PMA_Dia_Relation_Schema" constructor
|
||||
*
|
||||
* Upon instantiation This outputs the Dia XML document
|
||||
* that user can download
|
||||
*
|
||||
* @return void
|
||||
* @see PMA_DIA,Table_Stats,Relation_Stats
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $dia,$db;
|
||||
|
||||
$this->setPageNumber($_POST['pdf_page_number']);
|
||||
$this->setShowGrid(isset($_POST['show_grid']));
|
||||
$this->setShowColor($_POST['show_color']);
|
||||
$this->setShowKeys(isset($_POST['show_keys']));
|
||||
$this->setOrientation(isset($_POST['orientation']));
|
||||
$this->setPaper($_POST['paper']);
|
||||
$this->setExportType($_POST['export_type']);
|
||||
|
||||
$dia = new PMA_DIA();
|
||||
$dia->startDiaDoc(
|
||||
$this->paper, $this->_topMargin, $this->_bottomMargin,
|
||||
$this->_leftMargin, $this->_rightMargin, $this->orientation
|
||||
);
|
||||
$alltables = $this->getAllTables($db, $this->pageNumber);
|
||||
foreach ($alltables as $table) {
|
||||
if (! isset($this->tables[$table])) {
|
||||
$this->tables[$table] = new Table_Stats(
|
||||
$table, $this->pageNumber, $this->showKeys
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$seen_a_relation = false;
|
||||
foreach ($alltables as $one_table) {
|
||||
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
|
||||
if ($exist_rel) {
|
||||
$seen_a_relation = true;
|
||||
foreach ($exist_rel as $master_field => $rel) {
|
||||
/* put the foreign table on the schema only if selected
|
||||
* by the user
|
||||
* (do not use array_search() because we would have to
|
||||
* to do a === false and this is not PHP3 compatible)
|
||||
*/
|
||||
if (in_array($rel['foreign_table'], $alltables)) {
|
||||
$this->_addRelation(
|
||||
$one_table, $master_field, $rel['foreign_table'],
|
||||
$rel['foreign_field'], $this->showKeys
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_drawTables($this->showColor);
|
||||
|
||||
if ($seen_a_relation) {
|
||||
$this->_drawRelations($this->showColor);
|
||||
}
|
||||
$dia->endDiaDoc();
|
||||
$dia->showOutput($db . '-' . $this->pageNumber);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines relation objects
|
||||
*
|
||||
* @param string $masterTable The master table name
|
||||
* @param string $masterField The relation field in the master table
|
||||
* @param string $foreignTable The foreign table name
|
||||
* @param string $foreignField The relation field in the foreign table
|
||||
* @param bool $showKeys Whether to display ONLY keys or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see Table_Stats::__construct(),Relation_Stats::__construct()
|
||||
*/
|
||||
private function _addRelation($masterTable, $masterField, $foreignTable, $foreignField, $showKeys)
|
||||
{
|
||||
if (! isset($this->tables[$masterTable])) {
|
||||
$this->tables[$masterTable] = new Table_Stats(
|
||||
$masterTable, $this->pageNumber, $showKeys
|
||||
);
|
||||
}
|
||||
if (! isset($this->tables[$foreignTable])) {
|
||||
$this->tables[$foreignTable] = new Table_Stats(
|
||||
$foreignTable, $this->pageNumber, $showKeys
|
||||
);
|
||||
}
|
||||
$this->_relations[] = new Relation_Stats(
|
||||
$this->tables[$masterTable], $masterField,
|
||||
$this->tables[$foreignTable], $foreignField
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation references
|
||||
*
|
||||
* connects master table's master field to
|
||||
* foreign table's forein field using Dia object
|
||||
* type Database - Reference
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see Relation_Stats::relationDraw()
|
||||
*/
|
||||
private function _drawRelations($changeColor)
|
||||
{
|
||||
foreach ($this->_relations as $relation) {
|
||||
$relation->relationDraw($changeColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws tables
|
||||
*
|
||||
* Tables are generated using Dia object type Database - Table
|
||||
* primary fields are underlined and bold in tables
|
||||
*
|
||||
* @param boolean $changeColor Whether to show color for tables text or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see Table_Stats::tableDraw()
|
||||
*/
|
||||
private function _drawTables($changeColor)
|
||||
{
|
||||
foreach ($this->tables as $table) {
|
||||
$table->tableDraw($changeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
951
html/phpmyad/libraries/schema/Eps_Relation_Schema.class.php
Normal file
951
html/phpmyad/libraries/schema/Eps_Relation_Schema.class.php
Normal file
@ -0,0 +1,951 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
require_once "Export_Relation_Schema.class.php";
|
||||
|
||||
/**
|
||||
* This Class is EPS Library and
|
||||
* helps in developing structure of EPS Schema Export
|
||||
*
|
||||
* @access public
|
||||
* @see http://php.net/manual/en/book.xmlwriter.php
|
||||
*/
|
||||
|
||||
class PMA_EPS
|
||||
{
|
||||
public $font;
|
||||
public $fontSize;
|
||||
public $stringCommands;
|
||||
|
||||
/**
|
||||
* The "PMA_EPS" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the EPS Document.
|
||||
* %!PS-Adobe-3.0 EPSF-3.0 This is the MUST first comment to include
|
||||
* it shows/tells that the Post Script document is purely under
|
||||
* Document Structuring Convention [DSC] and is Compliant
|
||||
* Encapsulated Post Script Document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->stringCommands = "";
|
||||
$this->stringCommands .= "%!PS-Adobe-3.0 EPSF-3.0 \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document title
|
||||
*
|
||||
* @param string $value sets the title text
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setTitle($value)
|
||||
{
|
||||
$this->stringCommands .= '%%Title: ' . $value . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document author
|
||||
*
|
||||
* @param string $value sets the author
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setAuthor($value)
|
||||
{
|
||||
$this->stringCommands .= '%%Creator: ' . $value . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document creation date
|
||||
*
|
||||
* @param string $value sets the date
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setDate($value)
|
||||
{
|
||||
$this->stringCommands .= '%%CreationDate: ' . $value . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document orientation
|
||||
*
|
||||
* @param string $value sets the author
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setOrientation($value)
|
||||
{
|
||||
$this->stringCommands .= "%%PageOrder: Ascend \n";
|
||||
if ($value == "L") {
|
||||
$value = "Landscape";
|
||||
$this->stringCommands .= '%%Orientation: ' . $value . "\n";
|
||||
} else {
|
||||
$value = "Portrait";
|
||||
$this->stringCommands .= '%%Orientation: ' . $value . "\n";
|
||||
}
|
||||
$this->stringCommands .= "%%EndComments \n";
|
||||
$this->stringCommands .= "%%Pages 1 \n";
|
||||
$this->stringCommands .= "%%BoundingBox: 72 150 144 170 \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the font and size
|
||||
*
|
||||
* font can be set whenever needed in EPS
|
||||
*
|
||||
* @param string $value sets the font name e.g Arial
|
||||
* @param integer $size sets the size of the font e.g 10
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setFont($value, $size)
|
||||
{
|
||||
$this->font = $value;
|
||||
$this->fontSize = $size;
|
||||
$this->stringCommands .= "/" . $value . " findfont % Get the basic font\n";
|
||||
$this->stringCommands .= "" . $size . " scalefont % Scale the font to $size points\n";
|
||||
$this->stringCommands .= "setfont % Make it the current font\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font
|
||||
*
|
||||
* @return string return the font name e.g Arial
|
||||
* @access public
|
||||
*/
|
||||
function getFont()
|
||||
{
|
||||
return $this->font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the font Size
|
||||
*
|
||||
* @return string return the size of the font e.g 10
|
||||
* @access public
|
||||
*/
|
||||
function getFontSize()
|
||||
{
|
||||
return $this->fontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the line
|
||||
*
|
||||
* drawing the lines from x,y source to x,y destination and set the
|
||||
* width of the line. lines helps in showing relationships of tables
|
||||
*
|
||||
* @param integer $x_from The x_from attribute defines the start
|
||||
* left position of the element
|
||||
* @param integer $y_from The y_from attribute defines the start
|
||||
* right position of the element
|
||||
* @param integer $x_to The x_to attribute defines the end
|
||||
* left position of the element
|
||||
* @param integer $y_to The y_to attribute defines the end
|
||||
* right position of the element
|
||||
* @param integer $lineWidth Sets the width of the line e.g 2
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function line($x_from = 0, $y_from = 0, $x_to = 0, $y_to = 0, $lineWidth = 0)
|
||||
{
|
||||
$this->stringCommands .= $lineWidth . " setlinewidth \n";
|
||||
$this->stringCommands .= $x_from . ' ' . $y_from . " moveto \n";
|
||||
$this->stringCommands .= $x_to . ' ' . $y_to . " lineto \n";
|
||||
$this->stringCommands .= "stroke \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the rectangle
|
||||
*
|
||||
* drawing the rectangle from x,y source to x,y destination and set the
|
||||
* width of the line. rectangles drawn around the text shown of fields
|
||||
*
|
||||
* @param integer $x_from The x_from attribute defines the start
|
||||
left position of the element
|
||||
* @param integer $y_from The y_from attribute defines the start
|
||||
right position of the element
|
||||
* @param integer $x_to The x_to attribute defines the end
|
||||
left position of the element
|
||||
* @param integer $y_to The y_to attribute defines the end
|
||||
right position of the element
|
||||
* @param integer $lineWidth Sets the width of the line e.g 2
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function rect($x_from, $y_from, $x_to, $y_to, $lineWidth)
|
||||
{
|
||||
$this->stringCommands .= $lineWidth . " setlinewidth \n";
|
||||
$this->stringCommands .= "newpath \n";
|
||||
$this->stringCommands .= $x_from . " " . $y_from . " moveto \n";
|
||||
$this->stringCommands .= "0 " . $y_to . " rlineto \n";
|
||||
$this->stringCommands .= $x_to . " 0 rlineto \n";
|
||||
$this->stringCommands .= "0 -" . $y_to . " rlineto \n";
|
||||
$this->stringCommands .= "closepath \n";
|
||||
$this->stringCommands .= "stroke \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current point
|
||||
*
|
||||
* The moveto operator takes two numbers off the stack and treats
|
||||
* them as x and y coordinates to which to move. The coordinates
|
||||
* specified become the current point.
|
||||
*
|
||||
* @param integer $x The x attribute defines the left position of the element
|
||||
* @param integer $y The y attribute defines the right position of the element
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function moveTo($x, $y)
|
||||
{
|
||||
$this->stringCommands .= $x . ' ' . $y . " moveto \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Output/Display the text
|
||||
*
|
||||
* @param string $text The string to be displayed
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function show($text)
|
||||
{
|
||||
$this->stringCommands .= '(' . $text . ") show \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the text at specified co-ordinates
|
||||
*
|
||||
* @param string $text String to be displayed
|
||||
* @param integer $x X attribute defines the left position of the element
|
||||
* @param integer $y Y attribute defines the right position of the element
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function showXY($text, $x, $y)
|
||||
{
|
||||
$this->moveTo($x, $y);
|
||||
$this->show($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* get width of string/text
|
||||
*
|
||||
* EPS text width is calcualted depending on font name
|
||||
* and font size. It is very important to know the width of text
|
||||
* because rectangle is drawn around it.
|
||||
*
|
||||
* This is a bit hardcore method. I didn't found any other better than this.
|
||||
* if someone found better than this. would love to hear that method
|
||||
*
|
||||
* @param string $text string that width will be calculated
|
||||
* @param integer $font name of the font like Arial,sans-serif etc
|
||||
* @param integer $fontSize size of font
|
||||
*
|
||||
* @return integer width of the text
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function getStringWidth($text,$font,$fontSize)
|
||||
{
|
||||
/*
|
||||
* Start by counting the width, giving each character a modifying value
|
||||
*/
|
||||
$count = 0;
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("i", "j", "l"), "", $text))) * 0.23);//ijl
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("f"), "", $text))) * 0.27);//f
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("t", "I"), "", $text))) * 0.28);//tI
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("r"), "", $text))) * 0.34);//r
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("1"), "", $text))) * 0.49);//1
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("c", "k", "s", "v", "x", "y", "z", "J"), "", $text))) * 0.5);//cksvxyzJ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("a", "b", "d", "e", "g", "h", "n", "o", "p", "q", "u", "L", "0", "2", "3", "4", "5", "6", "7", "8", "9"), "", $text))) * 0.56);//abdeghnopquL023456789
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("F", "T", "Z"), "", $text))) * 0.61);//FTZ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("A", "B", "E", "K", "P", "S", "V", "X", "Y"), "", $text))) * 0.67);//ABEKPSVXY
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("w", "C", "D", "H", "N", "R", "U"), "", $text))) * 0.73);//wCDHNRU
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("G", "O", "Q"), "", $text))) * 0.78);//GOQ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("m", "M"), "", $text))) * 0.84);//mM
|
||||
$count = $count + ((strlen($text) - strlen(str_replace("W", "", $text))) * .95);//W
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(" ", "", $text))) * .28);//" "
|
||||
$text = str_replace(" ", "", $text);//remove the " "'s
|
||||
$count = $count + (strlen(preg_replace("/[a-z0-9]/i", "", $text)) * 0.3); //all other chrs
|
||||
|
||||
$modifier = 1;
|
||||
$font = strtolower($font);
|
||||
switch($font){
|
||||
/*
|
||||
* no modifier for arial and sans-serif
|
||||
*/
|
||||
case 'arial':
|
||||
case 'sans-serif':
|
||||
break;
|
||||
/*
|
||||
* .92 modifer for time, serif, brushscriptstd, and californian fb
|
||||
*/
|
||||
case 'times':
|
||||
case 'serif':
|
||||
case 'brushscriptstd':
|
||||
case 'californian fb':
|
||||
$modifier = .92;
|
||||
break;
|
||||
/*
|
||||
* 1.23 modifier for broadway
|
||||
*/
|
||||
case 'broadway':
|
||||
$modifier = 1.23;
|
||||
break;
|
||||
}
|
||||
$textWidth = $count*$fontSize;
|
||||
return ceil($textWidth*$modifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends EPS Document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function endEpsDoc()
|
||||
{
|
||||
$this->stringCommands .= "showpage \n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Output EPS Document for download
|
||||
*
|
||||
* @param string $fileName name of the eps document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function showOutput($fileName)
|
||||
{
|
||||
// if(ob_get_clean()){
|
||||
//ob_end_clean();
|
||||
//}
|
||||
$output = $this->stringCommands;
|
||||
PMA_download_header($fileName . '.eps', 'image/x-eps', strlen($output));
|
||||
print $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Table preferences/statistics
|
||||
*
|
||||
* This class preserves the table co-ordinates,fields
|
||||
* and helps in drawing/generating the Tables in EPS.
|
||||
*
|
||||
* @name Table_Stats
|
||||
* @see PMA_EPS
|
||||
*/
|
||||
class Table_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
|
||||
private $_tableName;
|
||||
private $_showInfo = false;
|
||||
|
||||
public $width = 0;
|
||||
public $height;
|
||||
public $fields = array();
|
||||
public $heightCell = 0;
|
||||
public $currentCell = 0;
|
||||
public $x, $y;
|
||||
public $primary = array();
|
||||
|
||||
/**
|
||||
* The "Table_Stats" constructor
|
||||
*
|
||||
* @param string $tableName The table name
|
||||
* @param string $font The font name
|
||||
* @param integer $fontSize The font size
|
||||
* @param integer $pageNumber Page number
|
||||
* @param integer &$same_wide_width The max width among tables
|
||||
* @param boolean $showKeys Whether to display keys or not
|
||||
* @param boolean $showInfo Whether to display table position or not
|
||||
*
|
||||
* @global object The current eps document
|
||||
* @global integer The current page number (from the
|
||||
* $cfg['Servers'][$i]['table_coords'] table)
|
||||
* @global array The relations settings
|
||||
* @global string The current db name
|
||||
*
|
||||
* @access private
|
||||
* @see PMA_EPS, Table_Stats::Table_Stats_setWidth,
|
||||
* Table_Stats::Table_Stats_setHeight
|
||||
*/
|
||||
function __construct($tableName, $font, $fontSize, $pageNumber, &$same_wide_width,
|
||||
$showKeys = false, $showInfo = false)
|
||||
{
|
||||
global $eps, $cfgRelation, $db;
|
||||
|
||||
$this->_tableName = $tableName;
|
||||
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
|
||||
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
|
||||
if (! $result || ! PMA_DBI_num_rows($result)) {
|
||||
$eps->dieSchema(
|
||||
$pageNumber, "EPS",
|
||||
sprintf(__('The %s table doesn\'t exist!'), $tableName)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* load fields
|
||||
* check to see if it will load all fields or only the foreign keys
|
||||
*/
|
||||
if ($showKeys) {
|
||||
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
|
||||
$all_columns = array();
|
||||
foreach ($indexes as $index) {
|
||||
$all_columns = array_merge(
|
||||
$all_columns,
|
||||
array_flip(array_keys($index->getColumns()))
|
||||
);
|
||||
}
|
||||
$this->fields = array_keys($all_columns);
|
||||
} else {
|
||||
while ($row = PMA_DBI_fetch_row($result)) {
|
||||
$this->fields[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_showInfo = $showInfo;
|
||||
|
||||
// height and width
|
||||
$this->_setHeightTable($fontSize);
|
||||
|
||||
// setWidth must me after setHeight, because title
|
||||
// can include table height which changes table width
|
||||
$this->_setWidthTable($font, $fontSize);
|
||||
if ($same_wide_width < $this->width) {
|
||||
$same_wide_width = $this->width;
|
||||
}
|
||||
|
||||
// x and y
|
||||
$sql = 'SELECT x, y FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($tableName) . '\''
|
||||
. ' AND pdf_page_number = ' . $pageNumber;
|
||||
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
|
||||
|
||||
if (! $result || ! PMA_DBI_num_rows($result)) {
|
||||
$eps->dieSchema(
|
||||
$pageNumber, "EPS",
|
||||
sprintf(
|
||||
__('Please configure the coordinates for table %s'),
|
||||
$tableName
|
||||
)
|
||||
);
|
||||
}
|
||||
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
|
||||
$this->x = (double) $this->x;
|
||||
$this->y = (double) $this->y;
|
||||
// displayfield
|
||||
$this->displayfield = PMA_getDisplayField($db, $tableName);
|
||||
// index
|
||||
$result = PMA_DBI_query(
|
||||
'SHOW INDEX FROM ' . PMA_backquote($tableName) . ';',
|
||||
null, PMA_DBI_QUERY_STORE
|
||||
);
|
||||
if (PMA_DBI_num_rows($result) > 0) {
|
||||
while ($row = PMA_DBI_fetch_assoc($result)) {
|
||||
if ($row['Key_name'] == 'PRIMARY') {
|
||||
$this->primary[] = $row['Column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns title of the current table,
|
||||
* title can have the dimensions/co-ordinates of the table
|
||||
*
|
||||
* @return string The relation/table name
|
||||
* @access private
|
||||
*/
|
||||
private function _getTitle()
|
||||
{
|
||||
return ($this->_showInfo
|
||||
? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell)
|
||||
: '') . ' ' . $this->_tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the table
|
||||
*
|
||||
* @param string $font The font name
|
||||
* @param integer $fontSize The font size
|
||||
*
|
||||
* @global object The current eps document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see PMA_EPS
|
||||
*/
|
||||
private function _setWidthTable($font,$fontSize)
|
||||
{
|
||||
global $eps;
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
$this->width = max(
|
||||
$this->width,
|
||||
$eps->getStringWidth($field, $font, $fontSize)
|
||||
);
|
||||
}
|
||||
$this->width += $eps->getStringWidth(' ', $font, $fontSize);
|
||||
/*
|
||||
* it is unknown what value must be added, because
|
||||
* table title is affected by the tabe width value
|
||||
*/
|
||||
while ($this->width < $eps->getStringWidth($this->_getTitle(), $font, $fontSize)) {
|
||||
$this->width += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the height of the table
|
||||
*
|
||||
* @param integer $fontSize The font size
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _setHeightTable($fontSize)
|
||||
{
|
||||
$this->heightCell = $fontSize + 4;
|
||||
$this->height = (count($this->fields) + 1) * $this->heightCell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the table
|
||||
*
|
||||
* @param boolean $showColor Whether to display color
|
||||
*
|
||||
* @global object The current eps document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @see PMA_EPS,PMA_EPS::line,PMA_EPS::rect
|
||||
*/
|
||||
public function tableDraw($showColor)
|
||||
{
|
||||
global $eps;
|
||||
//echo $this->_tableName.'<br />';
|
||||
$eps->rect($this->x, $this->y + 12, $this->width, $this->heightCell, 1);
|
||||
$eps->showXY($this->_getTitle(), $this->x + 5, $this->y + 14);
|
||||
foreach ($this->fields as $field) {
|
||||
$this->currentCell += $this->heightCell;
|
||||
$showColor = 'none';
|
||||
if ($showColor) {
|
||||
if (in_array($field, $this->primary)) {
|
||||
$showColor = '#0c0';
|
||||
}
|
||||
if ($field == $this->displayfield) {
|
||||
$showColor = 'none';
|
||||
}
|
||||
}
|
||||
$eps->rect(
|
||||
$this->x, $this->y + 12 + $this->currentCell,
|
||||
$this->width, $this->heightCell, 1
|
||||
);
|
||||
$eps->showXY($field, $this->x + 5, $this->y + 14 + $this->currentCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Relation preferences/statistics
|
||||
*
|
||||
* This class fetches the table master and foreign fields positions
|
||||
* and helps in generating the Table references and then connects
|
||||
* master table's master field to foreign table's foreign key
|
||||
* in EPS document.
|
||||
*
|
||||
* @name Relation_Stats
|
||||
* @see PMA_EPS
|
||||
*/
|
||||
class Relation_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
public $xSrc, $ySrc;
|
||||
public $srcDir ;
|
||||
public $destDir;
|
||||
public $xDest, $yDest;
|
||||
public $wTick = 10;
|
||||
|
||||
/**
|
||||
* The "Relation_Stats" constructor
|
||||
*
|
||||
* @param string $master_table The master table name
|
||||
* @param string $master_field The relation field in the master table
|
||||
* @param string $foreign_table The foreign table name
|
||||
* @param string $foreign_field The relation field in the foreign table
|
||||
*
|
||||
* @see Relation_Stats::_getXy
|
||||
*/
|
||||
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
|
||||
{
|
||||
$src_pos = $this->_getXy($master_table, $master_field);
|
||||
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
|
||||
/*
|
||||
* [0] is x-left
|
||||
* [1] is x-right
|
||||
* [2] is y
|
||||
*/
|
||||
$src_left = $src_pos[0] - $this->wTick;
|
||||
$src_right = $src_pos[1] + $this->wTick;
|
||||
$dest_left = $dest_pos[0] - $this->wTick;
|
||||
$dest_right = $dest_pos[1] + $this->wTick;
|
||||
|
||||
$d1 = abs($src_left - $dest_left);
|
||||
$d2 = abs($src_right - $dest_left);
|
||||
$d3 = abs($src_left - $dest_right);
|
||||
$d4 = abs($src_right - $dest_right);
|
||||
$d = min($d1, $d2, $d3, $d4);
|
||||
|
||||
if ($d == $d1) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d2) {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d3) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
} else {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
}
|
||||
$this->ySrc = $src_pos[2] + 10;
|
||||
$this->yDest = $dest_pos[2] + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets arrows coordinates
|
||||
*
|
||||
* @param string $table The current table name
|
||||
* @param string $column The relation column name
|
||||
*
|
||||
* @return array Arrows coordinates
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _getXy($table, $column)
|
||||
{
|
||||
$pos = array_search($column, $table->fields);
|
||||
// x_left, x_right, y
|
||||
return array(
|
||||
$table->x,
|
||||
$table->x + $table->width,
|
||||
$table->y + ($pos + 1.5) * $table->heightCell
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* draws relation links and arrows
|
||||
* shows foreign key relations
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @global object The current EPS document
|
||||
*
|
||||
* @access public
|
||||
* @see PMA_EPS
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function relationDraw($changeColor)
|
||||
{
|
||||
global $eps;
|
||||
|
||||
if ($changeColor) {
|
||||
$listOfColors = array(
|
||||
'red',
|
||||
'grey',
|
||||
'black',
|
||||
'yellow',
|
||||
'green',
|
||||
'cyan',
|
||||
' orange'
|
||||
);
|
||||
shuffle($listOfColors);
|
||||
$color = $listOfColors[0];
|
||||
} else {
|
||||
$color = 'black';
|
||||
}
|
||||
// draw a line like -- to foreign field
|
||||
$eps->line(
|
||||
$this->xSrc,
|
||||
$this->ySrc,
|
||||
$this->xSrc + $this->srcDir * $this->wTick,
|
||||
$this->ySrc,
|
||||
1
|
||||
);
|
||||
// draw a line like -- to master field
|
||||
$eps->line(
|
||||
$this->xDest + $this->destDir * $this->wTick,
|
||||
$this->yDest,
|
||||
$this->xDest,
|
||||
$this->yDest,
|
||||
1
|
||||
);
|
||||
// draw a line that connects to master field line and foreign field line
|
||||
$eps->line(
|
||||
$this->xSrc + $this->srcDir * $this->wTick,
|
||||
$this->ySrc,
|
||||
$this->xDest + $this->destDir * $this->wTick,
|
||||
$this->yDest,
|
||||
1
|
||||
);
|
||||
$root2 = 2 * sqrt(2);
|
||||
$eps->line(
|
||||
$this->xSrc + $this->srcDir * $this->wTick * 0.75,
|
||||
$this->ySrc,
|
||||
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
|
||||
$this->ySrc + $this->wTick / $root2,
|
||||
1
|
||||
);
|
||||
$eps->line(
|
||||
$this->xSrc + $this->srcDir * $this->wTick * 0.75,
|
||||
$this->ySrc,
|
||||
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
|
||||
$this->ySrc - $this->wTick / $root2,
|
||||
1
|
||||
);
|
||||
$eps->line(
|
||||
$this->xDest + $this->destDir * $this->wTick / 2,
|
||||
$this->yDest,
|
||||
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
|
||||
$this->yDest + $this->wTick / $root2,
|
||||
1
|
||||
);
|
||||
$eps->line(
|
||||
$this->xDest + $this->destDir * $this->wTick / 2,
|
||||
$this->yDest,
|
||||
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
|
||||
$this->yDest - $this->wTick / $root2,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* end of the "Relation_Stats" class
|
||||
*/
|
||||
|
||||
/**
|
||||
* EPS Relation Schema Class
|
||||
*
|
||||
* Purpose of this class is to generate the EPS Document
|
||||
* which is used for representing the database diagrams.
|
||||
* This class uses post script commands and with
|
||||
* the combination of these commands actually helps in preparing EPS Document.
|
||||
*
|
||||
* This class inherits Export_Relation_Schema class has common functionality added
|
||||
* to this class
|
||||
*
|
||||
* @name Eps_Relation_Schema
|
||||
*/
|
||||
class PMA_Eps_Relation_Schema extends PMA_Export_Relation_Schema
|
||||
{
|
||||
private $tables = array();
|
||||
private $_relations = array();
|
||||
|
||||
/**
|
||||
* The "PMA_EPS_Relation_Schema" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the EPS document
|
||||
* user will be prompted for download as .eps extension
|
||||
*
|
||||
* @return void
|
||||
* @see PMA_EPS
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $eps,$db;
|
||||
|
||||
$this->setPageNumber($_POST['pdf_page_number']);
|
||||
$this->setShowColor(isset($_POST['show_color']));
|
||||
$this->setShowKeys(isset($_POST['show_keys']));
|
||||
$this->setTableDimension(isset($_POST['show_table_dimension']));
|
||||
$this->setAllTableSameWidth(isset($_POST['all_table_same_wide']));
|
||||
$this->setOrientation($_POST['orientation']);
|
||||
$this->setExportType($_POST['export_type']);
|
||||
|
||||
$eps = new PMA_EPS();
|
||||
$eps->setTitle(
|
||||
sprintf(
|
||||
__('Schema of the %s database - Page %s'),
|
||||
$db,
|
||||
$this->pageNumber
|
||||
)
|
||||
);
|
||||
$eps->setAuthor('phpMyAdmin ' . PMA_VERSION);
|
||||
$eps->setDate(date("j F Y, g:i a"));
|
||||
$eps->setOrientation($this->orientation);
|
||||
$eps->setFont('Verdana', '10');
|
||||
|
||||
$alltables = $this->getAllTables($db, $this->pageNumber);
|
||||
|
||||
foreach ($alltables AS $table) {
|
||||
if (! isset($this->tables[$table])) {
|
||||
$this->tables[$table] = new Table_Stats(
|
||||
$table, $eps->getFont(), $eps->getFontSize(), $this->pageNumber,
|
||||
$this->_tablewidth, $this->showKeys, $this->tableDimension
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->sameWide) {
|
||||
$this->tables[$table]->width = $this->_tablewidth;
|
||||
}
|
||||
}
|
||||
|
||||
$seen_a_relation = false;
|
||||
foreach ($alltables as $one_table) {
|
||||
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
|
||||
if ($exist_rel) {
|
||||
$seen_a_relation = true;
|
||||
foreach ($exist_rel as $master_field => $rel) {
|
||||
/* put the foreign table on the schema only if selected
|
||||
* by the user
|
||||
* (do not use array_search() because we would have to
|
||||
* to do a === false and this is not PHP3 compatible)
|
||||
*/
|
||||
if (in_array($rel['foreign_table'], $alltables)) {
|
||||
$this->_addRelation(
|
||||
$one_table, $eps->getFont(), $eps->getFontSize(),
|
||||
$master_field, $rel['foreign_table'],
|
||||
$rel['foreign_field'], $this->tableDimension
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($seen_a_relation) {
|
||||
$this->_drawRelations($this->showColor);
|
||||
}
|
||||
|
||||
$this->_drawTables($this->showColor);
|
||||
$eps->endEpsDoc();
|
||||
$eps->showOutput($db.'-'.$this->pageNumber);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines relation objects
|
||||
*
|
||||
* @param string $masterTable The master table name
|
||||
* @param string $font The font
|
||||
* @param int $fontSize The font size
|
||||
* @param string $masterField The relation field in the master table
|
||||
* @param string $foreignTable The foreign table name
|
||||
* @param string $foreignField The relation field in the foreign table
|
||||
* @param boolean $showInfo Whether to display table position or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
|
||||
*/
|
||||
private function _addRelation($masterTable, $font, $fontSize, $masterField,
|
||||
$foreignTable, $foreignField, $showInfo)
|
||||
{
|
||||
if (! isset($this->tables[$masterTable])) {
|
||||
$this->tables[$masterTable] = new Table_Stats(
|
||||
$masterTable, $font, $fontSize, $this->pageNumber,
|
||||
$this->_tablewidth, false, $showInfo
|
||||
);
|
||||
}
|
||||
if (! isset($this->tables[$foreignTable])) {
|
||||
$this->tables[$foreignTable] = new Table_Stats(
|
||||
$foreignTable, $font, $fontSize, $this->pageNumber,
|
||||
$this->_tablewidth, false, $showInfo
|
||||
);
|
||||
}
|
||||
$this->_relations[] = new Relation_Stats(
|
||||
$this->tables[$masterTable], $masterField,
|
||||
$this->tables[$foreignTable], $foreignField
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation arrows and lines connects master table's master field to
|
||||
* foreign table's forein field
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see Relation_Stats::relationDraw()
|
||||
*/
|
||||
private function _drawRelations($changeColor)
|
||||
{
|
||||
foreach ($this->_relations as $relation) {
|
||||
$relation->relationDraw($changeColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws tables
|
||||
*
|
||||
* @param boolean $changeColor Whether to show color for primary fields or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
* @see Table_Stats::Table_Stats_tableDraw()
|
||||
*/
|
||||
private function _drawTables($changeColor)
|
||||
{
|
||||
foreach ($this->tables as $table) {
|
||||
$table->tableDraw($changeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
243
html/phpmyad/libraries/schema/Export_Relation_Schema.class.php
Normal file
243
html/phpmyad/libraries/schema/Export_Relation_Schema.class.php
Normal file
@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is inherited by all schema classes
|
||||
* It contains those methods which are common in them
|
||||
* it works like factory pattern
|
||||
*/
|
||||
class PMA_Export_Relation_Schema
|
||||
{
|
||||
private $_pageTitle;
|
||||
public $showGrid;
|
||||
public $showColor;
|
||||
public $tableDimension;
|
||||
public $sameWide;
|
||||
public $withDoc;
|
||||
public $showKeys;
|
||||
public $orientation;
|
||||
public $paper;
|
||||
public $pageNumber;
|
||||
|
||||
/**
|
||||
* Set Page Number
|
||||
*
|
||||
* @param integer $value Page Number of the document to be created
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setPageNumber($value)
|
||||
{
|
||||
$this->pageNumber = isset($value) ? $value : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Show Grid
|
||||
*
|
||||
* @param boolean $value show grid of the document or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setShowGrid($value)
|
||||
{
|
||||
$this->showGrid = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets showColor
|
||||
*
|
||||
* @param string $value 'on' to set the the variable
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
public function setShowColor($value)
|
||||
{
|
||||
$this->showColor = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Table Dimension
|
||||
*
|
||||
* @param boolean $value show table co-ordinates or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setTableDimension($value)
|
||||
{
|
||||
$this->tableDimension = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set same width of All Tables
|
||||
*
|
||||
* @param boolean $value set same width of all tables or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setAllTableSameWidth($value)
|
||||
{
|
||||
$this->sameWide = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Data Dictionary
|
||||
*
|
||||
* @param boolean $value show selected database data dictionary or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setWithDataDictionary($value)
|
||||
{
|
||||
$this->withDoc = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Show only keys
|
||||
*
|
||||
* @param boolean $value show only keys or not
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setShowKeys($value)
|
||||
{
|
||||
$this->showKeys = (isset($value) && $value == 'on') ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Orientation
|
||||
*
|
||||
* @param string $value Orientation will be portrait or landscape
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setOrientation($value)
|
||||
{
|
||||
$this->orientation = (isset($value) && $value == 'P') ? 'P' : 'L';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type of paper
|
||||
*
|
||||
* @param string $value paper type can be A4 etc
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setPaper($value)
|
||||
{
|
||||
$this->paper = isset($value) ? $value : 'A4';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title of the page
|
||||
*
|
||||
* @param string $title title of the page displayed at top of the document
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setPageTitle($title)
|
||||
{
|
||||
$this->_pageTitle=$title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type of export relational schema
|
||||
*
|
||||
* @param string $value can be pdf,svg,dia,visio,eps etc
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setExportType($value)
|
||||
{
|
||||
$this->exportType=$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all tables involved or included in page
|
||||
*
|
||||
* @param string $db name of the database
|
||||
* @param integer $pageNumber page no. whose tables will be fetched in an array
|
||||
*
|
||||
* @return Array an array of tables
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getAllTables($db, $pageNumber)
|
||||
{
|
||||
global $cfgRelation;
|
||||
// Get All tables
|
||||
$tab_sql = 'SELECT table_name FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND pdf_page_number = ' . $pageNumber;
|
||||
|
||||
$tab_rs = PMA_query_as_controluser($tab_sql, null, PMA_DBI_QUERY_STORE);
|
||||
if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) {
|
||||
$this->dieSchema('', __('This page does not contain any tables!'));
|
||||
}
|
||||
while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) {
|
||||
$alltables[] = PMA_sqlAddSlashes($curr_table['table_name']);
|
||||
}
|
||||
return $alltables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error message
|
||||
*
|
||||
* @param integer $pageNumber ID of the chosen page
|
||||
* @param string $type Schema Type
|
||||
* @param string $error_message The error mesage
|
||||
*
|
||||
* @global array the PMA configuration array
|
||||
* @global string the current database name
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function dieSchema($pageNumber, $type = '', $error_message = '')
|
||||
{
|
||||
global $cfg;
|
||||
global $db;
|
||||
|
||||
include_once './libraries/header.inc.php';
|
||||
echo "<p><strong>" . __("SCHEMA ERROR: ") . $type . "</strong></p>" . "\n";
|
||||
if (!empty($error_message)) {
|
||||
$error_message = htmlspecialchars($error_message);
|
||||
}
|
||||
echo '<p>' . "\n";
|
||||
echo ' ' . $error_message . "\n";
|
||||
echo '</p>' . "\n";
|
||||
echo '<a href="schema_edit.php?' . PMA_generate_common_url($db)
|
||||
. '&do=selectpage&chpage=' . $pageNumber . '&action_choose=0'
|
||||
. '">' . __('Back') . '</a>';
|
||||
echo "\n";
|
||||
include_once './libraries/footer.inc.php';
|
||||
exit();
|
||||
}
|
||||
}
|
||||
?>
|
1385
html/phpmyad/libraries/schema/Pdf_Relation_Schema.class.php
Normal file
1385
html/phpmyad/libraries/schema/Pdf_Relation_Schema.class.php
Normal file
File diff suppressed because it is too large
Load Diff
949
html/phpmyad/libraries/schema/Svg_Relation_Schema.class.php
Normal file
949
html/phpmyad/libraries/schema/Svg_Relation_Schema.class.php
Normal file
@ -0,0 +1,949 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
require_once 'Export_Relation_Schema.class.php';
|
||||
|
||||
/**
|
||||
* This Class inherits the XMLwriter class and
|
||||
* helps in developing structure of SVG Schema Export
|
||||
*
|
||||
* @access public
|
||||
* @see http://php.net/manual/en/book.xmlwriter.php
|
||||
*/
|
||||
class PMA_SVG extends XMLWriter
|
||||
{
|
||||
public $title;
|
||||
public $author;
|
||||
public $font;
|
||||
public $fontSize;
|
||||
|
||||
/**
|
||||
* The "PMA_SVG" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the Svg XML document
|
||||
*
|
||||
* @return void
|
||||
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->openMemory();
|
||||
/*
|
||||
* Set indenting using three spaces,
|
||||
* so output is formatted
|
||||
*/
|
||||
|
||||
$this->setIndent(true);
|
||||
$this->setIndentString(' ');
|
||||
/*
|
||||
* Create the XML document
|
||||
*/
|
||||
|
||||
$this->startDocument('1.0', 'UTF-8');
|
||||
$this->startDtd(
|
||||
'svg', '-//W3C//DTD SVG 1.1//EN',
|
||||
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
|
||||
);
|
||||
$this->endDtd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document title
|
||||
*
|
||||
* @param string $value sets the title text
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setTitle($value)
|
||||
{
|
||||
$this->title = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document author
|
||||
*
|
||||
* @param string $value sets the author
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setAuthor($value)
|
||||
{
|
||||
$this->author = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document font
|
||||
*
|
||||
* @param string $value sets the font e.g Arial, Sans-serif etc
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setFont($value)
|
||||
{
|
||||
$this->font = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document font
|
||||
*
|
||||
* @return string returns the font name
|
||||
* @access public
|
||||
*/
|
||||
function getFont()
|
||||
{
|
||||
return $this->font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document font size
|
||||
*
|
||||
* @param string $value sets the font size in pixels
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setFontSize($value)
|
||||
{
|
||||
$this->fontSize = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document font size
|
||||
*
|
||||
* @return string returns the font size
|
||||
* @access public
|
||||
*/
|
||||
function getFontSize()
|
||||
{
|
||||
return $this->fontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Svg Document
|
||||
*
|
||||
* svg document starts by first initializing svg tag
|
||||
* which contains all the attributes and namespace that needed
|
||||
* to define the svg document
|
||||
*
|
||||
* @param integer $width total width of the Svg document
|
||||
* @param integer $height total height of the Svg document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*
|
||||
* @see XMLWriter::startElement(),XMLWriter::writeAttribute()
|
||||
*/
|
||||
function startSvgDoc($width,$height)
|
||||
{
|
||||
$this->startElement('svg');
|
||||
$this->writeAttribute('width', $width);
|
||||
$this->writeAttribute('height', $height);
|
||||
$this->writeAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
||||
$this->writeAttribute('version', '1.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends Svg Document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::endElement(),XMLWriter::endDocument()
|
||||
*/
|
||||
function endSvgDoc()
|
||||
{
|
||||
$this->endElement();
|
||||
$this->endDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* output Svg Document
|
||||
*
|
||||
* svg document prompted to the user for download
|
||||
* Svg document saved in .svg extension and can be
|
||||
* easily changeable by using any svg IDE
|
||||
*
|
||||
* @param string $fileName file name
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::startElement(),XMLWriter::writeAttribute()
|
||||
*/
|
||||
function showOutput($fileName)
|
||||
{
|
||||
//ob_get_clean();
|
||||
$output = $this->flush();
|
||||
PMA_download_header($fileName . '.svg', 'image/svg+xml', strlen($output));
|
||||
print $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws Svg elements
|
||||
*
|
||||
* SVG has some predefined shape elements like rectangle & text
|
||||
* and other elements who have x,y co-ordinates are drawn.
|
||||
* specify their width and height and can give styles too.
|
||||
*
|
||||
* @param string $name Svg element name
|
||||
* @param integer $x The x attr defines the left position of the element
|
||||
* (e.g. x="0" places the element 0 pixels from the left of the browser window)
|
||||
* @param integer $y The y attribute defines the top position of the element
|
||||
* (e.g. y="0" places the element 0 pixels from the top of the browser window)
|
||||
* @param integer $width The width attribute defines the width the element
|
||||
* @param integer $height The height attribute defines the height the element
|
||||
* @param string $text The text attribute defines the text the element
|
||||
* @param string $styles The style attribute defines the style the element
|
||||
* styles can be defined like CSS styles
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*
|
||||
* @see XMLWriter::startElement(), XMLWriter::writeAttribute(),
|
||||
* XMLWriter::text(), XMLWriter::endElement()
|
||||
*/
|
||||
function printElement($name, $x, $y, $width = '', $height = '', $text = '', $styles = '')
|
||||
{
|
||||
$this->startElement($name);
|
||||
$this->writeAttribute('width', $width);
|
||||
$this->writeAttribute('height', $height);
|
||||
$this->writeAttribute('x', $x);
|
||||
$this->writeAttribute('y', $y);
|
||||
$this->writeAttribute('style', $styles);
|
||||
if (isset($text)) {
|
||||
$this->writeAttribute('font-family', $this->font);
|
||||
$this->writeAttribute('font-size', $this->fontSize);
|
||||
$this->text($text);
|
||||
}
|
||||
$this->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws Svg Line element
|
||||
*
|
||||
* Svg line element is drawn for connecting the tables.
|
||||
* arrows are also drawn by specify its start and ending
|
||||
* co-ordinates
|
||||
*
|
||||
* @param string $name Svg element name i.e line
|
||||
* @param integer $x1 Defines the start of the line on the x-axis
|
||||
* @param integer $y1 Defines the start of the line on the y-axis
|
||||
* @param integer $x2 Defines the end of the line on the x-axis
|
||||
* @param integer $y2 Defines the end of the line on the y-axis
|
||||
* @param string $styles The style attribute defines the style the element
|
||||
* styles can be defined like CSS styles
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*
|
||||
* @see XMLWriter::startElement(), XMLWriter::writeAttribute(),
|
||||
* XMLWriter::endElement()
|
||||
*/
|
||||
function printElementLine($name,$x1,$y1,$x2,$y2,$styles)
|
||||
{
|
||||
$this->startElement($name);
|
||||
$this->writeAttribute('x1', $x1);
|
||||
$this->writeAttribute('y1', $y1);
|
||||
$this->writeAttribute('x2', $x2);
|
||||
$this->writeAttribute('y2', $y2);
|
||||
$this->writeAttribute('style', $styles);
|
||||
$this->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* get width of string/text
|
||||
*
|
||||
* Svg text element width is calcualted depending on font name
|
||||
* and font size. It is very important to know the width of text
|
||||
* because rectangle is drawn around it.
|
||||
*
|
||||
* This is a bit hardcore method. I didn't found any other than this.
|
||||
*
|
||||
* @param string $text string that width will be calculated
|
||||
* @param integer $font name of the font like Arial,sans-serif etc
|
||||
* @param integer $fontSize size of font
|
||||
*
|
||||
* @return integer width of the text
|
||||
* @access public
|
||||
*/
|
||||
function getStringWidth($text,$font,$fontSize)
|
||||
{
|
||||
/*
|
||||
* Start by counting the width, giving each character a modifying value
|
||||
*/
|
||||
$count = 0;
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("i", "j", "l"), "", $text))) * 0.23);//ijl
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("f"), "", $text))) * 0.27);//f
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("t", "I"), "", $text))) * 0.28);//tI
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("r"), "", $text))) * 0.34);//r
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("1"), "", $text))) * 0.49);//1
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("c", "k", "s", "v", "x", "y", "z", "J"), "", $text))) * 0.5);//cksvxyzJ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("a", "b", "d", "e", "g", "h", "n", "o", "p", "q", "u", "L", "0", "2", "3", "4", "5", "6", "7", "8", "9"), "", $text))) * 0.56);//abdeghnopquL023456789
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("F", "T", "Z"), "", $text))) * 0.61);//FTZ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("A", "B", "E", "K", "P", "S", "V", "X", "Y"), "", $text))) * 0.67);//ABEKPSVXY
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("w", "C", "D", "H", "N", "R", "U"), "", $text))) * 0.73);//wCDHNRU
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("G", "O", "Q"), "", $text))) * 0.78);//GOQ
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(array("m", "M"), "", $text))) * 0.84);//mM
|
||||
$count = $count + ((strlen($text) - strlen(str_replace("W", "", $text))) * .95);//W
|
||||
$count = $count + ((strlen($text) - strlen(str_replace(" ", "", $text))) * .28);//" "
|
||||
$text = str_replace(" ", "", $text);//remove the " "'s
|
||||
$count = $count + (strlen(preg_replace("/[a-z0-9]/i", "", $text)) * 0.3); //all other chrs
|
||||
|
||||
$modifier = 1;
|
||||
$font = strtolower($font);
|
||||
switch($font){
|
||||
/*
|
||||
* no modifier for arial and sans-serif
|
||||
*/
|
||||
case 'arial':
|
||||
case 'sans-serif':
|
||||
break;
|
||||
/*
|
||||
* .92 modifer for time, serif, brushscriptstd, and californian fb
|
||||
*/
|
||||
case 'times':
|
||||
case 'serif':
|
||||
case 'brushscriptstd':
|
||||
case 'californian fb':
|
||||
$modifier = .92;
|
||||
break;
|
||||
/*
|
||||
* 1.23 modifier for broadway
|
||||
*/
|
||||
case 'broadway':
|
||||
$modifier = 1.23;
|
||||
break;
|
||||
}
|
||||
$textWidth = $count*$fontSize;
|
||||
return ceil($textWidth*$modifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Table preferences/statistics
|
||||
*
|
||||
* This class preserves the table co-ordinates,fields
|
||||
* and helps in drawing/generating the Tables in SVG XML document.
|
||||
*
|
||||
* @name Table_Stats
|
||||
* @see PMA_SVG
|
||||
*/
|
||||
class Table_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
|
||||
private $_tableName;
|
||||
private $_showInfo = false;
|
||||
|
||||
public $width = 0;
|
||||
public $height;
|
||||
public $fields = array();
|
||||
public $heightCell = 0;
|
||||
public $currentCell = 0;
|
||||
public $x, $y;
|
||||
public $primary = array();
|
||||
|
||||
/**
|
||||
* The "Table_Stats" constructor
|
||||
*
|
||||
* @param string $tableName The table name
|
||||
* @param string $font Font face
|
||||
* @param integer $fontSize The font size
|
||||
* @param integer $pageNumber Page number
|
||||
* @param integer &$same_wide_width The max. with among tables
|
||||
* @param boolean $showKeys Whether to display keys or not
|
||||
* @param boolean $showInfo Whether to display table position or not
|
||||
*
|
||||
* @global object The current SVG image document
|
||||
* @global integer The current page number (from the
|
||||
* $cfg['Servers'][$i]['table_coords'] table)
|
||||
* @global array The relations settings
|
||||
* @global string The current db name
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @see PMA_SVG, Table_Stats::Table_Stats_setWidth,
|
||||
* Table_Stats::Table_Stats_setHeight
|
||||
*/
|
||||
function __construct($tableName, $font, $fontSize, $pageNumber,
|
||||
&$same_wide_width, $showKeys = false, $showInfo = false)
|
||||
{
|
||||
global $svg, $cfgRelation, $db;
|
||||
|
||||
$this->_tableName = $tableName;
|
||||
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
|
||||
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
|
||||
if (! $result || ! PMA_DBI_num_rows($result)) {
|
||||
$svg->dieSchema(
|
||||
$pageNumber,
|
||||
"SVG",
|
||||
sprintf(__('The %s table doesn\'t exist!'), $tableName)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* load fields
|
||||
* check to see if it will load all fields or only the foreign keys
|
||||
*/
|
||||
|
||||
if ($showKeys) {
|
||||
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
|
||||
$all_columns = array();
|
||||
foreach ($indexes as $index) {
|
||||
$all_columns = array_merge(
|
||||
$all_columns,
|
||||
array_flip(array_keys($index->getColumns()))
|
||||
);
|
||||
}
|
||||
$this->fields = array_keys($all_columns);
|
||||
} else {
|
||||
while ($row = PMA_DBI_fetch_row($result)) {
|
||||
$this->fields[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_showInfo = $showInfo;
|
||||
|
||||
// height and width
|
||||
$this->_setHeightTable($fontSize);
|
||||
|
||||
// setWidth must me after setHeight, because title
|
||||
// can include table height which changes table width
|
||||
$this->_setWidthTable($font, $fontSize);
|
||||
if ($same_wide_width < $this->width) {
|
||||
$same_wide_width = $this->width;
|
||||
}
|
||||
|
||||
// x and y
|
||||
$sql = 'SELECT x, y FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($tableName) . '\''
|
||||
. ' AND pdf_page_number = ' . $pageNumber;
|
||||
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
|
||||
|
||||
if (!$result || !PMA_DBI_num_rows($result)) {
|
||||
$svg->dieSchema(
|
||||
$pageNumber,
|
||||
"SVG",
|
||||
sprintf(
|
||||
__('Please configure the coordinates for table %s'),
|
||||
$tableName
|
||||
)
|
||||
);
|
||||
}
|
||||
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
|
||||
$this->x = (double) $this->x;
|
||||
$this->y = (double) $this->y;
|
||||
// displayfield
|
||||
$this->displayfield = PMA_getDisplayField($db, $tableName);
|
||||
// index
|
||||
$result = PMA_DBI_query(
|
||||
'SHOW INDEX FROM ' . PMA_backquote($tableName) . ';',
|
||||
null,
|
||||
PMA_DBI_QUERY_STORE
|
||||
);
|
||||
if (PMA_DBI_num_rows($result) > 0) {
|
||||
while ($row = PMA_DBI_fetch_assoc($result)) {
|
||||
if ($row['Key_name'] == 'PRIMARY') {
|
||||
$this->primary[] = $row['Column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns title of the current table,
|
||||
* title can have the dimensions/co-ordinates of the table
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _getTitle()
|
||||
{
|
||||
return ($this->_showInfo
|
||||
? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell)
|
||||
: ''
|
||||
) . ' ' . $this->_tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the table
|
||||
*
|
||||
* @param string $font The font size
|
||||
* @param integer $fontSize The font size
|
||||
*
|
||||
* @global object The current SVG image document
|
||||
*
|
||||
* @return nothing
|
||||
* @access private
|
||||
*
|
||||
* @see PMA_SVG
|
||||
*/
|
||||
private function _setWidthTable($font,$fontSize)
|
||||
{
|
||||
global $svg;
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
$this->width = max(
|
||||
$this->width,
|
||||
$svg->getStringWidth($field, $font, $fontSize)
|
||||
);
|
||||
}
|
||||
$this->width += $svg->getStringWidth(' ', $font, $fontSize);
|
||||
|
||||
/*
|
||||
* it is unknown what value must be added, because
|
||||
* table title is affected by the tabe width value
|
||||
*/
|
||||
while ($this->width < $svg->getStringWidth($this->_getTitle(), $font, $fontSize)) {
|
||||
$this->width += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the height of the table
|
||||
*
|
||||
* @param integer $fontSize font size
|
||||
*
|
||||
* @return nothing
|
||||
* @access private
|
||||
*/
|
||||
function _setHeightTable($fontSize)
|
||||
{
|
||||
$this->heightCell = $fontSize + 4;
|
||||
$this->height = (count($this->fields) + 1) * $this->heightCell;
|
||||
}
|
||||
|
||||
/**
|
||||
* draw the table
|
||||
*
|
||||
* @param boolean $showColor Whether to display color
|
||||
*
|
||||
* @global object The current SVG image document
|
||||
*
|
||||
* @access public
|
||||
* @return nothing
|
||||
*
|
||||
* @see PMA_SVG,PMA_SVG::printElement
|
||||
*/
|
||||
public function tableDraw($showColor)
|
||||
{
|
||||
global $svg;
|
||||
//echo $this->_tableName.'<br />';
|
||||
$svg->printElement(
|
||||
'rect', $this->x, $this->y, $this->width,
|
||||
$this->heightCell, null, 'fill:red;stroke:black;'
|
||||
);
|
||||
$svg->printElement(
|
||||
'text', $this->x + 5, $this->y+ 14, $this->width, $this->heightCell,
|
||||
$this->_getTitle(), 'fill:none;stroke:black;'
|
||||
);
|
||||
foreach ($this->fields as $field) {
|
||||
$this->currentCell += $this->heightCell;
|
||||
$showColor = 'none';
|
||||
if ($showColor) {
|
||||
if (in_array($field, $this->primary)) {
|
||||
$showColor = '#0c0';
|
||||
}
|
||||
if ($field == $this->displayfield) {
|
||||
$showColor = 'none';
|
||||
}
|
||||
}
|
||||
$svg->printElement(
|
||||
'rect', $this->x, $this->y + $this->currentCell, $this->width,
|
||||
$this->heightCell, null, 'fill:'.$showColor.';stroke:black;'
|
||||
);
|
||||
$svg->printElement(
|
||||
'text', $this->x + 5, $this->y + 14 + $this->currentCell,
|
||||
$this->width, $this->heightCell, $field, 'fill:none;stroke:black;'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Relation preferences/statistics
|
||||
*
|
||||
* This class fetches the table master and foreign fields positions
|
||||
* and helps in generating the Table references and then connects
|
||||
* master table's master field to foreign table's foreign key
|
||||
* in SVG XML document.
|
||||
*
|
||||
* @name Relation_Stats
|
||||
* @see PMA_SVG::printElementLine
|
||||
*/
|
||||
class Relation_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
public $xSrc, $ySrc;
|
||||
public $srcDir ;
|
||||
public $destDir;
|
||||
public $xDest, $yDest;
|
||||
public $wTick = 10;
|
||||
|
||||
/**
|
||||
* The "Relation_Stats" constructor
|
||||
*
|
||||
* @param string $master_table The master table name
|
||||
* @param string $master_field The relation field in the master table
|
||||
* @param string $foreign_table The foreign table name
|
||||
* @param string $foreign_field The relation field in the foreign table
|
||||
*
|
||||
* @return nothing
|
||||
*
|
||||
* @see Relation_Stats::_getXy
|
||||
*/
|
||||
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
|
||||
{
|
||||
$src_pos = $this->_getXy($master_table, $master_field);
|
||||
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
|
||||
/*
|
||||
* [0] is x-left
|
||||
* [1] is x-right
|
||||
* [2] is y
|
||||
*/
|
||||
$src_left = $src_pos[0] - $this->wTick;
|
||||
$src_right = $src_pos[1] + $this->wTick;
|
||||
$dest_left = $dest_pos[0] - $this->wTick;
|
||||
$dest_right = $dest_pos[1] + $this->wTick;
|
||||
|
||||
$d1 = abs($src_left - $dest_left);
|
||||
$d2 = abs($src_right - $dest_left);
|
||||
$d3 = abs($src_left - $dest_right);
|
||||
$d4 = abs($src_right - $dest_right);
|
||||
$d = min($d1, $d2, $d3, $d4);
|
||||
|
||||
if ($d == $d1) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d2) {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d3) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
} else {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
}
|
||||
$this->ySrc = $src_pos[2];
|
||||
$this->yDest = $dest_pos[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets arrows coordinates
|
||||
*
|
||||
* @param string $table The current table name
|
||||
* @param string $column The relation column name
|
||||
*
|
||||
* @return array Arrows coordinates
|
||||
* @access private
|
||||
*/
|
||||
function _getXy($table, $column)
|
||||
{
|
||||
$pos = array_search($column, $table->fields);
|
||||
// x_left, x_right, y
|
||||
return array(
|
||||
$table->x,
|
||||
$table->x + $table->width,
|
||||
$table->y + ($pos + 1.5) * $table->heightCell
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* draws relation links and arrows shows foreign key relations
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @global object The current SVG image document
|
||||
*
|
||||
* @return nothing
|
||||
* @access public
|
||||
*
|
||||
* @see PMA_SVG
|
||||
*/
|
||||
public function relationDraw($changeColor)
|
||||
{
|
||||
global $svg;
|
||||
|
||||
if ($changeColor) {
|
||||
$listOfColors = array(
|
||||
'red',
|
||||
'grey',
|
||||
'black',
|
||||
'yellow',
|
||||
'green',
|
||||
'cyan',
|
||||
' orange'
|
||||
);
|
||||
shuffle($listOfColors);
|
||||
$color = $listOfColors[0];
|
||||
} else {
|
||||
$color = 'black';
|
||||
}
|
||||
|
||||
$svg->printElementLine(
|
||||
'line', $this->xSrc, $this->ySrc,
|
||||
$this->xSrc + $this->srcDir * $this->wTick, $this->ySrc,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xDest + $this->destDir * $this->wTick,
|
||||
$this->yDest, $this->xDest, $this->yDest,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xSrc + $this->srcDir * $this->wTick, $this->ySrc,
|
||||
$this->xDest + $this->destDir * $this->wTick, $this->yDest,
|
||||
'fill:' . $color . ';stroke:' . $color . ';stroke-width:1;'
|
||||
);
|
||||
$root2 = 2 * sqrt(2);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
|
||||
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
|
||||
$this->ySrc + $this->wTick / $root2,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
|
||||
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick,
|
||||
$this->ySrc - $this->wTick / $root2,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xDest + $this->destDir * $this->wTick / 2, $this->yDest,
|
||||
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
|
||||
$this->yDest + $this->wTick / $root2,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
$svg->printElementLine(
|
||||
'line', $this->xDest + $this->destDir * $this->wTick / 2, $this->yDest,
|
||||
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
|
||||
$this->yDest - $this->wTick / $root2,
|
||||
'fill:' . $color . ';stroke:black;stroke-width:2;'
|
||||
);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* end of the "Relation_Stats" class
|
||||
*/
|
||||
|
||||
/**
|
||||
* Svg Relation Schema Class
|
||||
*
|
||||
* Purpose of this class is to generate the SVG XML Document because
|
||||
* SVG defines the graphics in XML format which is used for representing
|
||||
* the database diagrams as vector image. This class actually helps
|
||||
* in preparing SVG XML format.
|
||||
*
|
||||
* SVG XML is generated by using XMLWriter php extension and this class
|
||||
* inherits Export_Relation_Schema class has common functionality added
|
||||
* to this class
|
||||
*
|
||||
* @name Svg_Relation_Schema
|
||||
*/
|
||||
class PMA_Svg_Relation_Schema extends PMA_Export_Relation_Schema
|
||||
{
|
||||
|
||||
private $tables = array();
|
||||
private $_relations = array();
|
||||
private $_xMax = 0;
|
||||
private $_yMax = 0;
|
||||
private $scale;
|
||||
private $_xMin = 100000;
|
||||
private $_yMin = 100000;
|
||||
private $t_marg = 10;
|
||||
private $b_marg = 10;
|
||||
private $l_marg = 10;
|
||||
private $r_marg = 10;
|
||||
private $_tablewidth;
|
||||
|
||||
/**
|
||||
* The "PMA_Svg_Relation_Schema" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the SVG XML document
|
||||
* user will be prompted for download as .svg extension
|
||||
*
|
||||
* @return void
|
||||
* @see PMA_SVG
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $svg,$db;
|
||||
|
||||
$this->setPageNumber($_POST['pdf_page_number']);
|
||||
$this->setShowColor(isset($_POST['show_color']));
|
||||
$this->setShowKeys(isset($_POST['show_keys']));
|
||||
$this->setTableDimension(isset($_POST['show_table_dimension']));
|
||||
$this->setAllTableSameWidth(isset($_POST['all_table_same_wide']));
|
||||
$this->setExportType($_POST['export_type']);
|
||||
|
||||
$svg = new PMA_SVG();
|
||||
$svg->setTitle(
|
||||
sprintf(
|
||||
__('Schema of the %s database - Page %s'),
|
||||
$db,
|
||||
$this->pageNumber
|
||||
)
|
||||
);
|
||||
$svg->SetAuthor('phpMyAdmin ' . PMA_VERSION);
|
||||
$svg->setFont('Arial');
|
||||
$svg->setFontSize('16px');
|
||||
$svg->startSvgDoc('1000px', '1000px');
|
||||
$alltables = $this->getAllTables($db, $this->pageNumber);
|
||||
|
||||
foreach ($alltables AS $table) {
|
||||
if (! isset($this->tables[$table])) {
|
||||
$this->tables[$table] = new Table_Stats(
|
||||
$table, $svg->getFont(), $svg->getFontSize(), $this->pageNumber,
|
||||
$this->_tablewidth, $this->showKeys, $this->tableDimension
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->sameWide) {
|
||||
$this->tables[$table]->width = $this->_tablewidth;
|
||||
}
|
||||
$this->_setMinMax($this->tables[$table]);
|
||||
}
|
||||
$seen_a_relation = false;
|
||||
foreach ($alltables as $one_table) {
|
||||
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
|
||||
if ($exist_rel) {
|
||||
$seen_a_relation = true;
|
||||
foreach ($exist_rel as $master_field => $rel) {
|
||||
/* put the foreign table on the schema only if selected
|
||||
* by the user
|
||||
* (do not use array_search() because we would have to
|
||||
* to do a === false and this is not PHP3 compatible)
|
||||
*/
|
||||
if (in_array($rel['foreign_table'], $alltables)) {
|
||||
$this->_addRelation(
|
||||
$one_table, $svg->getFont(), $svg->getFontSize(),
|
||||
$master_field, $rel['foreign_table'],
|
||||
$rel['foreign_field'], $this->tableDimension
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($seen_a_relation) {
|
||||
$this->_drawRelations($this->showColor);
|
||||
}
|
||||
|
||||
$this->_drawTables($this->showColor);
|
||||
$svg->endSvgDoc();
|
||||
$svg->showOutput($db.'-'.$this->pageNumber);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets X and Y minimum and maximum for a table cell
|
||||
*
|
||||
* @param string $table The table name
|
||||
*
|
||||
* @return nothing
|
||||
* @access private
|
||||
*/
|
||||
private function _setMinMax($table)
|
||||
{
|
||||
$this->_xMax = max($this->_xMax, $table->x + $table->width);
|
||||
$this->_yMax = max($this->_yMax, $table->y + $table->height);
|
||||
$this->_xMin = min($this->_xMin, $table->x);
|
||||
$this->_yMin = min($this->_yMin, $table->y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines relation objects
|
||||
*
|
||||
* @param string $masterTable The master table name
|
||||
* @param string $font The font face
|
||||
* @param int $fontSize Font size
|
||||
* @param string $masterField The relation field in the master table
|
||||
* @param string $foreignTable The foreign table name
|
||||
* @param string $foreignField The relation field in the foreign table
|
||||
* @param boolean $showInfo Whether to display table position or not
|
||||
*
|
||||
* @access private
|
||||
* @return nothing
|
||||
*
|
||||
* @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
|
||||
*/
|
||||
private function _addRelation($masterTable,$font,$fontSize, $masterField,
|
||||
$foreignTable, $foreignField, $showInfo)
|
||||
{
|
||||
if (! isset($this->tables[$masterTable])) {
|
||||
$this->tables[$masterTable] = new Table_Stats(
|
||||
$masterTable, $font, $fontSize, $this->pageNumber,
|
||||
$this->_tablewidth, false, $showInfo
|
||||
);
|
||||
$this->_setMinMax($this->tables[$masterTable]);
|
||||
}
|
||||
if (! isset($this->tables[$foreignTable])) {
|
||||
$this->tables[$foreignTable] = new Table_Stats(
|
||||
$foreignTable, $font, $fontSize, $this->pageNumber,
|
||||
$this->_tablewidth, false, $showInfo
|
||||
);
|
||||
$this->_setMinMax($this->tables[$foreignTable]);
|
||||
}
|
||||
$this->_relations[] = new Relation_Stats(
|
||||
$this->tables[$masterTable], $masterField,
|
||||
$this->tables[$foreignTable], $foreignField
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation arrows and lines
|
||||
* connects master table's master field to
|
||||
* foreign table's forein field
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @return nothing
|
||||
* @access private
|
||||
*
|
||||
* @see Relation_Stats::relationDraw()
|
||||
*/
|
||||
private function _drawRelations($changeColor)
|
||||
{
|
||||
foreach ($this->_relations as $relation) {
|
||||
$relation->relationDraw($changeColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws tables
|
||||
*
|
||||
* @param boolean $changeColor Whether to show color for primary fields or not
|
||||
*
|
||||
* @return nothing
|
||||
* @access private
|
||||
*
|
||||
* @see Table_Stats::Table_Stats_tableDraw()
|
||||
*/
|
||||
private function _drawTables($changeColor)
|
||||
{
|
||||
foreach ($this->tables as $table) {
|
||||
$table->tableDraw($changeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
888
html/phpmyad/libraries/schema/User_Schema.class.php
Normal file
888
html/phpmyad/libraries/schema/User_Schema.class.php
Normal file
@ -0,0 +1,888 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/**
|
||||
* This Class interacts with the user to gather the information
|
||||
* about their tables for which they want to export the relational schema
|
||||
* export options are shown to user from they can choose
|
||||
*/
|
||||
|
||||
class PMA_User_Schema
|
||||
{
|
||||
|
||||
public $chosenPage;
|
||||
public $autoLayoutForeign;
|
||||
public $autoLayoutInternal;
|
||||
public $pageNumber;
|
||||
public $c_table_rows;
|
||||
public $action;
|
||||
|
||||
public function setAction($value)
|
||||
{
|
||||
$this->action = $value;
|
||||
}
|
||||
/**
|
||||
* This function will process the user defined pages
|
||||
* and tables which will be exported as Relational schema
|
||||
* you can set the table positions on the paper via scratchboard
|
||||
* for table positions, put the x,y co-ordinates
|
||||
*
|
||||
* $this->action tells what the Schema is supposed to do
|
||||
* create and select a page, generate schema etc
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function processUserChoice()
|
||||
{
|
||||
global $action_choose, $db, $cfgRelation;
|
||||
|
||||
if (isset($this->action)) {
|
||||
switch ($this->action) {
|
||||
case 'selectpage':
|
||||
$this->chosenPage = $_REQUEST['chpage'];
|
||||
if ($action_choose=="1") {
|
||||
$this->deleteCoordinates(
|
||||
$db,
|
||||
$cfgRelation,
|
||||
$this->chosenPage
|
||||
);
|
||||
$this->deletePages(
|
||||
$db,
|
||||
$cfgRelation,
|
||||
$this->chosenPage
|
||||
);
|
||||
$this->chosenPage = 0;
|
||||
}
|
||||
break;
|
||||
case 'createpage':
|
||||
$this->pageNumber = PMA_REL_create_page(
|
||||
$_POST['newpage'],
|
||||
$cfgRelation,
|
||||
$db
|
||||
);
|
||||
$this->autoLayoutForeign = isset($_POST['auto_layout_foreign'])
|
||||
? "1"
|
||||
: null;
|
||||
$this->autoLayoutInternal = isset($_POST['auto_layout_internal'])
|
||||
? "1"
|
||||
: null;
|
||||
$this->processRelations(
|
||||
$db,
|
||||
$this->pageNumber,
|
||||
$cfgRelation
|
||||
);
|
||||
break;
|
||||
case 'edcoord':
|
||||
$this->chosenPage = $_POST['chpage'];
|
||||
$this->c_table_rows = $_POST['c_table_rows'];
|
||||
$this->_editCoordinates($db, $cfgRelation);
|
||||
break;
|
||||
case 'delete_old_references':
|
||||
$this->_deleteTableRows(
|
||||
$_POST['delrow'],
|
||||
$cfgRelation,
|
||||
$db,
|
||||
$_POST['chpage']
|
||||
);
|
||||
break;
|
||||
case 'process_export':
|
||||
$this->_processExportSchema();
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
} // end if (isset($do))
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* shows/displays the HTML FORM to create the page
|
||||
*
|
||||
* @param string $db name of the selected database
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function showCreatePageDialog($db)
|
||||
{
|
||||
?>
|
||||
<form method="post" action="schema_edit.php" name="frm_create_page">
|
||||
<fieldset>
|
||||
<legend>
|
||||
<?php echo __('Create a page') . "\n"; ?>
|
||||
</legend>
|
||||
<?php echo PMA_generate_common_hidden_inputs($db); ?>
|
||||
<input type="hidden" name="do" value="createpage" />
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="id_newpage"><?php echo __('Page name'); ?></label></td>
|
||||
<td><input type="text" name="newpage" id="id_newpage" size="20" maxlength="50" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo __('Automatic layout based on'); ?></td>
|
||||
<td>
|
||||
<input type="checkbox" name="auto_layout_internal" id="id_auto_layout_internal" /><label for="id_auto_layout_internal">
|
||||
<?php echo __('Internal relations'); ?></label><br />
|
||||
<?php
|
||||
/*
|
||||
* Check to see whether INNODB and PBXT storage engines are Available in MYSQL PACKAGE
|
||||
* If available, then provide AutoLayout for Foreign Keys in Schema View
|
||||
*/
|
||||
|
||||
if (PMA_StorageEngine::isValid('InnoDB') || PMA_StorageEngine::isValid('PBXT')) {
|
||||
?>
|
||||
<input type="checkbox" name="auto_layout_foreign" id="id_auto_layout_foreign" /><label for="id_auto_layout_foreign">
|
||||
<?php echo __('FOREIGN KEY'); ?></label><br />
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td></tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<fieldset class="tblFooters">
|
||||
<input type="submit" value="<?php echo __('Go'); ?>" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* shows/displays the created page names in a drop down list
|
||||
* User can select any page number and edit it using dashboard etc
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function selectPage()
|
||||
{
|
||||
global $db,$table,$cfgRelation;
|
||||
$page_query = 'SELECT * FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['pdf_pages'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\'';
|
||||
$page_rs = PMA_query_as_controluser($page_query, false, PMA_DBI_QUERY_STORE);
|
||||
if ($page_rs && PMA_DBI_num_rows($page_rs) > 0) {
|
||||
?>
|
||||
<form method="get" action="schema_edit.php" name="frm_select_page">
|
||||
<fieldset>
|
||||
<legend>
|
||||
<?php echo __('Please choose a page to edit') . "\n"; ?>
|
||||
</legend>
|
||||
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
|
||||
<input type="hidden" name="do" value="selectpage" />
|
||||
<select name="chpage" id="chpage" class="autosubmit">
|
||||
<option value="0"><?php echo __('Select page'); ?></option>
|
||||
<?php
|
||||
while ($curr_page = PMA_DBI_fetch_assoc($page_rs)) {
|
||||
echo "\n" . ' '
|
||||
. '<option value="' . $curr_page['page_nr'] . '"';
|
||||
if (isset($this->chosenPage)
|
||||
&& $this->chosenPage == $curr_page['page_nr']
|
||||
) {
|
||||
echo ' selected="selected"';
|
||||
}
|
||||
echo '>' . $curr_page['page_nr'] . ': '
|
||||
. htmlspecialchars($curr_page['page_descr']) . '</option>';
|
||||
} // end while
|
||||
echo "\n";
|
||||
?>
|
||||
</select>
|
||||
<?php
|
||||
$choices = array(
|
||||
'0' => __('Edit'),
|
||||
'1' => __('Delete')
|
||||
);
|
||||
PMA_display_html_radio('action_choose', $choices, '0', false);
|
||||
unset($choices);
|
||||
?>
|
||||
</fieldset>
|
||||
<fieldset class="tblFooters">
|
||||
<input type="submit" value="<?php echo __('Go'); ?>" /><br />
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php
|
||||
} // end IF
|
||||
echo "\n";
|
||||
} // end function
|
||||
|
||||
/**
|
||||
* A dashboard is displayed to AutoLayout the position of tables
|
||||
* users can drag n drop the tables and change their positions
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function showTableDashBoard()
|
||||
{
|
||||
global $db, $cfgRelation, $table, $with_field_names;
|
||||
/*
|
||||
* We will need an array of all tables in this db
|
||||
*/
|
||||
$selectboxall = array('--');
|
||||
$alltab_rs = PMA_DBI_query(
|
||||
'SHOW TABLES FROM ' . PMA_backquote($db) . ';',
|
||||
null,
|
||||
PMA_DBI_QUERY_STORE
|
||||
);
|
||||
while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
|
||||
$selectboxall[] = $val[0];
|
||||
}
|
||||
|
||||
$tabExist = array();
|
||||
|
||||
/*
|
||||
* Now if we already have chosen a page number then we should
|
||||
* show the tables involved
|
||||
*/
|
||||
if (isset($this->chosenPage) && $this->chosenPage > 0) {
|
||||
echo "\n";
|
||||
?>
|
||||
<h2><?php echo __('Select Tables'); ?></h2>
|
||||
<?php
|
||||
$page_query = 'SELECT * FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db'])
|
||||
. '.' . PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($this->chosenPage) . '\'';
|
||||
$page_rs = PMA_query_as_controluser($page_query, false);
|
||||
$array_sh_page = array();
|
||||
while ($temp_sh_page = @PMA_DBI_fetch_assoc($page_rs)) {
|
||||
$array_sh_page[] = $temp_sh_page;
|
||||
}
|
||||
/*
|
||||
* Display WYSIWYG parts
|
||||
*/
|
||||
|
||||
if (! isset($_POST['with_field_names']) && ! isset($_POST['showwysiwyg'])) {
|
||||
$with_field_names = true;
|
||||
}
|
||||
$this->_displayScratchboardTables($array_sh_page);
|
||||
?>
|
||||
|
||||
<form method="post" action="schema_edit.php" name="edcoord">
|
||||
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
|
||||
<input type="hidden" name="chpage" value="<?php echo htmlspecialchars($this->chosenPage); ?>" />
|
||||
<input type="hidden" name="do" value="edcoord" />
|
||||
<table border="0">
|
||||
<tr>
|
||||
<th><?php echo __('Table'); ?></th>
|
||||
<th><?php echo __('Delete'); ?></th>
|
||||
<th>X</th>
|
||||
<th>Y</th>
|
||||
</tr>
|
||||
<?php
|
||||
if (isset($ctable)) {
|
||||
unset($ctable);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$odd_row = true;
|
||||
foreach ($array_sh_page as $dummy_sh_page => $sh_page) {
|
||||
$_mtab = $sh_page['table_name'];
|
||||
$tabExist[$_mtab] = false;
|
||||
echo "\n" . ' <tr class="noclick ';
|
||||
if ($odd_row) {
|
||||
echo 'odd';
|
||||
} else {
|
||||
echo 'even';
|
||||
}
|
||||
echo '">';
|
||||
$odd_row != $odd_row;
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <select name="c_table_' . $i . '[name]">';
|
||||
foreach ($selectboxall as $key => $value) {
|
||||
echo "\n" . ' <option value="' . htmlspecialchars($value) . '"';
|
||||
if ($value == $sh_page['table_name']) {
|
||||
echo ' selected="selected"';
|
||||
$tabExist[$_mtab] = true;
|
||||
}
|
||||
echo '>' . htmlspecialchars($value) . '</option>';
|
||||
}
|
||||
echo "\n" . ' </select>'
|
||||
. "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="checkbox" id="id_c_table_' . $i .'" name="c_table_' . $i . '[delete]" value="y" /><label for="id_c_table_' . $i .'">' . __('Delete') . '</label>';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="text" onchange="dragPlace(' . $i . ', \'x\', this.value)" name="c_table_' . $i . '[x]" value="' . $sh_page['x'] . '" />';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="text" onchange="dragPlace(' . $i . ', \'y\', this.value)" name="c_table_' . $i . '[y]" value="' . $sh_page['y'] . '" />';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' </tr>';
|
||||
$i++;
|
||||
}
|
||||
/*
|
||||
* Add one more empty row
|
||||
*/
|
||||
echo "\n" . ' <tr class="noclick ';
|
||||
if ($odd_row) {
|
||||
echo 'odd';
|
||||
} else {
|
||||
echo 'even';
|
||||
}
|
||||
$odd_row != $odd_row;
|
||||
echo '">';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <select name="c_table_' . $i . '[name]">';
|
||||
foreach ($selectboxall as $key => $value) {
|
||||
echo "\n" . ' <option value="' . htmlspecialchars($value) . '">' . htmlspecialchars($value) . '</option>';
|
||||
}
|
||||
echo "\n" . ' </select>'
|
||||
. "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="checkbox" id="id_c_table_' . $i .'" name="c_table_' . $i . '[delete]" value="y" /><label for="id_c_table_' . $i .'">' . __('Delete') . '</label>';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="text" name="c_table_' . $i . '[x]" value="' . (isset($sh_page['x'])?$sh_page['x']:'') . '" />';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' <td>'
|
||||
. "\n" . ' <input type="text" name="c_table_' . $i . '[y]" value="' . (isset($sh_page['y'])?$sh_page['y']:'') . '" />';
|
||||
echo "\n" . ' </td>';
|
||||
echo "\n" . ' </tr>';
|
||||
echo "\n" . ' </table>' . "\n";
|
||||
|
||||
echo "\n" . ' <input type="hidden" name="c_table_rows" value="' . ($i + 1) . '" />';
|
||||
echo "\n" . ' <input type="hidden" id="showwysiwyg" name="showwysiwyg" value="' . ((isset($showwysiwyg) && $showwysiwyg == '1') ? '1' : '0') . '" />';
|
||||
echo "\n" . ' <input type="checkbox" name="with_field_names" ' . (isset($with_field_names) ? 'checked="checked"' : ''). ' />' . __('Column names') . '<br />';
|
||||
echo "\n" . ' <input type="submit" value="' . __('Save') . '" />';
|
||||
echo "\n" . '</form>' . "\n\n";
|
||||
} // end if
|
||||
|
||||
if (isset($tabExist)) {
|
||||
$this->_deleteTables($db, $this->chosenPage, $tabExist);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* show Export relational schema generation options
|
||||
* user can select export type of his own choice
|
||||
* and the attributes related to it
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
|
||||
public function displaySchemaGenerationOptions()
|
||||
{
|
||||
global $cfg,$pmaThemeImage,$db,$test_rs,$chpage;
|
||||
?>
|
||||
<form method="post" action="schema_export.php">
|
||||
<fieldset>
|
||||
<legend>
|
||||
<?php
|
||||
echo PMA_generate_common_hidden_inputs($db);
|
||||
if ($cfg['PropertiesIconic']) {
|
||||
echo PMA_getImage('b_views.png');
|
||||
}
|
||||
echo __('Display relational schema');
|
||||
?>:
|
||||
</legend>
|
||||
<select name="export_type" id="export_type">
|
||||
<option value="pdf" selected="selected">PDF</option>
|
||||
<option value="svg">SVG</option>
|
||||
<option value="dia">DIA</option>
|
||||
<option value="visio">Visio</option>
|
||||
<option value="eps">EPS</option>
|
||||
</select>
|
||||
<label><?php echo __('Select Export Relational Type');?></label><br />
|
||||
<?php
|
||||
if (isset($test_rs)) {
|
||||
?>
|
||||
<label for="pdf_page_number_opt"><?php echo __('Page number:'); ?></label>
|
||||
<select name="pdf_page_number" id="pdf_page_number_opt">
|
||||
<?php
|
||||
while ($pages = @PMA_DBI_fetch_assoc($test_rs)) {
|
||||
echo ' <option value="' . $pages['page_nr'] . '">'
|
||||
. $pages['page_nr'] . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
|
||||
} // end while
|
||||
PMA_DBI_free_result($test_rs);
|
||||
unset($test_rs);
|
||||
?>
|
||||
</select><br />
|
||||
<?php } else { ?>
|
||||
<input type="hidden" name="pdf_page_number" value="<?php echo htmlspecialchars($this->chosenPage); ?>" />
|
||||
<?php } ?>
|
||||
<input type="hidden" name="do" value="process_export" />
|
||||
<input type="hidden" name="chpage" value="<?php echo $chpage; ?>" />
|
||||
<input type="checkbox" name="show_grid" id="show_grid_opt" />
|
||||
<label for="show_grid_opt"><?php echo __('Show grid'); ?></label><br />
|
||||
<input type="checkbox" name="show_color" id="show_color_opt" checked="checked" />
|
||||
<label for="show_color_opt"><?php echo __('Show color'); ?></label><br />
|
||||
<input type="checkbox" name="show_table_dimension" id="show_table_dim_opt" />
|
||||
<label for="show_table_dim_opt"><?php echo __('Show dimension of tables'); ?>
|
||||
</label><br />
|
||||
<input type="checkbox" name="all_table_same_wide" id="all_table_same_wide" />
|
||||
<label for="all_table_same_wide"><?php echo __('Display all tables with the same width'); ?>
|
||||
</label><br />
|
||||
<input type="checkbox" name="with_doc" id="with_doc" checked="checked" />
|
||||
<label for="with_doc"><?php echo __('Data Dictionary'); ?></label><br />
|
||||
<input type="checkbox" name="show_keys" id="show_keys" />
|
||||
<label for="show_keys"><?php echo __('Only show keys'); ?></label><br />
|
||||
<select name="orientation" id="orientation_opt" onchange="refreshDragOption('pdflayout');" >
|
||||
<option value="L"><?php echo __('Landscape');?></option>
|
||||
<option value="P"><?php echo __('Portrait');?></option>
|
||||
</select>
|
||||
<label for="orientation_opt"><?php echo __('Orientation'); ?></label>
|
||||
<br />
|
||||
<select name="paper" id="paper_opt" onchange="refreshDragOption('pdflayout');">
|
||||
<?php
|
||||
foreach ($cfg['PDFPageSizes'] as $key => $val) {
|
||||
echo '<option value="' . $val . '"';
|
||||
if ($val == $cfg['PDFDefaultPageSize']) {
|
||||
echo ' selected="selected"';
|
||||
}
|
||||
echo ' >' . $val . '</option>' . "\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<label for="paper_opt"><?php echo __('Paper size'); ?></label>
|
||||
</fieldset>
|
||||
<fieldset class="tblFooters">
|
||||
<input type="submit" value="<?php echo __('Go'); ?>" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are tables that need to be deleted in dashboard,
|
||||
* if there are, ask the user for allowance
|
||||
*
|
||||
* @param string $db name of database selected
|
||||
* @param integer $chpage selected page
|
||||
* @param array $tabExist
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _deleteTables($db, $chpage, $tabExist)
|
||||
{
|
||||
global $table;
|
||||
$_strtrans = '';
|
||||
$_strname = '';
|
||||
$shoot = false;
|
||||
if (! empty($tabExist) && is_array($tabExist)) {
|
||||
foreach ($tabExist as $key => $value) {
|
||||
if (! $value) {
|
||||
$_strtrans .= '<input type="hidden" name="delrow[]" value="' . htmlspecialchars($key) . '" />' . "\n";
|
||||
$_strname .= '<li>' . htmlspecialchars($key) . '</li>' . "\n";
|
||||
$shoot = true;
|
||||
}
|
||||
}
|
||||
if ($shoot) {
|
||||
echo '<form action="schema_edit.php" method="post">' . "\n"
|
||||
. PMA_generate_common_hidden_inputs($db)
|
||||
. '<input type="hidden" name="do" value="delete_old_references" />' . "\n"
|
||||
. '<input type="hidden" name="chpage" value="' . htmlspecialchars($chpage) . '" />' . "\n"
|
||||
. __('The current page has references to tables that no longer exist. Would you like to delete those references?')
|
||||
. '<ul>' . "\n"
|
||||
. $_strname
|
||||
. '</ul>' . "\n"
|
||||
. $_strtrans
|
||||
. '<input type="submit" value="' . __('Go') . '" />' . "\n"
|
||||
. '</form>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are tables that need to be deleted in dashboard,
|
||||
* if there are, ask the user for allowance
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _displayScratchboardTables($array_sh_page)
|
||||
{
|
||||
global $with_field_names, $db;
|
||||
?>
|
||||
<script type="text/javascript" src="./js/dom-drag.js"></script>
|
||||
<form method="post" action="schema_edit.php" name="dragdrop">
|
||||
<input type="button" name="dragdrop" value="<?php echo __('Toggle scratchboard'); ?>" onclick="ToggleDragDrop('pdflayout');" />
|
||||
<input type="button" name="dragdropreset" value="<?php echo __('Reset'); ?>" onclick="resetDrag();" />
|
||||
</form>
|
||||
<div id="pdflayout" class="pdflayout" style="visibility: hidden;">
|
||||
<?php
|
||||
$draginit = '';
|
||||
$draginit2 = '';
|
||||
$reset_draginit = '';
|
||||
$i = 0;
|
||||
foreach ($array_sh_page as $key => $temp_sh_page) {
|
||||
$drag_x = $temp_sh_page['x'];
|
||||
$drag_y = $temp_sh_page['y'];
|
||||
|
||||
$draginit2 .= ' Drag.init($("#table_' . $i . '")[0], null, 0, parseInt(myid.style.width)-2, 0, parseInt(myid.style.height)-5);' . "\n";
|
||||
$draginit2 .= ' $("#table_' . $i . '")[0].onDrag = function (x, y) { document.edcoord.elements["c_table_' . $i . '[x]"].value = parseInt(x); document.edcoord.elements["c_table_' . $i . '[y]"].value = parseInt(y) }' . "\n";
|
||||
$draginit .= ' $("#table_' . $i . '")[0].style.left = "' . $drag_x . 'px";' . "\n";
|
||||
$draginit .= ' $("#table_' . $i . '")[0].style.top = "' . $drag_y . 'px";' . "\n";
|
||||
$reset_draginit .= ' $("#table_' . $i . '")[0].style.left = "2px";' . "\n";
|
||||
$reset_draginit .= ' $("#table_' . $i . '")[0].style.top = "' . (15 * $i) . 'px";' . "\n";
|
||||
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[x]"].value = "2"' . "\n";
|
||||
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[y]"].value = "' . (15 * $i) . '"' . "\n";
|
||||
|
||||
echo '<div id="table_' . $i . '" class="pdflayout_table"><u>' . $temp_sh_page['table_name'] . '</u>';
|
||||
if (isset($with_field_names)) {
|
||||
$fields = PMA_DBI_get_columns($db, $temp_sh_page['table_name']);
|
||||
// if the table has been dropped from outside phpMyAdmin,
|
||||
// we can no longer obtain its columns list
|
||||
if ($fields) {
|
||||
foreach ($fields as $row) {
|
||||
echo '<br />' . htmlspecialchars($row['Field']) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '</div>' . "\n";
|
||||
$i++;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function PDFinit() {
|
||||
refreshLayout();
|
||||
myid = $('#pdflayout')[0];
|
||||
<?php echo $draginit; ?>
|
||||
TableDragInit();
|
||||
}
|
||||
|
||||
function TableDragInit() {
|
||||
myid = $('#pdflayout')[0];
|
||||
<?php echo $draginit2; ?>
|
||||
}
|
||||
|
||||
function resetDrag() {
|
||||
<?php echo $reset_draginit; ?>
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* delete the table rows with table co-ordinates
|
||||
*
|
||||
* @param int $delrow delete selected table from list of tables
|
||||
* @param array $cfgRelation relation settings
|
||||
* @param string $db database name
|
||||
* @param integer $chpage selected page for adding relations etc
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _deleteTableRows($delrow,$cfgRelation,$db,$chpage)
|
||||
{
|
||||
foreach ($delrow as $current_row) {
|
||||
$del_query = 'DELETE FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords']) . ' ' . "\n"
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\'' . "\n"
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($current_row) . '\'' . "\n"
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($chpage) . '\'';
|
||||
echo $del_query;
|
||||
PMA_query_as_controluser($del_query, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get all the export options and verify
|
||||
* call and include the appropriate Schema Class depending on $export_type
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _processExportSchema()
|
||||
{
|
||||
/**
|
||||
* Settings for relation stuff
|
||||
*/
|
||||
include_once './libraries/transformations.lib.php';
|
||||
include_once './libraries/Index.class.php';
|
||||
/**
|
||||
* default is PDF, otherwise validate it's only letters a-z
|
||||
*/
|
||||
global $db,$export_type;
|
||||
if (!isset($export_type) || !preg_match('/^[a-zA-Z]+$/', $export_type)) {
|
||||
$export_type = 'pdf';
|
||||
}
|
||||
|
||||
PMA_DBI_select_db($db);
|
||||
|
||||
include "./libraries/schema/" . ucfirst($export_type) . "_Relation_Schema.class.php";
|
||||
$obj_schema = eval("new PMA_" . ucfirst($export_type) . "_Relation_Schema();");
|
||||
}
|
||||
|
||||
/**
|
||||
* delete X and Y coordinates
|
||||
*
|
||||
* @param string $db The database name
|
||||
* @param array $cfgRelation relation settings
|
||||
* @param integer $choosePage selected page for adding relations etc
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
public function deleteCoordinates($db, $cfgRelation, $choosePage)
|
||||
{
|
||||
$query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($choosePage) . '\'';
|
||||
PMA_query_as_controluser($query, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete pages
|
||||
*
|
||||
* @param string $db The database name
|
||||
* @param array $cfgRelation relation settings
|
||||
* @param integer $choosePage selected page for adding relations etc
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
public function deletePages($db, $cfgRelation, $choosePage)
|
||||
{
|
||||
$query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['pdf_pages'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND page_nr = \'' . PMA_sqlAddSlashes($choosePage) . '\'';
|
||||
PMA_query_as_controluser($query, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* process internal and foreign key relations
|
||||
*
|
||||
* @param string $db The database name
|
||||
* @param integer $pageNumber document number/Id
|
||||
* @param array $cfgRelation relation settings
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
public function processRelations($db, $pageNumber, $cfgRelation)
|
||||
{
|
||||
/*
|
||||
* A u t o m a t i c l a y o u t
|
||||
*
|
||||
* There are 2 kinds of relations in PMA
|
||||
* 1) Internal Relations 2) Foreign Key Relations
|
||||
*/
|
||||
if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
|
||||
$all_tables = array();
|
||||
}
|
||||
|
||||
if (isset($this->autoLayoutForeign)) {
|
||||
/*
|
||||
* get the tables list
|
||||
* who support FOREIGN KEY, it's not
|
||||
* important that we group together InnoDB tables
|
||||
* and PBXT tables, as this logic is just to put
|
||||
* the tables on the layout, not to determine relations
|
||||
*/
|
||||
$tables = PMA_DBI_get_tables_full($db);
|
||||
$foreignkey_tables = array();
|
||||
foreach ($tables as $table_name => $table_properties) {
|
||||
if (PMA_foreignkey_supported($table_properties['ENGINE'])) {
|
||||
$foreignkey_tables[] = $table_name;
|
||||
}
|
||||
}
|
||||
$all_tables = $foreignkey_tables;
|
||||
/*
|
||||
* could be improved by finding the tables which have the
|
||||
* most references keys and placing them at the beginning
|
||||
* of the array (so that they are all center of schema)
|
||||
*/
|
||||
unset($tables, $foreignkey_tables);
|
||||
}
|
||||
|
||||
if (isset($this->autoLayoutInternal)) {
|
||||
/*
|
||||
* get the tables list who support Internal Relations;
|
||||
* This type of relations will be created when
|
||||
* you setup the PMA tables correctly
|
||||
*/
|
||||
$master_tables = 'SELECT COUNT(master_table), master_table'
|
||||
. ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['relation'])
|
||||
. ' WHERE master_db = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' GROUP BY master_table'
|
||||
. ' ORDER BY COUNT(master_table) DESC';
|
||||
$master_tables_rs = PMA_query_as_controluser(
|
||||
$master_tables, false, PMA_DBI_QUERY_STORE
|
||||
);
|
||||
if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) {
|
||||
/* first put all the master tables at beginning
|
||||
* of the list, so they are near the center of
|
||||
* the schema
|
||||
*/
|
||||
while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) {
|
||||
$all_tables[] = $master_table;
|
||||
}
|
||||
|
||||
/* Now for each master, add its foreigns into an array
|
||||
* of foreign tables, if not already there
|
||||
* (a foreign might be foreign for more than
|
||||
* one table, and might be a master itself)
|
||||
*/
|
||||
|
||||
$foreign_tables = array();
|
||||
foreach ($all_tables as $master_table) {
|
||||
$foreigners = PMA_getForeigners($db, $master_table);
|
||||
foreach ($foreigners as $foreigner) {
|
||||
if (! in_array($foreigner['foreign_table'], $foreign_tables)) {
|
||||
$foreign_tables[] = $foreigner['foreign_table'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now merge the master and foreign arrays/tables
|
||||
*/
|
||||
foreach ($foreign_tables as $foreign_table) {
|
||||
if (! in_array($foreign_table, $all_tables)) {
|
||||
$all_tables[] = $foreign_table;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
|
||||
$this->addRelationCoordinates(
|
||||
$all_tables, $pageNumber, $db, $cfgRelation
|
||||
);
|
||||
}
|
||||
|
||||
$this->chosenPage = $pageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add X and Y coordinates for a table
|
||||
*
|
||||
* @param array $all_tables A list of all tables involved
|
||||
* @param integer $pageNumber document number/Id
|
||||
* @param string $db The database name
|
||||
* @param array $cfgRelation relation settings
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
public function addRelationCoordinates($all_tables, $pageNumber, $db, $cfgRelation)
|
||||
{
|
||||
/*
|
||||
* Now generate the coordinates for the schema
|
||||
* in a clockwise spiral and add to co-ordinates table
|
||||
*/
|
||||
$pos_x = 300;
|
||||
$pos_y = 300;
|
||||
$delta = 110;
|
||||
$delta_mult = 1.10;
|
||||
$direction = "right";
|
||||
foreach ($all_tables as $current_table) {
|
||||
/*
|
||||
* save current table's coordinates
|
||||
*/
|
||||
$insert_query = 'INSERT INTO '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords']) . ' '
|
||||
. '(db_name, table_name, pdf_page_number, x, y) '
|
||||
. 'VALUES (\'' . PMA_sqlAddSlashes($db) . '\', \''
|
||||
. PMA_sqlAddSlashes($current_table) . '\',' . $pageNumber
|
||||
. ',' . $pos_x . ',' . $pos_y . ')';
|
||||
PMA_query_as_controluser($insert_query, false);
|
||||
|
||||
/*
|
||||
* compute for the next table
|
||||
*/
|
||||
switch ($direction) {
|
||||
case 'right':
|
||||
$pos_x += $delta;
|
||||
$direction = "down";
|
||||
$delta *= $delta_mult;
|
||||
break;
|
||||
case 'down':
|
||||
$pos_y += $delta;
|
||||
$direction = "left";
|
||||
$delta *= $delta_mult;
|
||||
break;
|
||||
case 'left':
|
||||
$pos_x -= $delta;
|
||||
$direction = "up";
|
||||
$delta *= $delta_mult;
|
||||
break;
|
||||
case 'up':
|
||||
$pos_y -= $delta;
|
||||
$direction = "right";
|
||||
$delta *= $delta_mult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update X and Y coordinates for a table
|
||||
*
|
||||
* @param string $db The database name
|
||||
* @param array $cfgRelation relation settings
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private function _editCoordinates($db, $cfgRelation)
|
||||
{
|
||||
for ($i = 0; $i < $this->c_table_rows; $i++) {
|
||||
$arrvalue = 'c_table_' . $i;
|
||||
global $$arrvalue;
|
||||
$arrvalue = $$arrvalue;
|
||||
if (! isset($arrvalue['x']) || $arrvalue['x'] == '') {
|
||||
$arrvalue['x'] = 0;
|
||||
}
|
||||
if (! isset($arrvalue['y']) || $arrvalue['y'] == '') {
|
||||
$arrvalue['y'] = 0;
|
||||
}
|
||||
if (isset($arrvalue['name']) && $arrvalue['name'] != '--') {
|
||||
$test_query = 'SELECT * FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($arrvalue['name']) . '\''
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($this->chosenPage) . '\'';
|
||||
$test_rs = PMA_query_as_controluser($test_query, false, PMA_DBI_QUERY_STORE);
|
||||
//echo $test_query;
|
||||
if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
|
||||
if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') {
|
||||
$ch_query = 'DELETE FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($arrvalue['name']) . '\''
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($this->chosenPage) . '\'';
|
||||
} else {
|
||||
$ch_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db'])
|
||||
. '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
|
||||
. 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y']
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($arrvalue['name']) . '\''
|
||||
. ' AND pdf_page_number = \'' . PMA_sqlAddSlashes($this->chosenPage) . '\'';
|
||||
}
|
||||
} else {
|
||||
$ch_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db'])
|
||||
. '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
|
||||
. '(db_name, table_name, pdf_page_number, x, y) '
|
||||
. 'VALUES (\'' . PMA_sqlAddSlashes($db) . '\', \''
|
||||
. PMA_sqlAddSlashes($arrvalue['name']) . '\', \''
|
||||
. PMA_sqlAddSlashes($this->chosenPage) . '\','
|
||||
. $arrvalue['x'] . ',' . $arrvalue['y'] . ')';
|
||||
}
|
||||
//echo $ch_query;
|
||||
PMA_query_as_controluser($ch_query, false);
|
||||
} // end if
|
||||
} // end for
|
||||
}
|
||||
}
|
||||
?>
|
645
html/phpmyad/libraries/schema/Visio_Relation_Schema.class.php
Normal file
645
html/phpmyad/libraries/schema/Visio_Relation_Schema.class.php
Normal file
@ -0,0 +1,645 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
require_once 'Export_Relation_Schema.class.php';
|
||||
|
||||
/**
|
||||
* This Class inherits the XMLwriter class and
|
||||
* helps in developing structure of MS Visio Schema Export
|
||||
*
|
||||
* @access public
|
||||
* @see http://php.net/manual/en/book.xmlwriter.php
|
||||
*/
|
||||
class PMA_VISIO extends XMLWriter
|
||||
{
|
||||
public $title;
|
||||
public $author;
|
||||
public $font;
|
||||
public $fontSize;
|
||||
|
||||
/**
|
||||
* The "PMA_VISIO" constructor
|
||||
*
|
||||
* Upon instantiation This starts writing the Visio XML .VDX document
|
||||
*
|
||||
* @return void
|
||||
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$this->openMemory();
|
||||
/*
|
||||
* Set indenting using three spaces,
|
||||
* so output is formatted
|
||||
*/
|
||||
|
||||
$this->setIndent(true);
|
||||
$this->setIndentString(' ');
|
||||
/*
|
||||
* Create the XML document
|
||||
*/
|
||||
|
||||
$this->startDocument('1.0', 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts Visio XML .VDX Document
|
||||
*
|
||||
* Visio XML document starts by first initializing VisioDocument tag
|
||||
* then DocumentProperties & DocumentSettings contains all the
|
||||
* attributes that needed to define the document. Order of elements
|
||||
* should be maintained while generating XML of Visio.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::startElement(), XMLWriter::writeAttribute(),
|
||||
* _documentProperties, _documentSettings
|
||||
*/
|
||||
function startVisioDoc()
|
||||
{
|
||||
$this->startElement('VisioDocument');
|
||||
$this->writeAttribute('xmlns', 'http://schemas.microsoft.com/visio/2003/core');
|
||||
$this->writeAttribute('xmlns:vx', 'http://schemas.microsoft.com/visio/2006/extension');
|
||||
$this->writeAttribute('xml:space', 'preserve');
|
||||
$this->_documentProperties();
|
||||
$this->_documentSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document title
|
||||
*
|
||||
* @param string $value title text
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setTitle($value)
|
||||
{
|
||||
$this->title = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set document author
|
||||
*
|
||||
* @param string $value the author
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function setAuthor($value)
|
||||
{
|
||||
$this->author = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Visio XML .VDX Document Properties
|
||||
*
|
||||
* DocumentProperties tag contains document property elements such as
|
||||
the document's Title,Subject,Creator and templates tags
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see XMLWriter::startElement(),XMLWriter::endElement(),XMLWriter::writeRaw()
|
||||
*/
|
||||
private function _documentProperties()
|
||||
{
|
||||
$this->startElement('DocumentProperties');
|
||||
$this->writeRaw('<Title>'.$this->title.'</Title>');
|
||||
$this->writeRaw('<Subject>'.$this->title.'</Subject>');
|
||||
$this->writeRaw('<Creator>'.$this->author.'</Creator>');
|
||||
$this->writeRaw('<Company>phpMyAdmin</Company>');
|
||||
$this->writeRaw('<Template>c:\program files\microsoft office\office12\1033\DBMODL_U.VST</Template>');
|
||||
$this->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Visio XML .VDX Document Settings
|
||||
*
|
||||
* DocumentSettings tag contains elements that specify document settings.
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see XMLWriter::startElement(),XMLWriter::endElement()
|
||||
*/
|
||||
private function _documentSettings()
|
||||
{
|
||||
$this->startElement('DocumentSettings');
|
||||
$this->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends Visio XML Document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::endElement(),XMLWriter::endDocument()
|
||||
*/
|
||||
function endVisioDoc()
|
||||
{
|
||||
$this->endElement();
|
||||
$this->endDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Visio XML .VDX Document for download
|
||||
*
|
||||
* @param string $fileName name of the Visio XML document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see XMLWriter::flush()
|
||||
*/
|
||||
function showOutput($fileName)
|
||||
{
|
||||
//if(ob_get_clean()){
|
||||
//ob_end_clean();
|
||||
//}
|
||||
$output = $this->flush();
|
||||
PMA_download_header($fileName . '.vdx', 'application/visio', strlen($output));
|
||||
print $output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draws tables schema
|
||||
*/
|
||||
class Table_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
|
||||
private $_tableName;
|
||||
private $_showInfo = false;
|
||||
|
||||
public $width = 0;
|
||||
public $height;
|
||||
public $fields = array();
|
||||
public $heightCell = 0;
|
||||
public $currentCell = 0;
|
||||
public $x, $y;
|
||||
public $primary = array();
|
||||
|
||||
/**
|
||||
* The "Table_Stats" constructor
|
||||
*
|
||||
* @param string $tableName The table name
|
||||
* @param integer $pageNumber Page number
|
||||
* @param integer &$same_wide_width The max. with among tables
|
||||
* @param boolean $showKeys Whether to display keys or not
|
||||
* @param boolean $showInfo Whether to display table position or not
|
||||
*
|
||||
* @global object The current Visio XML document
|
||||
* @global integer The current page number (from the
|
||||
* $cfg['Servers'][$i]['table_coords'] table)
|
||||
* @global array The relations settings
|
||||
* @global string The current db name
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see PMA_VISIO, Table_Stats::Table_Stats_setWidth,
|
||||
* Table_Stats::Table_Stats_setHeight
|
||||
*/
|
||||
function __construct($tableName, $pageNumber, &$same_wide_width, $showKeys = false, $showInfo = false)
|
||||
{
|
||||
global $visio, $cfgRelation, $db;
|
||||
|
||||
$this->_tableName = $tableName;
|
||||
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
|
||||
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
|
||||
if (!$result || !PMA_DBI_num_rows($result)) {
|
||||
$visio->dieSchema(
|
||||
$pageNumber,
|
||||
"VISIO",
|
||||
sprintf(__('The %s table doesn\'t exist!'), $tableName)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* load fields
|
||||
* check to see if it will load all fields or only the foreign keys
|
||||
*/
|
||||
|
||||
if ($showKeys) {
|
||||
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
|
||||
$all_columns = array();
|
||||
foreach ($indexes as $index) {
|
||||
$all_columns = array_merge(
|
||||
$all_columns,
|
||||
array_flip(array_keys($index->getColumns()))
|
||||
);
|
||||
}
|
||||
$this->fields = array_keys($all_columns);
|
||||
} else {
|
||||
while ($row = PMA_DBI_fetch_row($result)) {
|
||||
$this->fields[] = $row[0];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_showInfo = $showInfo;
|
||||
|
||||
// height and width
|
||||
$this->_setHeightTable($fontSize);
|
||||
|
||||
// setWidth must me after setHeight, because title
|
||||
// can include table height which changes table width
|
||||
$this->_setWidthTable($font, $fontSize);
|
||||
if ($same_wide_width < $this->width) {
|
||||
$same_wide_width = $this->width;
|
||||
}
|
||||
|
||||
// x and y
|
||||
$sql = 'SELECT x, y FROM '
|
||||
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.'
|
||||
. PMA_backquote($cfgRelation['table_coords'])
|
||||
. ' WHERE db_name = \'' . PMA_sqlAddSlashes($db) . '\''
|
||||
. ' AND table_name = \'' . PMA_sqlAddSlashes($tableName) . '\''
|
||||
. ' AND pdf_page_number = ' . $pageNumber;
|
||||
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
|
||||
|
||||
if (!$result || !PMA_DBI_num_rows($result)) {
|
||||
$visio->dieSchema(
|
||||
$pageNumber,
|
||||
"VISIO",
|
||||
sprintf(
|
||||
__('Please configure the coordinates for table %s'),
|
||||
$tableName
|
||||
)
|
||||
);
|
||||
}
|
||||
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
|
||||
$this->x = (double) $this->x;
|
||||
$this->y = (double) $this->y;
|
||||
// displayfield
|
||||
$this->displayfield = PMA_getDisplayField($db, $tableName);
|
||||
// index
|
||||
$result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE);
|
||||
if (PMA_DBI_num_rows($result) > 0) {
|
||||
while ($row = PMA_DBI_fetch_assoc($result)) {
|
||||
if ($row['Key_name'] == 'PRIMARY') {
|
||||
$this->primary[] = $row['Column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns title of the current table,
|
||||
* title can have the dimensions/co-ordinates of the table
|
||||
*
|
||||
* @return the title
|
||||
* @access private
|
||||
*/
|
||||
private function _getTitle()
|
||||
{
|
||||
return ($this->_showInfo
|
||||
? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell)
|
||||
: '') . ' ' . $this->_tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the table
|
||||
*
|
||||
* @param string $font font name
|
||||
* @param integer $fontSize font size
|
||||
*
|
||||
* @global object The current Visio XML document
|
||||
*
|
||||
* @return void
|
||||
* @see PMA_VISIO
|
||||
*/
|
||||
private function _setWidthTable($font,$fontSize)
|
||||
{
|
||||
global $visio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the height of the table
|
||||
*
|
||||
* @param integer $fontSize font size
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _setHeightTable($fontSize)
|
||||
{
|
||||
$this->heightCell = $fontSize + 4;
|
||||
$this->height = (count($this->fields) + 1) * $this->heightCell;
|
||||
}
|
||||
|
||||
/**
|
||||
* draw the table
|
||||
*
|
||||
* @param boolean $showColor Whether to display color
|
||||
*
|
||||
* @global object The current Visio XML document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see PMA_VISIO
|
||||
*/
|
||||
public function tableDraw($showColor)
|
||||
{
|
||||
global $visio;
|
||||
//echo $this->_tableName.'<br />';
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
$this->currentCell += $this->heightCell;
|
||||
$showColor = 'none';
|
||||
if ($showColor) {
|
||||
if (in_array($field, $this->primary)) {
|
||||
$showColor = '#0c0';
|
||||
}
|
||||
if ($field == $this->displayfield) {
|
||||
$showColor = 'none';
|
||||
}
|
||||
}
|
||||
// code here for drawing table diagrams
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation links
|
||||
*
|
||||
* @access public
|
||||
* @see PMA_VISIO
|
||||
*/
|
||||
class Relation_Stats
|
||||
{
|
||||
/**
|
||||
* Defines properties
|
||||
*/
|
||||
public $xSrc, $ySrc;
|
||||
public $srcDir ;
|
||||
public $destDir;
|
||||
public $xDest, $yDest;
|
||||
public $wTick = 10;
|
||||
|
||||
/**
|
||||
* The "Relation_Stats" constructor
|
||||
*
|
||||
* @param string $master_table The master table name
|
||||
* @param string $master_field The relation field in the master table
|
||||
* @param string $foreign_table The foreign table name
|
||||
* @param string $foreign_field The relation field in the foreign table
|
||||
*
|
||||
* @return void
|
||||
* @see Relation_Stats::_getXy
|
||||
*/
|
||||
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
|
||||
{
|
||||
$src_pos = $this->_getXy($master_table, $master_field);
|
||||
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
|
||||
/*
|
||||
* [0] is x-left
|
||||
* [1] is x-right
|
||||
* [2] is y
|
||||
*/
|
||||
$src_left = $src_pos[0] - $this->wTick;
|
||||
$src_right = $src_pos[1] + $this->wTick;
|
||||
$dest_left = $dest_pos[0] - $this->wTick;
|
||||
$dest_right = $dest_pos[1] + $this->wTick;
|
||||
|
||||
$d1 = abs($src_left - $dest_left);
|
||||
$d2 = abs($src_right - $dest_left);
|
||||
$d3 = abs($src_left - $dest_right);
|
||||
$d4 = abs($src_right - $dest_right);
|
||||
$d = min($d1, $d2, $d3, $d4);
|
||||
|
||||
if ($d == $d1) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d2) {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[0];
|
||||
$this->destDir = -1;
|
||||
} elseif ($d == $d3) {
|
||||
$this->xSrc = $src_pos[0];
|
||||
$this->srcDir = -1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
} else {
|
||||
$this->xSrc = $src_pos[1];
|
||||
$this->srcDir = 1;
|
||||
$this->xDest = $dest_pos[1];
|
||||
$this->destDir = 1;
|
||||
}
|
||||
$this->ySrc = $src_pos[2];
|
||||
$this->yDest = $dest_pos[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets arrows coordinates
|
||||
*
|
||||
* @param string $table The current table name
|
||||
* @param string $column The relation column name
|
||||
*
|
||||
* @return array Arrows coordinates
|
||||
* @access private
|
||||
*/
|
||||
function _getXy($table, $column)
|
||||
{
|
||||
$pos = array_search($column, $table->fields);
|
||||
// x_left, x_right, y
|
||||
return array(
|
||||
$table->x,
|
||||
$table->x + $table->width,
|
||||
$table->y + ($pos + 1.5) * $table->heightCell
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* draws relation links and arrows shows foreign key relations
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @global object The current Visio XML document
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
* @see PMA_VISIO
|
||||
*/
|
||||
public function relationDraw($changeColor)
|
||||
{
|
||||
global $visio;
|
||||
|
||||
if ($changeColor) {
|
||||
$listOfColors = array(
|
||||
'red',
|
||||
'grey',
|
||||
'black',
|
||||
'yellow',
|
||||
'green',
|
||||
'cyan',
|
||||
'orange'
|
||||
);
|
||||
shuffle($listOfColors);
|
||||
$color = $listOfColors[0];
|
||||
} else {
|
||||
$color = 'black';
|
||||
}
|
||||
|
||||
// code here for making connections b/w relation objects
|
||||
}
|
||||
}
|
||||
/*
|
||||
* end of the "Relation_Stats" class
|
||||
*/
|
||||
|
||||
/**
|
||||
* Visio Relation Schema Class
|
||||
*
|
||||
* Purpose of this class is to generate the Visio XML .VDX Document which is used
|
||||
* for representing the database diagrams in any version of MS Visio IDE.
|
||||
* This class uses Software and Database Template and Database model diagram of
|
||||
* Visio and with the combination of these objects actually helps in preparing
|
||||
* Visio XML .VDX document.
|
||||
*
|
||||
* Visio XML is generated by using XMLWriter php extension and this class
|
||||
* inherits Export_Relation_Schema class has common functionality added
|
||||
* to this class
|
||||
*
|
||||
* @name Visio_Relation_Schema
|
||||
*/
|
||||
class PMA_Visio_Relation_Schema extends PMA_Export_Relation_Schema
|
||||
{
|
||||
/**
|
||||
* The "PMA_Visio_Relation_Schema" constructor
|
||||
*
|
||||
* Upon instantiation This outputs the Visio XML document
|
||||
* that user can download
|
||||
*
|
||||
* @return void
|
||||
* @see PMA_VISIO,Table_Stats,Relation_Stats
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
global $visio,$db;
|
||||
|
||||
$this->setPageNumber($_POST['pdf_page_number']);
|
||||
$this->setShowGrid(isset($_POST['show_grid']));
|
||||
$this->setShowColor($_POST['show_color']);
|
||||
$this->setShowKeys(isset($_POST['show_keys']));
|
||||
$this->setOrientation(isset($_POST['orientation']));
|
||||
$this->setPaper($_POST['paper']);
|
||||
$this->setExportType($_POST['export_type']);
|
||||
|
||||
$visio = new PMA_VISIO();
|
||||
$visio->setTitle(sprintf(__('Schema of the %s database - Page %s'), $db, $this->pageNumber));
|
||||
$visio->SetAuthor('phpMyAdmin ' . PMA_VERSION);
|
||||
$visio->startVisioDoc();
|
||||
$alltables = $this->getAllTables($db, $this->pageNumber);
|
||||
|
||||
foreach ($alltables as $table) {
|
||||
if (! isset($this->tables[$table])) {
|
||||
$this->tables[$table] = new Table_Stats($table, $this->pageNumber, $this->showKeys);
|
||||
}
|
||||
}
|
||||
|
||||
$seen_a_relation = false;
|
||||
foreach ($alltables as $one_table) {
|
||||
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
|
||||
if ($exist_rel) {
|
||||
$seen_a_relation = true;
|
||||
foreach ($exist_rel as $master_field => $rel) {
|
||||
/* put the foreign table on the schema only if selected
|
||||
* by the user
|
||||
* (do not use array_search() because we would have to
|
||||
* to do a === false and this is not PHP3 compatible)
|
||||
*/
|
||||
if (in_array($rel['foreign_table'], $alltables)) {
|
||||
$this->_addRelation(
|
||||
$one_table,
|
||||
$master_field,
|
||||
$rel['foreign_table'],
|
||||
$rel['foreign_field'],
|
||||
$this->showKeys
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_drawTables($this->showColor);
|
||||
|
||||
if ($seen_a_relation) {
|
||||
$this->_drawRelations($this->showColor);
|
||||
}
|
||||
$visio->endVisioDoc();
|
||||
$visio->showOutput($db.'-'.$this->pageNumber);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines relation objects
|
||||
*
|
||||
* @param string $masterTable The master table name
|
||||
* @param string $masterField The relation field in the master table
|
||||
* @param string $foreignTable The foreign table name
|
||||
* @param string $foreignField The relation field in the foreign table
|
||||
* @param boolean $showKeys Whether to display keys or not
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see Table_Stats::__construct(), Relation_Stats::__construct()
|
||||
*/
|
||||
private function _addRelation($masterTable, $masterField, $foreignTable, $foreignField, $showKeys)
|
||||
{
|
||||
if (! isset($this->tables[$masterTable])) {
|
||||
$this->tables[$masterTable] = new Table_Stats(
|
||||
$masterTable, $this->pageNumber, $showKeys
|
||||
);
|
||||
}
|
||||
if (! isset($this->tables[$foreignTable])) {
|
||||
$this->tables[$foreignTable] = new Table_Stats(
|
||||
$foreignTable, $this->pageNumber, $showKeys
|
||||
);
|
||||
}
|
||||
$this->_relations[] = new Relation_Stats(
|
||||
$this->tables[$masterTable], $masterField,
|
||||
$this->tables[$foreignTable], $foreignField
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws relation references
|
||||
* connects master table's master field to foreign table's forein field.
|
||||
*
|
||||
* @param boolean $changeColor Whether to use one color per relation or not
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see Relation_Stats::relationDraw()
|
||||
*/
|
||||
private function _drawRelations($changeColor)
|
||||
{
|
||||
foreach ($this->_relations as $relation) {
|
||||
$relation->relationDraw($changeColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws tables
|
||||
*
|
||||
* @param boolean $changeColor Whether to show color for tables text or not
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @see Table_Stats::tableDraw()
|
||||
*/
|
||||
private function _drawTables($changeColor)
|
||||
{
|
||||
foreach ($this->tables as $table) {
|
||||
$table->tableDraw($changeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user