DiaRelationSchema.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. /**
  3. * Classes to create relation schema in Dia format.
  4. */
  5. declare(strict_types=1);
  6. namespace PhpMyAdmin\Plugins\Schema\Dia;
  7. use PhpMyAdmin\Plugins\Schema\Eps\TableStatsEps;
  8. use PhpMyAdmin\Plugins\Schema\ExportRelationSchema;
  9. use PhpMyAdmin\Plugins\Schema\Pdf\TableStatsPdf;
  10. use PhpMyAdmin\Plugins\Schema\Svg\TableStatsSvg;
  11. use function in_array;
  12. /**
  13. * Dia Relation Schema Class
  14. *
  15. * Purpose of this class is to generate the Dia XML Document
  16. * which is used for representing the database diagrams in Dia IDE
  17. * This class uses Database Table and Reference Objects of Dia and with
  18. * the combination of these objects actually helps in preparing Dia XML.
  19. *
  20. * Dia XML is generated by using XMLWriter php extension and this class
  21. * inherits ExportRelationSchema class has common functionality added
  22. * to this class
  23. *
  24. * @name Dia_Relation_Schema
  25. */
  26. class DiaRelationSchema extends ExportRelationSchema
  27. {
  28. /** @var TableStatsDia[]|TableStatsEps[]|TableStatsPdf[]|TableStatsSvg[] */
  29. private $tables = [];
  30. /** @var RelationStatsDia[] Relations */
  31. private $relations = [];
  32. /** @var float */
  33. private $topMargin = 2.8222000598907471;
  34. /** @var float */
  35. private $bottomMargin = 2.8222000598907471;
  36. /** @var float */
  37. private $leftMargin = 2.8222000598907471;
  38. /** @var float */
  39. private $rightMargin = 2.8222000598907471;
  40. /** @var int */
  41. public static $objectId = 0;
  42. /**
  43. * Upon instantiation This outputs the Dia XML document
  44. * that user can download
  45. *
  46. * @see Dia
  47. * @see TableStatsDia
  48. * @see RelationStatsDia
  49. *
  50. * @param string $db database name
  51. */
  52. public function __construct($db)
  53. {
  54. parent::__construct($db, new Dia());
  55. $this->setShowColor(isset($_REQUEST['dia_show_color']));
  56. $this->setShowKeys(isset($_REQUEST['dia_show_keys']));
  57. $this->setOrientation((string) $_REQUEST['dia_orientation']);
  58. $this->setPaper((string) $_REQUEST['dia_paper']);
  59. $this->diagram->startDiaDoc(
  60. $this->paper,
  61. $this->topMargin,
  62. $this->bottomMargin,
  63. $this->leftMargin,
  64. $this->rightMargin,
  65. $this->orientation
  66. );
  67. $alltables = $this->getTablesFromRequest();
  68. foreach ($alltables as $table) {
  69. if (isset($this->tables[$table])) {
  70. continue;
  71. }
  72. $this->tables[$table] = new TableStatsDia(
  73. $this->diagram,
  74. $this->db,
  75. $table,
  76. $this->pageNumber,
  77. $this->showKeys,
  78. $this->offline
  79. );
  80. }
  81. $seen_a_relation = false;
  82. foreach ($alltables as $one_table) {
  83. $exist_rel = $this->relation->getForeigners($this->db, $one_table, '', 'both');
  84. if (! $exist_rel) {
  85. continue;
  86. }
  87. $seen_a_relation = true;
  88. foreach ($exist_rel as $master_field => $rel) {
  89. /* put the foreign table on the schema only if selected
  90. * by the user
  91. * (do not use array_search() because we would have to
  92. * to do a === false and this is not PHP3 compatible)
  93. */
  94. if ($master_field !== 'foreign_keys_data') {
  95. if (in_array($rel['foreign_table'], $alltables)) {
  96. $this->addRelation(
  97. $one_table,
  98. $master_field,
  99. $rel['foreign_table'],
  100. $rel['foreign_field'],
  101. $this->showKeys
  102. );
  103. }
  104. continue;
  105. }
  106. foreach ($rel as $one_key) {
  107. if (! in_array($one_key['ref_table_name'], $alltables)) {
  108. continue;
  109. }
  110. foreach ($one_key['index_list'] as $index => $one_field) {
  111. $this->addRelation(
  112. $one_table,
  113. $one_field,
  114. $one_key['ref_table_name'],
  115. $one_key['ref_index_list'][$index],
  116. $this->showKeys
  117. );
  118. }
  119. }
  120. }
  121. }
  122. $this->drawTables();
  123. if ($seen_a_relation) {
  124. $this->drawRelations();
  125. }
  126. $this->diagram->endDiaDoc();
  127. }
  128. /**
  129. * Output Dia Document for download
  130. *
  131. * @return void
  132. *
  133. * @access public
  134. */
  135. public function showOutput()
  136. {
  137. $this->diagram->showOutput($this->getFileName('.dia'));
  138. }
  139. /**
  140. * Defines relation objects
  141. *
  142. * @see TableStatsDia::__construct(),RelationStatsDia::__construct()
  143. *
  144. * @param string $masterTable The master table name
  145. * @param string $masterField The relation field in the master table
  146. * @param string $foreignTable The foreign table name
  147. * @param string $foreignField The relation field in the foreign table
  148. * @param bool $showKeys Whether to display ONLY keys or not
  149. *
  150. * @return void
  151. *
  152. * @access private
  153. */
  154. private function addRelation(
  155. $masterTable,
  156. $masterField,
  157. $foreignTable,
  158. $foreignField,
  159. $showKeys
  160. ) {
  161. if (! isset($this->tables[$masterTable])) {
  162. $this->tables[$masterTable] = new TableStatsDia(
  163. $this->diagram,
  164. $this->db,
  165. $masterTable,
  166. $this->pageNumber,
  167. $showKeys
  168. );
  169. }
  170. if (! isset($this->tables[$foreignTable])) {
  171. $this->tables[$foreignTable] = new TableStatsDia(
  172. $this->diagram,
  173. $this->db,
  174. $foreignTable,
  175. $this->pageNumber,
  176. $showKeys
  177. );
  178. }
  179. $this->relations[] = new RelationStatsDia(
  180. $this->diagram,
  181. $this->tables[$masterTable],
  182. $masterField,
  183. $this->tables[$foreignTable],
  184. $foreignField
  185. );
  186. }
  187. /**
  188. * Draws relation references
  189. *
  190. * connects master table's master field to
  191. * foreign table's foreign field using Dia object
  192. * type Database - Reference
  193. *
  194. * @see RelationStatsDia::relationDraw()
  195. *
  196. * @return void
  197. *
  198. * @access private
  199. */
  200. private function drawRelations()
  201. {
  202. foreach ($this->relations as $relation) {
  203. $relation->relationDraw($this->showColor);
  204. }
  205. }
  206. /**
  207. * Draws tables
  208. *
  209. * Tables are generated using Dia object type Database - Table
  210. * primary fields are underlined and bold in tables
  211. *
  212. * @see TableStatsDia::tableDraw()
  213. *
  214. * @return void
  215. *
  216. * @access private
  217. */
  218. private function drawTables()
  219. {
  220. foreach ($this->tables as $table) {
  221. $table->tableDraw($this->showColor);
  222. }
  223. }
  224. }