From b8b46557657db33b1fe159ef18ce807de2243f01 Mon Sep 17 00:00:00 2001
From: ebremner <ebremner@uwaterloo.ca>
Date: Tue, 8 Jun 2021 12:07:09 -0400
Subject: [PATCH] ISTWCMS-4619: refactoring teaser content/data

---
 src/Service/UWService.php          | 247 +++++++++++++++++------------
 src/Service/UWServiceInterface.php |  17 +-
 2 files changed, 159 insertions(+), 105 deletions(-)

diff --git a/src/Service/UWService.php b/src/Service/UWService.php
index 4c5eeac1..03ff39e1 100644
--- a/src/Service/UWService.php
+++ b/src/Service/UWService.php
@@ -106,120 +106,159 @@ class UWService implements UWServiceInterface {
   /**
    * {@inheritDoc}
    */
-  public function getTeaserContent(NodeInterface $node, array $variables_to_get, string $teaser_type): array {
-    $variables = [];
-    // Step through each of the variables to get and set the variables for the
-    // teaser content.
-    foreach ($variables_to_get as $variable_to_get) {
-
-      // Switch on the variable to get and set the variables for the teaser
-      // content.
-      switch ($variable_to_get) {
-
-        case 'title':
-
-          // Set the title from the node object.
-          $variables['title'] = $node->getTitle();
-          break;
-
-        case 'url':
-
-          // Set the title from the node object.
-          $variables['url'] = $node->toUrl()->toString();
-          break;
-
-        case 'date':
-
-          // Set the field name, all of our content types use the same format,
-          // field_uw_<content_type>_date.
-          $field_name = 'field_uw_' . trim($teaser_type) . '_date';
-
-          if (trim($teaser_type) == 'event') {
-            $variables['date'] = $node->$field_name->getValue();
-          }
-          else {
-
-            // Set the date variable, once returned to the calling function,
-            // they can change the date format as required (i.e. change it
-            // to long-date or date-time).
-            $variables['date'] = $node->$field_name->getString();
-          }
-
-          break;
-
-        case 'author':
-
-          // If author is selected, get both the author name and link.
-          $variables['author_name'] = $node->getOwner()->getDisplayName();
-          $variables['author_link'] = $node->getOwner()->toUrl()->toString();
-          break;
-
-        case 'sources':
-
-          // Event has a different name for the image than the rest, so ensuring
-          // that we get the correct field name for the image.
-          // In most cases it is field_uw_<content_type>_lising_page_image.
-          if ($teaser_type == 'event') {
-            $field_name = 'field_uw_event_listing_page_img';
-          }
-          else {
-            $field_name = 'field_uw_' . trim($teaser_type) . '_listing_page_image';
-          }
-
-          // Get the image object from the node.
-          $image = $node->$field_name->entity;
-
-          // Ensure that we have an image before adding variables.
-          if ($image !== NULL) {
+  public function getTeaserContent(Node $node, string $teaser_type, string $teaser_content = 'all'): array {
+
+    // Flags for getting teaser content.
+    $get_header = FALSE;
+    $get_footer = FALSE;
+    $get_image = FALSE;
+    $get_content = FALSE;
+
+    // Setup flags based on teaser content argument.
+    if ($teaser_content == 'all') {
+      $get_header = TRUE;
+      $get_footer = TRUE;
+      $get_image = TRUE;
+      $get_content = TRUE;
+    }
+    else {
+      if ($teaser_content == 'header') {
+        $get_header = TRUE;
+      }
 
-            // Get all the image variables, including the sources using the
-            // prepareResponsiveImage function.
-            $image_variables = $this->prepareResponsiveImage($image, 'uw_ris_media');
+      if ($teaser_content == 'footer') {
+        $get_footer = TRUE;
+      }
+    }
 
-            // Set the responsive image variables for the teaser content.
-            $variables['sources'] = $image_variables['responsive_sources'];
-            $variables['img_element'] = $image_variables['img_element']['#uri'];
-            $variables['alt'] = $image->field_media_image->alt;
-          }
-          break;
+    // Setup the teaser data array, based on flags.
+    switch ($teaser_type) {
+      case 'blog':
+        $teaser_data = [
+          'title' => $get_header ? TRUE : NULL,
+          'url' => TRUE,
+          'date' => $get_header ? 'field_uw_blog_date' : NULL,
+          'author' => $get_header ? TRUE : NULL,
+          'sources' => $get_image ? 'field_uw_blog_listing_page_image' : NULL,
+          'content' => $get_content ? 'field_uw_blog_summary' : NULL,
+          'tags' => $get_footer ? ['field_uw_blog_tags', 'field_uw_audience'] : NULL
+        ];
+        break;
 
-        case 'tags':
+      case 'events':
+        $teaser_data = [
+          'title' => $get_header ? TRUE : NULL,
+          'url' => TRUE,
+          'date' => $get_header ? 'field_uw_event_date' : NULL,
+          'sources' => $get_image ? 'field_uw_event_listing_page_img' : NULL,
+          'content' => $get_content ? 'field_uw_event_summary' : NULL,
+          'tags' => $get_footer ? ['field_uw_event_tags', 'field_uw_audience', 'field_uw_event_type'] : NULL,
+        ];
+        break;
 
-          // Set the field name for the tags which is
-          // field_uw_<content_type>_tags.
-          $field_name = 'field_uw_' . trim($teaser_type) . '_tags';
+      case 'news':
+        $teaser_data = [
+          'title' => $get_header ? TRUE : NULL,
+          'url' => TRUE,
+          'date' => $get_header ? 'field_uw_news_date' : NULL,
+          'sources' => $get_image ? 'field_uw_news_listing_page_image' : NULL,
+          'content' => $get_content ? 'field_uw_news_summary' : NULL,
+          'tags' => $get_footer ? ['field_uw_news_tags', 'field_uw_audience'] : NULL,
+        ];
+        break;
+    }
 
-          // Get all the taxonomy terms for the blog.
-          // Step through each taxonomy term and get the tag info.
-          foreach ($node->$field_name as $tag) {
+    return $this->getTeaserData($node, $teaser_type, $teaser_data);
+  }
 
-            // Set the tags in the teaser content variables.
-            $variables['tags'][] = [
-              'title' => $tag->entity->name->value,
-              'url' => $tag->entity->toUrl()->toString(),
+  /**
+   * {@inheritDoc}
+   */
+  public function getTeaserData(Node $node, string $teaser_type, array $teaser_data): array {
+
+    // Array to store the teaser data, need blank
+    // array in case there is no data to return.
+    $teaser = [];
+
+    // Step through each of the teaser data, and if
+    // we are to get the data then set the variable
+    // inside the teaser array.
+    foreach ($teaser_data as $index => $data) {
+
+      // If there is data to get, then get it.
+      if ($data) {
+
+        // Switch on the index to get the proper value.
+        // The index will either be true (like title) or
+        // a field name.
+        switch ($index) {
+
+          case 'title':
+            $teaser['title'] = $node->getTitle();
+            break;
+
+          case 'author':
+            $teaser['author'] = $this->uwGetAuthor($node);
+            break;
+
+          case 'date':
+            if ($teaser_type !== 'event') {
+              $teaser['date'] = date('l, F j, Y', strtotime($node->$data->value));
+            }
+            else {
+
+              // Get all the dates.
+              // @todo figure out what date to display for events.
+              $dates = $node->$data->getValue();
+
+              $teaser['date']  = date('l, F j, Y', $dates[0]['value']);
+            }
+            break;
+
+          case 'sources':
+
+            // Get the image entity.
+            $image = $node->$data->entity;
+
+            // If there is an image, get the responsive image sources.
+            if ($image) {
+              $sources = $this->prepareResponsiveImage($image, 'uw_ris_media');
+            }
+            else {
+              $sources = NULL;
+            }
+
+            if (isset($sources['responsive_sources'])) {
+              $teaser['image']['sources'] = $sources['sources'];
+              $teaser['image']['img_element'] = $sources['img_element']['#uri'];
+              $teaser['image']['alt'] = $sources['alt'];
+            }
+            break;
+
+          case 'content':
+            $teaser['content'] = [
+              '#type' => 'processed_text',
+              '#text' => $node->$data->value,
+              '#format' => $node->$data->format,
             ];
-          }
-          break;
-
-        case 'content':
-
-          // Set the field name for the summary, which is
-          // field_name<content_type>_summary.
-          $field_name = 'field_uw_' . $teaser_type . '_summary';
-
-          // Set the render array for the summary, we simply can not just send
-          // the value as Drupal will just render it with no filters or HTML
-          // applied. We need to send the full render array.
-          $variables['content'] = [
-            '#type' => 'processed_text',
-            '#text' => $node->$field_name->value,
-            '#format' => $node->$field_name->format,
-          ];
-          break;
+            break;
+
+          case 'tags':
+            $tags = [];
+            foreach ($data as $field) {
+              $tags = array_merge($tags, $this->uwGetTermsFromEntityField($node->$field, 'tags'));
+            }
+            $teaser['tags'] = [$tags];
+            break;
+
+          case 'url':
+            $teaser['url'] = $node->toUrl()->toString();
+            break;
+        }
       }
     }
 
-    return $variables;
+    return $teaser;
   }
 
   /**
diff --git a/src/Service/UWServiceInterface.php b/src/Service/UWServiceInterface.php
index 7507e3fa..b5f52815 100644
--- a/src/Service/UWServiceInterface.php
+++ b/src/Service/UWServiceInterface.php
@@ -42,7 +42,22 @@ interface UWServiceInterface {
    * @return array
    *   Array of variables and their values.
    */
-  public function getTeaserContent(NodeInterface $node, array $variables_to_get, string $teaser_type): array;
+  public function getTeaserContent(Node $node, string $teaser_type, string $teaser_content = 'all'): array;
+
+  /**
+   * Gets teaser data.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   Node entity.
+   * @param string $teaser_type
+   *   The type of teaser (i.e. blog, events, news, etc).
+   * @param array $teaser_data
+   *   An array of all the data to get for the teaser.
+   *
+   * @return array
+   *   Array of teaser values.
+   */
+  public function getTeaserData(Node $node, string $teaser_type, array $teaser_data): array;
 
   /**
    * A function to get or check the attached sidebar.
-- 
GitLab