generate_entity_diagrams 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/local/bin/php
  2. <?php
  3. define('INSTALL_DIR', dirname(__DIR__));
  4. require INSTALL_DIR . '/vendor/autoload.php';
  5. use App\Util\Common;
  6. use App\Util\HTML as H;
  7. use Functional as F;
  8. $template = '
  9. graph database {
  10. %tables%
  11. %edges%
  12. }
  13. ';
  14. $files = glob(INSTALL_DIR . '/src/Entity/*.php');
  15. $tables = [];
  16. $edges = [];
  17. foreach ($files as $file) {
  18. require_once $file;
  19. $declared = get_declared_classes();
  20. $class = end($declared);
  21. $schema = $class::schemaDef();
  22. $table = $schema['name'];
  23. $fields = [['name' => $table, 'type' => '']];
  24. foreach ($schema['fields'] as $name => $opts) {
  25. $fields[] = [
  26. 'name' => $name,
  27. 'type' => ": {$opts['type']}" . ($opts['type'] == 'varchar' ? "({$opts['length']})" : ''),
  28. ];
  29. }
  30. if (isset($schema['foreign keys'])) {
  31. foreach ($schema['foreign keys'] as $name => $map) {
  32. // Patern matching like above would be nice
  33. list($foreign_table,
  34. $keys) = $map;
  35. $local_key = array_keys($keys)[0];
  36. $foreign_key = $keys[$local_key];
  37. $edges[] = "{$table}:{$local_key} -- {$foreign_table}:{$foreign_key}";
  38. }
  39. }
  40. $cell = function ($field) {
  41. $def = $field['name'] . $field['type'];
  42. return ['tr' => ['td' => ['attrs' => ['port' => $field['name']], $def]]];
  43. };
  44. $html = ['table' => array_merge(
  45. ['attrs' => ['border' => '0', 'cellborder' => '1', 'cellspacing' => '0']],
  46. F\map($fields, $cell)),
  47. ];
  48. $tables[] = Common::indent("{$table} [shape=none, label=<\n" . Common::indent(H::html($html)) . "\n>]");
  49. }
  50. $replace = [
  51. '/%tables%/' => Common::indent(implode("\n", $tables)),
  52. '/%edges%/' => Common::indent(implode("\n", $edges)),
  53. // '/_/' => '\textunderscore ',
  54. ];
  55. $out = $template;
  56. foreach ($replace as $from => $to) {
  57. $out = preg_replace($from, $to, $out);
  58. }
  59. $path = dirname(__DIR__) . '/DOCUMENTATION/database';
  60. $outfile = $path . '/database.dot';
  61. file_put_contents($outfile, $out);
  62. system("neato -Goverlap=false -Gsplines=true -Tpdf {$path}/database.dot -o {$path}/database.pdf");
  63. echo "Generated database diagram. See {$path}/database.pdf\n";