From 083dd825da6f63c78b9ead05357a6cd181765eab Mon Sep 17 00:00:00 2001
From: Steve Wirt <swirtMiles@138230.no-reply.drupal.org>
Date: Fri, 1 Sep 2023 23:42:00 -0400
Subject: [PATCH] Issue #3360982: Diagram: Update entity reference diagram to
 use MermaidTrait

---
 src/Controller/EntityDiagramController.php   | 52 +++++++-------------
 src/Controller/WorkflowDiagramController.php |  1 -
 src/MermaidTrait.php                         | 19 +++++--
 3 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/src/Controller/EntityDiagramController.php b/src/Controller/EntityDiagramController.php
index 4f66c0f..98144f4 100644
--- a/src/Controller/EntityDiagramController.php
+++ b/src/Controller/EntityDiagramController.php
@@ -2,21 +2,23 @@
 
 namespace Drupal\content_model_documentation\Controller;
 
+use Drupal\content_model_documentation\EntityBundleId;
+use Drupal\content_model_documentation\MermaidTrait;
+use Drupal\content_model_documentation\RelatedEntities;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Url;
-use Drupal\content_model_documentation\EntityBundleId;
-use Drupal\content_model_documentation\RelatedEntities;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
  * Implements EntityDiagramController class.
  */
 class EntityDiagramController extends ControllerBase {
+use MermaidTrait;
 
   /**
    * Drupal\Core\Entity\EntityFieldManagerInterface definition.
@@ -49,7 +51,7 @@ class EntityDiagramController extends ControllerBase {
   /**
    * The request stack.
    *
-   * @var Symfony\Component\HttpFoundation\Request
+   * @var \Symfony\Component\HttpFoundation\Request
    */
   protected $request;
 
@@ -60,27 +62,6 @@ class EntityDiagramController extends ControllerBase {
    */
   protected $relatedEntities;
 
-  /**
-   * Used to construct mermaid flowchart.
-   *
-   * @see https://mermaid.js.org/syntax/flowchart.html.
-   */
-  const ENTITY_SHAPES = [
-    'rectangle' => ['[', ']'],
-    'circle' => ['((', '))'],
-    'trapezoid' => ['[/', '\]'],
-    'parallelogram' => ['[/', '/]'],
-    'hexagon' => ['{{', '}}'],
-    'flag' => ['>', ']'],
-    'rounded rectangle' => ['(', ')'],
-    'double circle' => ['(((', ')))'],
-    'parallelogram alt.' => ['[\\', '\\]'],
-    'rhombus' => ['{', '}'],
-    'trapezoid alt.' => ['[\\', '/]'],
-    'flag alt.' => ['[', ']'],
-    'rectangle subroutine' => ['[[', ']]'],
-  ];
-
   /**
    * Constructs the EntityDiagramController.
    *
@@ -218,11 +199,11 @@ class EntityDiagramController extends ControllerBase {
           $output .= $this->diagramNode($relation->getDest());
           $classed[] = $dest_node_id;
         }
-        $output .= $source_node_id . '-.->|"' . $relation->getField() . '"|' . $dest_node_id . "\n";
+        $output .= $this->makeArrow($source_node_id, $dest_node_id, $relation->getField());
       }
       // Highlight the starting bundle selected by the form.
       $start_name = (string) $start;
-      $output .= "\nstyle $start_name fill:#ffaacc,stroke:#333,stroke-width:4px;\n";
+      $output .= $this->highlightShape($start_name);
     }
     else {
       $output .= 'empty(No relations found)';
@@ -242,7 +223,8 @@ class EntityDiagramController extends ControllerBase {
     $mapping = [];
     $itemNo = 0;
     foreach (array_keys($this->relatedEntities->entityTypes()) as $entityId) {
-      $mapping[$entityId] = current(array_slice(self::ENTITY_SHAPES, $itemNo % count(self::ENTITY_SHAPES), 1, FALSE));
+      $shape_names = array_keys($this->getShapes());
+      $mapping[$entityId] = current(array_slice($shape_names, $itemNo % count($shape_names), 1, FALSE));
       $itemNo++;
     }
     return $mapping;
@@ -263,12 +245,13 @@ class EntityDiagramController extends ControllerBase {
     }
     $entityTypes = $this->entityTypeManager()->getDefinitions();
     $output = "flowchart LR\n";
-    $output .= "subgraph identifier[\" \"]\n";
     $entities = array_intersect_key($this->getMapping(), $entity_ids);
-    foreach ($entities as $entity_id => $shapeMarkup) {
-      $output .= '  ' . $entity_id . $shapeMarkup[0] . strval($entityTypes[$entity_id]->getLabel()) . $shapeMarkup[1] . "\n";
+    $subgraph_content = '';
+    foreach ($entities as $entity_id => $shape) {
+      $label = strval($entityTypes[$entity_id]->getLabel());
+      $subgraph_content .= "  {$entity_id}{$this->wrapMermaidShape($label, $shape)}\n";
     }
-    $output .= "end\n";
+    $output .= $this->wrapSubgraph('Entity types', $subgraph_content, TRUE);
     return $output;
   }
 
@@ -288,7 +271,10 @@ class EntityDiagramController extends ControllerBase {
     $info = $this->entityTypeBundleInfo->getBundleInfo($entity_id);
     $label = str_replace(['(', ')'], '', $info[$bundle_id]['label']);
     $mapping = $this->getMapping();
-    $node = (string) $entity_bundle . $mapping[$entity_id][0] . $label . '<br>' . $entity_id . $mapping[$entity_id][1] . "\n";
+    $node_content = "{$label}<br>{$entity_id}";
+    $bundle = (string) $entity_bundle;
+    $node = "  {$bundle}{$this->wrapMermaidShape($node_content, $mapping[$entity_id])}\n";
+
     // Add a link if the bundle has relationships.
     if (count($this->relatedEntities->getRelations($entity_bundle, 1)) > 1) {
       $node_label = (string) $entity_bundle;
diff --git a/src/Controller/WorkflowDiagramController.php b/src/Controller/WorkflowDiagramController.php
index 45e1583..4c5a11d 100644
--- a/src/Controller/WorkflowDiagramController.php
+++ b/src/Controller/WorkflowDiagramController.php
@@ -5,7 +5,6 @@ namespace Drupal\content_model_documentation\Controller;
 use Drupal\content_model_documentation\MermaidTrait;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\workflows\Entity\Workflow;
diff --git a/src/MermaidTrait.php b/src/MermaidTrait.php
index 2d07b14..7dd174d 100644
--- a/src/MermaidTrait.php
+++ b/src/MermaidTrait.php
@@ -18,7 +18,7 @@ trait MermaidTrait {
    * @return string
    *   Wrapped content.
    */
-  public function wrapMermaidShape($content, $shape = 'rectangle') : string {
+  public function wrapMermaidShape($content, $shape = 'rectangle'): string {
     $item = '';
     if (!empty($content)) {
       $wrapper = $this->getShape($shape);
@@ -80,7 +80,7 @@ trait MermaidTrait {
    * @return string
    *   The mermaid subgraph.
    */
-  public function wrapSubgraph($title, $content, $showtitle = TRUE):string {
+  public function wrapSubgraph($title, $content, $showtitle = TRUE): string {
     $subgraph = ($showtitle) ? "subgraph \"{$title}\"\n" : "subgraph \"{$title}\"[ ]\n";
     $subgraph .= $content;
     $subgraph .= "  end\n";
@@ -101,11 +101,24 @@ trait MermaidTrait {
    * @return string
    *   The mermaid code for an arrow connector.
    */
-  public function makeArrow(string $from_id, string $to_id, string $label = ''):string {
+  public function makeArrow(string $from_id, string $to_id, string $label = ''): string {
     if (empty($label)) {
       return "  {$from_id} --> {$to_id}\n";
     }
     return "  {$from_id} -->|\"$label\"|{$to_id}\n";
   }
 
+  /**
+   * Highlight a shape.  Use this to draw focus to a specific element.
+   *
+   * @param string $shape_id
+   *   The id of the shape element to highlight.
+   *
+   * @return string
+   *   The mermaid style to make the highlight.
+   */
+  public function highlightShape(string $shape_id): string {
+    return "style $shape_id fill:#ffaacc,stroke:#333,stroke-width:4px;\n";
+  }
+
 }
-- 
GitLab