From 8cf6548036cef8331c8c8d24563cf8070a19df90 Mon Sep 17 00:00:00 2001
From: Nidhi Patadia <nidhipatadia27@gmail.com>
Date: Tue, 4 Feb 2025 02:13:39 +0530
Subject: [PATCH 1/4] Add report for paragraphs entity types.

---
 content_model_documentation.links.menu.yml    |  10 +-
 .../ContentModelDocumentationConfigForm.php   |   2 +-
 src/Report/ParagraphCount.php                 | 232 ++++++++++++++++++
 3 files changed, 242 insertions(+), 2 deletions(-)
 create mode 100644 src/Report/ParagraphCount.php

diff --git a/content_model_documentation.links.menu.yml b/content_model_documentation.links.menu.yml
index a663eec..0bfa4eb 100644
--- a/content_model_documentation.links.menu.yml
+++ b/content_model_documentation.links.menu.yml
@@ -37,13 +37,21 @@ entity.content_model_documentation.report.node_count:
   route_parameters: { report_name: 'node-count' }
   weight: 2
 
+entity.content_model_documentation.report.paragraph_count:
+  title: 'Paragraph count'
+  description: 'Shows a summary of our paragraph types.'
+  parent: entity.content_model_documentation.base
+  route_name: entity.content_model_documentation.content_model_reports
+  route_parameters: { report_name: 'paragraph-count' }
+  weight: 3
+
 entity.content_model_documentation.report.vocabulary_count:
   title: 'Taxonomy: Vocabulary count'
   description: 'Shows a summary of our vocabulary types.'
   parent: entity.content_model_documentation.base
   route_name: entity.content_model_documentation.content_model_reports
   route_parameters: { report_name: 'vocabulary-count' }
-  weight: 3
+  weight: 4
 
 content_model_documentation.fields.search:
   title: 'Field search'
diff --git a/src/Form/ContentModelDocumentationConfigForm.php b/src/Form/ContentModelDocumentationConfigForm.php
index e6b26ea..b9ec9e0 100644
--- a/src/Form/ContentModelDocumentationConfigForm.php
+++ b/src/Form/ContentModelDocumentationConfigForm.php
@@ -73,7 +73,7 @@ class ContentModelDocumentationConfigForm extends ConfigFormBase {
     $documentable_entities['menu'] = $this->moduleHandler->moduleExists('menu_link_content');
     $documentable_entities['modules'] = TRUE;
     $documentable_entities['node'] = $this->moduleHandler->moduleExists('node');
-    $documentable_entities['paragraph'] = $this->moduleHandler->moduleExists('paragraphs');
+    $documentable_entities['paragraphs_type'] = $this->moduleHandler->moduleExists('paragraphs');
     $documentable_entities['taxonomy'] = $this->moduleHandler->moduleExists('taxonomy');
     return $documentable_entities;
   }
