SvgRelationSchema.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Contains PhpMyAdmin\Plugins\Schema\Svg\RelationStatsSvg class
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin\Plugins\Schema\Svg;
  9. use PhpMyAdmin\Plugins\Schema\Dia\RelationStatsDia;
  10. use PhpMyAdmin\Plugins\Schema\Eps\TableStatsEps;
  11. use PhpMyAdmin\Plugins\Schema\ExportRelationSchema;
  12. use PhpMyAdmin\Plugins\Schema\Pdf\TableStatsPdf;
  13. use PhpMyAdmin\Plugins\Schema\Svg\Svg;
  14. use PhpMyAdmin\Plugins\Schema\Svg\TableStatsSvg;
  15. use PhpMyAdmin\Plugins\Schema\Dia\TableStatsDia;
  16. use PhpMyAdmin\Relation;
  17. /**
  18. * RelationStatsSvg Relation Schema Class
  19. *
  20. * Purpose of this class is to generate the SVG XML Document because
  21. * SVG defines the graphics in XML format which is used for representing
  22. * the database diagrams as vector image. This class actually helps
  23. * in preparing SVG XML format.
  24. *
  25. * SVG XML is generated by using XMLWriter php extension and this class
  26. * inherits ExportRelationSchema class has common functionality added
  27. * to this class
  28. *
  29. * @package PhpMyAdmin
  30. * @name Svg_Relation_Schema
  31. */
  32. class SvgRelationSchema extends ExportRelationSchema
  33. {
  34. /**
  35. * @var PhpMyAdmin\Plugins\Schema\Dia\TableStatsDia[]|TableStatsEps[]|TableStatsPdf[]|TableStatsSvg[]
  36. */
  37. private $_tables = array();
  38. /** @var RelationStatsDia[] Relations */
  39. private $_relations = array();
  40. private $_xMax = 0;
  41. private $_yMax = 0;
  42. private $_xMin = 100000;
  43. private $_yMin = 100000;
  44. private $_tablewidth;
  45. /**
  46. * The "PhpMyAdmin\Plugins\Schema\Svg\SvgRelationSchema" constructor
  47. *
  48. * Upon instantiation This starts writing the SVG XML document
  49. * user will be prompted for download as .svg extension
  50. *
  51. * @param string $db database name
  52. *
  53. * @see PMA_SVG
  54. */
  55. function __construct($db)
  56. {
  57. parent::__construct($db, new Svg());
  58. $this->setShowColor(isset($_REQUEST['svg_show_color']));
  59. $this->setShowKeys(isset($_REQUEST['svg_show_keys']));
  60. $this->setTableDimension(isset($_REQUEST['svg_show_table_dimension']));
  61. $this->setAllTablesSameWidth(isset($_REQUEST['svg_all_tables_same_width']));
  62. $this->diagram->setTitle(
  63. sprintf(
  64. __('Schema of the %s database - Page %s'),
  65. $this->db,
  66. $this->pageNumber
  67. )
  68. );
  69. $this->diagram->SetAuthor('phpMyAdmin ' . PMA_VERSION);
  70. $this->diagram->setFont('Arial');
  71. $this->diagram->setFontSize(16);
  72. $alltables = $this->getTablesFromRequest();
  73. foreach ($alltables as $table) {
  74. if (!isset($this->_tables[$table])) {
  75. $this->_tables[$table] = new TableStatsSvg(
  76. $this->diagram, $this->db,
  77. $table, $this->diagram->getFont(),
  78. $this->diagram->getFontSize(), $this->pageNumber,
  79. $this->_tablewidth, $this->showKeys, $this->tableDimension,
  80. $this->offline
  81. );
  82. }
  83. if ($this->sameWide) {
  84. $this->_tables[$table]->width = &$this->_tablewidth;
  85. }
  86. $this->_setMinMax($this->_tables[$table]);
  87. }
  88. $border = 15;
  89. $this->diagram->startSvgDoc(
  90. $this->_xMax + $border,
  91. $this->_yMax + $border,
  92. $this->_xMin - $border,
  93. $this->_yMin - $border
  94. );
  95. $seen_a_relation = false;
  96. foreach ($alltables as $one_table) {
  97. $exist_rel = $this->relation->getForeigners($this->db, $one_table, '', 'both');
  98. if (!$exist_rel) {
  99. continue;
  100. }
  101. $seen_a_relation = true;
  102. foreach ($exist_rel as $master_field => $rel) {
  103. /* put the foreign table on the schema only if selected
  104. * by the user
  105. * (do not use array_search() because we would have to
  106. * to do a === false and this is not PHP3 compatible)
  107. */
  108. if ($master_field != 'foreign_keys_data') {
  109. if (in_array($rel['foreign_table'], $alltables)) {
  110. $this->_addRelation(
  111. $one_table,
  112. $this->diagram->getFont(),
  113. $this->diagram->getFontSize(),
  114. $master_field,
  115. $rel['foreign_table'],
  116. $rel['foreign_field'],
  117. $this->tableDimension
  118. );
  119. }
  120. continue;
  121. }
  122. foreach ($rel as $one_key) {
  123. if (!in_array($one_key['ref_table_name'], $alltables)) {
  124. continue;
  125. }
  126. foreach (
  127. $one_key['index_list']
  128. as $index => $one_field
  129. ) {
  130. $this->_addRelation(
  131. $one_table,
  132. $this->diagram->getFont(),
  133. $this->diagram->getFontSize(),
  134. $one_field,
  135. $one_key['ref_table_name'],
  136. $one_key['ref_index_list'][$index],
  137. $this->tableDimension
  138. );
  139. }
  140. }
  141. }
  142. }
  143. if ($seen_a_relation) {
  144. $this->_drawRelations();
  145. }
  146. $this->_drawTables();
  147. $this->diagram->endSvgDoc();
  148. }
  149. /**
  150. * Output RelationStatsSvg Document for download
  151. *
  152. * @return void
  153. */
  154. public function showOutput()
  155. {
  156. $this->diagram->showOutput($this->getFileName('.svg'));
  157. }
  158. /**
  159. * Sets X and Y minimum and maximum for a table cell
  160. *
  161. * @param string $table The table name
  162. *
  163. * @return void
  164. */
  165. private function _setMinMax($table)
  166. {
  167. $this->_xMax = max($this->_xMax, $table->x + $table->width);
  168. $this->_yMax = max($this->_yMax, $table->y + $table->height);
  169. $this->_xMin = min($this->_xMin, $table->x);
  170. $this->_yMin = min($this->_yMin, $table->y);
  171. }
  172. /**
  173. * Defines relation objects
  174. *
  175. * @param string $masterTable The master table name
  176. * @param string $font The font face
  177. * @param int $fontSize Font size
  178. * @param string $masterField The relation field in the master table
  179. * @param string $foreignTable The foreign table name
  180. * @param string $foreignField The relation field in the foreign table
  181. * @param boolean $tableDimension Whether to display table position or not
  182. *
  183. * @return void
  184. *
  185. * @see _setMinMax,Table_Stats_Svg::__construct(),
  186. * PhpMyAdmin\Plugins\Schema\Svg\RelationStatsSvg::__construct()
  187. */
  188. private function _addRelation(
  189. $masterTable,
  190. $font,
  191. $fontSize,
  192. $masterField,
  193. $foreignTable,
  194. $foreignField,
  195. $tableDimension
  196. ) {
  197. if (!isset($this->_tables[$masterTable])) {
  198. $this->_tables[$masterTable] = new TableStatsSvg(
  199. $this->diagram, $this->db,
  200. $masterTable, $font, $fontSize, $this->pageNumber,
  201. $this->_tablewidth, false, $tableDimension
  202. );
  203. $this->_setMinMax($this->_tables[$masterTable]);
  204. }
  205. if (!isset($this->_tables[$foreignTable])) {
  206. $this->_tables[$foreignTable] = new TableStatsSvg(
  207. $this->diagram, $this->db,
  208. $foreignTable, $font, $fontSize, $this->pageNumber,
  209. $this->_tablewidth, false, $tableDimension
  210. );
  211. $this->_setMinMax($this->_tables[$foreignTable]);
  212. }
  213. $this->_relations[] = new RelationStatsSvg(
  214. $this->diagram,
  215. $this->_tables[$masterTable],
  216. $masterField,
  217. $this->_tables[$foreignTable],
  218. $foreignField
  219. );
  220. }
  221. /**
  222. * Draws relation arrows and lines
  223. * connects master table's master field to
  224. * foreign table's foreign field
  225. *
  226. * @return void
  227. *
  228. * @see Relation_Stats_Svg::relationDraw()
  229. */
  230. private function _drawRelations()
  231. {
  232. foreach ($this->_relations as $relation) {
  233. $relation->relationDraw($this->showColor);
  234. }
  235. }
  236. /**
  237. * Draws tables
  238. *
  239. * @return void
  240. *
  241. * @see Table_Stats_Svg::Table_Stats_tableDraw()
  242. */
  243. private function _drawTables()
  244. {
  245. foreach ($this->_tables as $table) {
  246. $table->tableDraw($this->showColor);
  247. }
  248. }
  249. }