diff --git a/src/Report/ParagraphCount.php b/src/Report/ParagraphCount.php
new file mode 100644
index 0000000..1027c37
--- /dev/null
+++ b/src/Report/ParagraphCount.php
@@ -0,0 +1,232 @@
+<?php
+
+namespace Drupal\content_model_documentation\Report;
+
+/**
+ * A report that shows all paragraph types and their counts.
+ */
+class ParagraphCount extends ReportBase implements ReportInterface, ReportTableInterface, ReportDiagramInterface {
+
+  const ENTITY_TYPE = 'paragraphs_type';
+
+  /**
+   * The footer row.
+   *
+   * @var array
+   */
+  protected $footer = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getReportTitle(): string {
+    return 'Paragraph counts';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getReportType(): string {
+    return 'table';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription(): string {
+    $vars = ['@content_type' => self::ENTITY_TYPE];
+    if ($this->entityTypeExists(self::ENTITY_TYPE)) {
+      return $this->t("This is a snapshot of this site's @content_type types.", $vars);
+    }
+    return $this->t("The @content_type entity type does not exist on this site.", $vars);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCaption(): string {
+    return $this->t('List of paragraph types and the number of each in use.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getHeaderRow(): array {
+    $header = [
+      $this->t('Label'),
+      $this->t('Id'),
+      $this->t('Total'),
+      $this->t('Published'),
+      $this->t('Unpublished'),
+    ];
+    if ($this->config->get(self::ENTITY_TYPE)) {
+      array_push($header, $this->t('Documentation'));
+    }
+    return $header;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFooterRow(): array {
+    return $this->footer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTableBodyRows(): array {
+    $rows = $this->getData();
+    if ($this->config->get(self::ENTITY_TYPE)) {
+      $rows = $this->addDocumentationColumn(self::ENTITY_TYPE, '', $rows);
+    }
+    return $rows;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCsvBodyRows(): array {
+    // Will need to convert links to urls.
+    $rows = $this->getData();
+    if ($this->config->get(self::ENTITY_TYPE)) {
+      $rows = $this->addDocumentationColumn(self::ENTITY_TYPE, '', $rows, TRUE);
+    }
+    return $rows;
+  }
+
+  /**
+   * Gets the data for the table.
+   *
+   * @return array
+   *   The data of the rows, but not including documentation.
+   */
+  protected function getData(): array {
+    $label_content_types = $this->getContentTypeLabels();
+    $bundles_counted = $this->getBundlePublishedCount();
+    $total = 0;
+    $total_published = 0;
+
+    $resultTable = [];
+    foreach ($label_content_types as $bundle => $content_type_label) {
+      $resultTable[$bundle] = [
+        'label' => $content_type_label,
+        'id' => $bundle,
+        'total' => $bundles_counted[$bundle],
+        'publish' => $bundles_counted[$bundle],
+        'no_publish' => 0,
+      ];
+      $total += $bundles_counted[$bundle];
+      $total_published += $bundles_counted[$bundle];
+    }
+    $content_type_count = count($resultTable);
+    $footer = [];
+    $footer['label'] = (string) $this->t('TOTAL');
+    $footer['id'] = "{$content_type_count} {$this->t('Paragraph types')}";
+    $footer['total'] = "{$total} {$this->t('paragraphs')}";
+    $footer['publish'] = "{$total_published} {$this->t('paragraphs')}";
+    $footer['no-publish'] = "0";
+    $this->footer = [$footer];
+    return $resultTable;
+  }
+
+  /**
+   * Gets an array of paragraph labels.
+   *
+   * @return array
+   *   An array of paragraph content labels.
+   */
+  protected function getContentTypeLabels() {
+    $label_content_types = [];
+    // @todo There has to be a better way to get the paragraph types than
+    // looping through all the instances.
+    $types = ($this->entityTypeExists(self::ENTITY_TYPE)) ? $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple() : [];
+    foreach ($types as $key => $type) {
+      $label = $type->label();
+      $machine_name =  $type->id();
+      if (empty($label_content_types[$machine_name])) {
+        $label_content_types[$machine_name] = $label;
+      }
+    }
+    natcasesort($label_content_types);
+
+    return $label_content_types;
+  }
+
+  /**
+   * Gets the count of published nodes.
+   *
+   * @return array
+   *   The array of bundles with a published count.
+   */
+  protected function getBundlePublishedCount() {
+    if ($this->entityTypeExists(self::ENTITY_TYPE)) {
+      $paragraph_types = $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple();
+      foreach ($paragraph_types as $paragraph_type) {
+        $type_id = $paragraph_type->id();
+        // Query to count the number of paragraphs of this type.
+        $query = $this->entityTypeManager->getStorage('paragraph')->getQuery();
+        $query->condition('type', $type_id)->accessCheck(TRUE);
+        $count = $query->count()->execute();
+
+        // Store the count in the array.
+        $paragraph_type_counts[$type_id] = $count;
+      }
+    }
+    return $paragraph_type_counts;
+  }
+
+  /**
+   * Builds the Mermaid string for the diagram.
+   *
+   * @return string
+   *   The string that is the Mermaid Diagram.
+   */
+  protected function getDiagram(): string {
+    $label_content_types = $this->getContentTypeLabels();
+    if (empty($label_content_types)) {
+      // There is nothing to diagram, bail out.
+      return '';
+    }
+    // Sorting is largely irrelevant because mermaid will sort from high to low.
+    // The reason for the sort is in the case of screen readers it reads raw.
+    asort($label_content_types, SORT_NATURAL);
+    $bundles = $this->getBundlePublishedCount();
+    $bundle_count = count($bundles);
+    $vars = ['@total_count' => $bundle_count];
+
+    $title = $this->t('There are @total_count paragraph types (bundles).', $vars);
+    $mermaid = "pie showData title $title" . PHP_EOL;
+    foreach ($label_content_types as $machine_name => $label_content_type) {
+      $count = $bundles[$machine_name] ?? 0;
+      $mermaid .= "  \"$label_content_type\": {$count}" . PHP_EOL;
+    }
+
+    return $mermaid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDiagramList(): array {
+    $diagrams = [
+      'Paragraph Types' => [
+        'diagram' => $this->getDiagram(),
+        'caption' => $this->t('All paragraph bundle counts.'),
+        'key' => '',
+      ],
+    ];
+    return $diagrams;
+  }
+
+  /**
+   * Gets a render array for something to display above the table.
+   *
+   * @return array
+   *   A drupal render array for the diagram.
+   */
+  protected function getPreReport(): array {
+    return $this->buildDiagramPage(' ');
+  }
+
+}
-- 
GitLab


From c3451c5e601637f572d5f9eb484d076c8fb96f2d Mon Sep 17 00:00:00 2001
From: Nidhi Patadia <nidhipatadia27@gmail.com>
Date: Wed, 5 Feb 2025 22:39:53 +0530
Subject: [PATCH 2/4] Add report for paragraphs entity types

---
 src/Form/ContentModelDocumentationConfigForm.php |  2 +-
 src/Plugin/Derivative/DocumentLocalTab.php       |  2 +-
 src/Report/ParagraphCount.php                    | 16 +++++++++-------
 src/Report/ReportBase.php                        |  2 +-
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/Form/ContentModelDocumentationConfigForm.php b/src/Form/ContentModelDocumentationConfigForm.php
index b9ec9e0..e6b26ea 100644
--- a/src/Form/ContentModelDocumentationConfigForm.php
+++ b/src/Form/ContentModelDocumentationConfigForm.php
@@ -73,7 +73,7 @@ class ContentModelDocumentationConfigForm extends ConfigFormBase {
     $documentable_entities['menu'] = $this->moduleHandler->moduleExists('menu_link_content');
     $documentable_entities['modules'] = TRUE;
     $documentable_entities['node'] = $this->moduleHandler->moduleExists('node');
-    $documentable_entities['paragraphs_type'] = $this->moduleHandler->moduleExists('paragraphs');
+    $documentable_entities['paragraph'] = $this->moduleHandler->moduleExists('paragraphs');
     $documentable_entities['taxonomy'] = $this->moduleHandler->moduleExists('taxonomy');
     return $documentable_entities;
   }
diff --git a/src/Plugin/Derivative/DocumentLocalTab.php b/src/Plugin/Derivative/DocumentLocalTab.php
index 8489f8d..5f976b0 100644
--- a/src/Plugin/Derivative/DocumentLocalTab.php
+++ b/src/Plugin/Derivative/DocumentLocalTab.php
@@ -75,7 +75,7 @@ class DocumentLocalTab extends DeriverBase implements ContainerDeriverInterface
         continue;
       }
 
-      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
+      $entity_type = $this->entityTypeManager->hasDefinition($entity_type_id) ? $this->entityTypeManager->getDefinition($entity_type_id) : NULL;
       if (!$entity_type) {
         continue;
       }
diff --git a/src/Report/ParagraphCount.php b/src/Report/ParagraphCount.php
index 1027c37..22b9636 100644
--- a/src/Report/ParagraphCount.php
+++ b/src/Report/ParagraphCount.php
@@ -9,6 +9,8 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
 
   const ENTITY_TYPE = 'paragraphs_type';
 
+  const ENTITY_BUNDLE = 'paragraph';
+
   /**
    * The footer row.
    *
@@ -77,8 +79,8 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
    */
   public function getTableBodyRows(): array {
     $rows = $this->getData();
-    if ($this->config->get(self::ENTITY_TYPE)) {
-      $rows = $this->addDocumentationColumn(self::ENTITY_TYPE, '', $rows);
+    if ($this->config->get(self::ENTITY_BUNDLE)) {
+      $rows = $this->addDocumentationColumn(self::ENTITY_BUNDLE, '', $rows);
     }
     return $rows;
   }
@@ -89,8 +91,8 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
   public function getCsvBodyRows(): array {
     // Will need to convert links to urls.
     $rows = $this->getData();
-    if ($this->config->get(self::ENTITY_TYPE)) {
-      $rows = $this->addDocumentationColumn(self::ENTITY_TYPE, '', $rows, TRUE);
+    if ($this->config->get(self::ENTITY_BUNDLE)) {
+      $rows = $this->addDocumentationColumn(self::ENTITY_BUNDLE, '', $rows, TRUE);
     }
     return $rows;
   }
@@ -160,13 +162,13 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
    *   The array of bundles with a published count.
    */
   protected function getBundlePublishedCount() {
-    if ($this->entityTypeExists(self::ENTITY_TYPE)) {
+    if ($this->entityTypeExists(self::ENTITY_TYPE) && $this->entityTypeExists(self::ENTITY_BUNDLE)) {
       $paragraph_types = $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple();
       foreach ($paragraph_types as $paragraph_type) {
         $type_id = $paragraph_type->id();
         // Query to count the number of paragraphs of this type.
-        $query = $this->entityTypeManager->getStorage('paragraph')->getQuery();
-        $query->condition('type', $type_id)->accessCheck(TRUE);
+        $query = $this->entityTypeManager->getStorage(self::ENTITY_BUNDLE)->getQuery();
+        $query->condition('type', $type_id)->accessCheck(FALSE);
         $count = $query->count()->execute();
 
         // Store the count in the array.
diff --git a/src/Report/ReportBase.php b/src/Report/ReportBase.php
index d717ea8..fe68270 100644
--- a/src/Report/ReportBase.php
+++ b/src/Report/ReportBase.php
@@ -492,7 +492,7 @@ abstract class ReportBase implements ContainerInjectionInterface {
    *  TRUE if the entity type is defined, FALSE otherwise.
    */
   protected function entityTypeExists(string $entity_type_name): bool {
-    return $this->entityTypeManager->hasDefinition("block_content");
+    return $this->entityTypeManager->hasDefinition($entity_type_name);
   }
 
 }
-- 
GitLab


From aa0cf5c56bb6dd25ce2a0f6c4d955d2cacb0cd6b Mon Sep 17 00:00:00 2001
From: Steve Wirt <40593-swirtMiles@users.noreply.drupalcode.org>
Date: Thu, 6 Feb 2025 02:47:22 +0000
Subject: [PATCH 3/4] Instantiate  $paragraph_type_counts

---
 src/Report/ParagraphCount.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/Report/ParagraphCount.php b/src/Report/ParagraphCount.php
index 22b9636..f23656c 100644
--- a/src/Report/ParagraphCount.php
+++ b/src/Report/ParagraphCount.php
@@ -164,6 +164,7 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
   protected function getBundlePublishedCount() {
     if ($this->entityTypeExists(self::ENTITY_TYPE) && $this->entityTypeExists(self::ENTITY_BUNDLE)) {
       $paragraph_types = $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple();
+      $paragraph_type_counts = [];
       foreach ($paragraph_types as $paragraph_type) {
         $type_id = $paragraph_type->id();
         // Query to count the number of paragraphs of this type.
-- 
GitLab


From c4d224f47700f5250cbbbd54068196aa1413e24c Mon Sep 17 00:00:00 2001
From: Steve Wirt <Steve Wirt>
Date: Wed, 5 Feb 2025 22:01:34 -0500
Subject: [PATCH 4/4] Move instantiation.

---
 src/Report/ParagraphCount.php | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/Report/ParagraphCount.php b/src/Report/ParagraphCount.php
index f23656c..0c537c3 100644
--- a/src/Report/ParagraphCount.php
+++ b/src/Report/ParagraphCount.php
@@ -140,8 +140,6 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
    */
   protected function getContentTypeLabels() {
     $label_content_types = [];
-    // @todo There has to be a better way to get the paragraph types than
-    // looping through all the instances.
     $types = ($this->entityTypeExists(self::ENTITY_TYPE)) ? $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple() : [];
     foreach ($types as $key => $type) {
       $label = $type->label();
@@ -162,9 +160,9 @@ class ParagraphCount extends ReportBase implements ReportInterface, ReportTableI
    *   The array of bundles with a published count.
    */
   protected function getBundlePublishedCount() {
+    $paragraph_type_counts = [];
     if ($this->entityTypeExists(self::ENTITY_TYPE) && $this->entityTypeExists(self::ENTITY_BUNDLE)) {
       $paragraph_types = $this->entityTypeManager->getStorage(self::ENTITY_TYPE)->loadMultiple();
-      $paragraph_type_counts = [];
       foreach ($paragraph_types as $paragraph_type) {
         $type_id = $paragraph_type->id();
         // Query to count the number of paragraphs of this type.
-- 
GitLab