Skip to content
Snippets Groups Projects
UWService.php 24.8 KiB
Newer Older
<?php

namespace Drupal\uw_cfg_common\Service;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\simplify_menu\MenuItems;
use Drupal\path_alias\AliasManager;
 * Class UWService.
 *
 * UW Service that holds common functionality used by uw blocks.
 *
 * @package Drupal\uw_cfg_common\Service
 */
class UWService implements UWServiceInterface {

  /**
   * Entity type manager from core.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  private $entityTypeManager;

  /**
   * Database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  private $database;

   * Simplify_menu menu items.
   *
   * @var \Drupal\simplify_menu\MenuItems
   */
  private $simplifyMenu;

  /**
   * Simplify_menu menu items.
   *
   * @var \Drupal\simplify_menu\MenuItems
   */
  private $pathAliasManager;

  /**
   * Default constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity Type Manager from core.
   * @param \Drupal\Core\Database\Connection $database
   *   The database entity.
   * @param \Drupal\simplify_menu\MenuItems $simplifyMenu
   *   The simplify_menu menu items.
   * @param \Drupal\path_alias\AliasManager $pathAliasManager
   *   The Drupal path alias manager.
  public function __construct(EntityTypeManagerInterface $entityTypeManager, Connection $database, MenuItems $simplifyMenu, AliasManager $pathAliasManager) {
    $this->entityTypeManager = $entityTypeManager;
    $this->database = $database;
    $this->simplifyMenu = $simplifyMenu;
    $this->pathAliasManager = $pathAliasManager;
  /**
   * {@inheritDoc}
   */
  public function prepareResponsiveImage(EntityInterface $entity, string $image_style): array {
    // Load in the file object if we have one.
    if ($file = $entity->field_media_image->entity) {
      // Need to set these variables so that responsive image function,
      // has all the necessary info to process the image style.
      $variables['uri'] = $file->getFileUri();
      $variables['responsive_image_style_id'] = $image_style;

      // Set the alt for the image.
      $variables['alt'] = $entity->field_media_image->alt;

      // These is a function from the responsive image module that sets all
      // the variables for the sources of the responsive image.
      template_preprocess_responsive_image($variables);

      // Step through each of the sources and setup our own sources array.
      foreach ($variables['sources'] as $source) {
        $variables['responsive_sources'][] = [
          'srcset' => $source->storage()['srcset']->value(),
          'media' => $source->storage()['media']->value(),
          'type' => $source->storage()['type']->value(),
        ];
      }

      return $variables;
    }

    return [];
  }

Liam Morland's avatar
Liam Morland committed
   * {@inheritDoc}
   */
  public function uwGetNodeContent(Node $node, string $view_mode, string $content = 'all'): array {

    // Flags for getting teaser content.
    $get_header = FALSE;
    $get_footer = FALSE;
    $get_image = FALSE;
    $get_content = FALSE;
    $featured_image = $this->uwGetFeaturedImageContentTypes();

    // Setup flags based on teaser content argument.
      $get_header = TRUE;
      $get_footer = TRUE;
      $get_content = TRUE;

      if ($view_mode == 'teaser') {
        $get_image = TRUE;
      }

      if ($view_mode == 'full') {
        $get_title = FALSE;

        if (in_array($node->getType(), array_keys($featured_image))) {
          $get_image = TRUE;
        $get_header = TRUE;
        $get_footer = TRUE;
    // Setup the teaser data array, based on flags.

        // The list of tags for blogs.
        $tag_list = [
          'field_uw_blog_tags',
          'field_uw_audience',
        ];

          'title' => $get_title ? 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 ? $tag_list : NULL,

        // The list of tags for events.
        $tag_list = [
          'field_uw_event_tags',
          'field_uw_audience',
          'field_uw_event_type',
        ];

          'title' => $get_title ? 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 ? $tag_list : NULL,

        // The list of tags for news.
        $tag_list = [
          'field_uw_news_tags',
          'field_uw_audience',
        ];

          'title' => $get_title ? 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 ? $tag_list : NULL,

      case 'uw_ct_web_page':

        $content_data = [
          'title' => $get_title ? TRUE : NULL,
          'content' => $get_content ? 'layout_builder__layout' : NULL,
        ];
        break;

      case 'uw_ct_catalog_item':

        $content_data = [
          'title' => $get_title ? TRUE : NULL,
          'content' => $get_content ? 'layout_builder__layout' : NULL,
        ];
        break;
          'title' => $get_title ? TRUE : NULL,
          'sub_title' => $get_header ? 'field_uw_ct_contact_title' : NULL,
          'affiliation' => $get_header ? 'field_uw_ct_contact_affiliation' : NULL,
          'image' => $get_image ? 'field_uw_ct_contact_image' : NULL,
          'content' => $get_content ? 'layout_builder__layout' : NULL,
          'email' => $get_footer ? 'field_uw_ct_contact_email' : NULL,
          'location' => $get_footer ? 'field_uw_ct_contact_location' : NULL,
          'phone' => $get_footer ? 'field_uw_ct_contact_phone' : NULL,
          'additional_info' => $get_footer ? 'field_uw_ct_contact_info' : NULL,
          'link_profile' => $get_footer ? 'field_uw_ct_contact_link_profile' : NULL,
          'personal_webpage' => $get_footer ? 'field_uw_ct_contact_link_persona' : NULL,
          'contact_for' => $get_footer ? 'field_uw_ct_contact_contact_for' : NULL,
          'groups' => $get_footer ? 'field_uw_ct_contact_group' : NULL,
          'url' => TRUE,
        ];
        break;

      case 'uw_ct_profile':

        $tag_list = [
          'field_uw_ct_profile_type',
        ];

        $content_data = [
          'title' => $get_title ? TRUE : NULL,
          'sub_title' => $get_header ? 'field_uw_ct_profile_title' : NULL,
          'affiliation' => $get_header ? 'field_uw_ct_profile_affiliation' : NULL,
          'content' => $get_content ? 'field_uw_profile_summary' : NULL,
          'image' => $get_header ? 'field_uw_ct_profile_image' : NULL,
          'tags' => $get_footer ? $tag_list : NULL,
          'link_profile' => $get_footer ? 'field_uw_ct_profile_info_link' : NULL,
          'personal_webpage' => $get_footer ? 'field_uw_ct_profile_link_persona' : NULL,
    return $this->uwGetNodeData($node, $view_mode, $content_data);
  public function uwGetNodeData(Node $node, string $view_mode, array $content_data): array {

    // Array to store the teaser data, need blank
    // array in case there is no data to return.

    // Step through each of the teaser data, and if
    // we are to get the data then set the variable
    // inside the teaser array.
    foreach ($content_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 'additional_info':
            $additional_info = $node->field_uw_ct_contact_info->getValue();
            if ($additional_info) {
              $node_data['additional_info'] = [
                '#type' => 'processed_text',
                '#text' => $additional_info[0]['value'],
                '#format' => $additional_info[0]['format'],
              ];
            }
            $node_data['author'] = $this->uwGetAuthor($node);
            if ($view_mode == 'teaser') {
              $node_data['content'] = [
                '#type' => 'processed_text',
                '#text' => $node->$data->value,
                '#format' => $node->$data->format,
              ];
            }
          case 'date':
            $node_data['date'] = $this->uwGetDates($node, $data);
            break;

          case 'groups':
            $node_data['groups'] = $this->uwGetTermsFromEntityField($node->field_uw_ct_contact_group, 'tags');
            break;

          case 'image':
            $node_data['image'] = $this->uwGetImage($node, $data);
            break;

          case 'link_profile':
          case 'personal_webpage':
            $node_data[$index] = $this->uwGetLinkInfo($node, $data);
            break;

          case 'sources':
            $node_data['image'] = $this->uwGetSources($node, $data);
            break;

          case 'tags':
            $tags = [];
            foreach ($data as $field) {
              $tags = array_merge($tags, $this->uwGetTermsFromEntityField($node->$field, 'tags'));
            }
          case 'title':
            $node_data['title'] = $node->getTitle();
            break;

            $node_data['url'] = $node->toUrl()->toString();

          default:
            $node_data[$index] = $node->$data->value;
            break;
  /**
   * {@inheritDoc}
   */
  public function uwGetFeaturedImageContentTypes(): array {
    return [
      'uw_ct_blog' => 'field_uw_blog_listing_page_image',
      'uw_ct_event' => 'field_uw_event_listing_page_img',
      'uw_ct_news_item' => 'field_uw_news_listing_page_image',
    ];
  }

  /**
   * {@inheritDoc}
   */
  public function uwGetLinkInfo(Node $node, string $field_name): array {

    $return_link_data = [];

    // Get the link from the node.
    $link_data = $node->$field_name->getValue();

    // If there is data in the link, get the variables.
    if ($link_data) {
      $return_link_data['uri'] = $link_data[0]['uri'];
      $return_link_data['title'] = $link_data[0]['title'];
    }

    return $return_link_data;
  }

  /**
   * {@inheritDoc}
   */
  public function uwGetImage(Node $node, string $field_name): array {

    $image = [];

    // Get the media id.

    // If there is an image, process it.
    if ($mid) {

      // Load in the media item.
      $media = $this->entityTypeManager->getStorage('media')->load($mid[0]['target_id']);

      // Get the file id from the media object.
      $fid = $media->getSource()->getSourceFieldValue($media);

      // If there is a file id, then get the uri,
      // using the thumbnail image style.
      if ($fid) {
        $file = $this->entityTypeManager->getStorage('file')->load($fid);
        $image['uri'] = $this->entityTypeManager->getStorage('image_style')->load('thumbnail')->buildUrl($file->getFileUri());
        $image['alt'] = $media->field_media_image->alt;
      }
    }

    return $image;
  }

  /**
   * {@inheritDoc}
   */
  public function uwGetDates(Node $node, string $field_name): array {

    $return_dates = [];

    // If this is not and event, just get the date.
    if ($node->getType() !== 'uw_ct_event') {
      $return_dates[] = date('l, F j, Y', strtotime($node->$field_name->value));
    }
    else {

      // Get all the dates.
      $dates = $node->$field_name->getValue();

      // Step through each of the dates and get
      // out correct values.
      foreach ($dates as $date) {

        // The all day case, duration is always 1439.
        if ($date['duration'] == '1439' && $date['end_value'] > strtotime("now")) {
          $return_dates[] = date('l, F j, Y', $date['value']) . ' (all day)';
        }
        else {

          // If the date is upcoming, meaning greater than right now.
          // Taking this out for now, will be putting it back, if
          // we figure out how to do this in the view.
          // if ($date['end_value'] > strtotime("today")) {.
          // If this is the same day, get the date and the start
          // and end times.
          if ($date['duration'] < '1439') {
            $start_date = date('l, F j, Y g:i A', $date['value']);
            $end_date = date('g:i A', $date['end_value']);
          }
          // This is not the day, get the start and end date with time.
          else {
            $start_date = date('l, F j, Y g:i A', $date['value']);
            $end_date = date('l, F j, Y g:i A', $date['end_value']);

          // Add the start and end date with timezone.
          $return_dates[] = $start_date . ' - ' . $end_date . ' ' . date('T', $date['end_value']);
        }
      }
    }

    return $return_dates;
  }

  /**
   * {@inheritDoc}
   */
  public function uwGetSources(Node $node, string $field_name): array {

    $return_sources = [];

    // Get the image entity.
    $image = $node->$field_name->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'])) {
      $return_sources['sources'] = $sources['sources'];
      $return_sources['img_element'] = $sources['img_element']['#uri'];
      $return_sources['alt'] = $sources['alt'];
    }

    return $return_sources;
  }

  /**
   * {@inheritDoc}
   */
  public function getOrCheckAttachedSidebar(int $attached_page_nid, int $sidebar_nid = NULL, string $type = NULL): int {

    // A database called to get the field with the condition of the
    // attached_page_nid.
    $result = $this->database
      ->select('node__field_uw_attach_page', 'nfuap')
      ->fields('nfuap', ['entity_id', 'field_uw_attach_page_target_id'])
      ->condition('field_uw_attach_page_target_id', $attached_page_nid);

    // If we are doing a a check for sidebar, then add the condition
    // that it is not equal to the current sidebar_nid that we are on.
    // Meaning that we are checking for any other sidebars that this
    // attached_page_nid is attached to.
    if ($type == 'check') {

      // Add the not equals to condition.
      $result->condition('entity_id', $sidebar_nid, '<>');
    }

    // Get the results of query, we only need to fetch, because we are
    // only every expecting one sidebar only has one other node page
    // attached.
    $results = $result->execute()->fetch();

    // If we have results, then return the entity_id, which is the
    // sidebar_nid that the attached_page_nid is attached to.
    if (isset($results->entity_id)) {

      // Return the entity_id.
      return $results->entity_id;
    }

    // If we made it here, there are no other sidebars that the
    // attached_page_nid is attached to, so we can simply return 0.
    else {
      return 0;
    }
  }

  /**
   * {@inheritDoc}
   */
  public function getUwContentTypes($with_sidebar = FALSE): array {
    $return_content_types = [];

    // This is the list of all UW content types, with a TRUE/FALSE, indicating
    // whether or not a sidebar can be attached to this content type.
    $content_types = [
      'uw_ct_blog' => TRUE,
      'uw_ct_catalog_item' => FALSE,
      'uw_ct_event' => TRUE,
      'uw_ct_news_item' => TRUE,
      'uw_ct_sidebar' => FALSE,
      'uw_ct_site_footer' => FALSE,
      'uw_ct_web_page' => TRUE,
    ];

    foreach ($content_types as $key => $value) {
      if ($with_sidebar && $value) {
        $return_content_types[] = $key;
      }
      elseif (!$with_sidebar) {
        $return_content_types[] = $key;
      }
    }

    return $return_content_types;
  }

  public function uwGetMenu(string $menu_name = 'main', bool $count_menu_items = FALSE, bool $include_parent_in_count = FALSE): array {

    // Get the main menu from the simplify menu module.
    $menu = $this->simplifyMenu->getMenuTree($menu_name);

    // Set it to the menu_tree which is done by simplify menu.
    // Ensure that we only get the published menu items.
    $this->uwCheckPublishedMenuItems($menu);

    // If we want to have the count of menu items, then count them.
    if ($count_menu_items) {

      // Add the count of the menu items.
      $menu = $this->uwSetMenuItems($menu, $include_parent_in_count);
    }

    return $menu;
  }

  /**
   * {@inheritDoc}
   */
  public function uwCheckPublishedMenuItems(&$menu): void {

    // The base path, need this for removing when on subfoldered sites,
    // for example d8/fdsu5/, we need to remove the fdsu5 from the path
    // alias.
    global $base_path;

    // Step through each menu and ensure that it is published.
    foreach ($menu as $key => $m) {

      // If there is a submenu (i.e. children), process it first.
      if (isset($m['submenu'])) {
        $this->uwCheckPublishedMenuItems($menu[$key]['submenu']);
      }

      // Remove the base path from the url so that we can get
      // the actual content from the path alias.
      $alias = str_replace($base_path, '', $m['url']);

      // Get the path from the URL of the menu link.
      $path = $this->pathAliasManager->getPathByAlias('/' . $alias);

      // Check if it is a node path and if so check if published.
      if (preg_match('/^node\/(\d+)$/', $path, $matches)) {

        // Load in the node based on the path.
        $node = $this->entityTypeManager->getStorage('node')->load($matches[1]);

        // If the node is unpublished, remove it from the menus.
        if ($node->status->value == 0) {
          unset($menu[$key]);
        }
      }
    }
  public function uwSetMenuItems(array $menus, bool $include_parent_in_count = FALSE): array {

    // Step through the menu and do a few things:
    // (a) Remove the Home link (this will be a house icon)
    // (b) Add the number of menu items per menu link.
    foreach ($menus as $index => $menu) {

      // If this is the Home link, then remove it.
      if ($menu['text'] == "Home") {

        // Remove the home link.
        unset($menus[$index]);
      }

      // If we are not on the home link, then add the number
      // of menu items in this menu link.
      else {

        // Set the menu_item_count, initially to 0.

        // If there is a submenu, recursivley call the count function.
        if (isset($menu['submenu']) && count($menu['submenu']) > 0) {

          // Call the count function recursively till we have the number of
          // menu items.
          $this->uwCountMenuItems($menu['submenu'], $menu_items_count);

          // Set the menu items count.
          // If we need to include the parent in the count, for example the
          // main menu will print the parent inside the tray, then we increment
          // the menu items count by 1.
          if ($include_parent_in_count) {
            $menu_items_count++;
          }

          // Set the menu items count in the menu.
          $menus[$index]['menu_items_count'] = $menu_items_count;
        }

        // If there are no submenus, the count is 0, there will be no tray.
        else {

          // Set the number of items count, which is 0.
          $menus[$index]['menu_items_count'] = $menu_items_count;
  /**
   * {@inheritDoc}
   */
  public function uwCountMenuItems($menus, &$menu_items_count): void {

    // Step through the menus and check for submenus and count.
    foreach ($menus as $menu) {
      // Increment the menu items counter.
      $menu_items_count++;

      // If there is a submenu, recursivley call the count function.
      if (isset($menu['submenu']) && count($menu['submenu']) > 0) {

        // Recursively check the submenu.
        $this->uwCountMenuItems($menu['submenu'], $menu_items_count);

      }
    }
  }
  /**
   * Determine whether a node is the home page.
   *
   * @param int $nid
   *   A node ID.
   *
   * @return bool
   *   TRUE when the node is the home page, FALSE otherwise.
   */
  public static function nodeIsHomePage(int $nid): bool {
    $front_page_path = \Drupal::configFactory()->get('system.site')->get('page.front');
    $node_alias = \Drupal::service('path_alias.manager')->getAliasByPath('/node/' . $nid);
    return $front_page_path === $node_alias;
  }

  /**
   * {@inheritDoc}
   */
  public function uwMonthNameShort(int $month = NULL) {

    static $months = [
      1 => 'Jan.',
      2 => 'Feb.',
      3 => 'Mar.',
      4 => 'Apr.',
      5 => 'May',
      6 => 'June',
      7 => 'July',
      8 => 'Aug.',
      9 => 'Sep.',
      10 => 'Oct.',
      11 => 'Nov.',
      12 => 'Dec.',
    ];
    if ($month) {
      return $months[$month];
    }
    else {
      return $months;
    }
  }

   * {@inheritDoc}
  public function uwGetAuthor(Node $node): array {

    // Get the author field from the node, if there is
    // no author specified the value will be NULL.
    $author_name = $node->field_author->value;
    // If there is no author in the field, get the owner
    // of the blog post.
    if (!$author_name) {

      // Set the author to the person who made blog.
      $author = [
        'name' => $node->getOwner()->getDisplayName(),
        'link' => NULL,
      ];
    }

    // If there is an author, get the author name and link.
    else {

      // Get the link field from the node.
      $link = $node->field_uw_author_link->getValue();

      // Set the author name and link (if any).
      $author = [
        'name' => $author_name,
        'link' => empty($link) ? NULL : $link[0]['uri'],
      ];
  /**
   * {@inheritDoc}
   */
  public function uwGetTerms(array $tids, string $type = NULL): array {

    // Array to hold the terms, need to set to
    // null in case there are no terms to be
    // returned.
    $terms = [];

    // Step through each of the tids and get the term name.
    foreach ($tids as $tid) {

      // Load the term.
      $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid['target_id']);

      // If this is a tags term type, we have to include
      // url and title.  If not just the tag name.
      if ($type == 'tags') {

        $terms[] = [
          'title' => $term->getName(),
          'url' => Url::fromRoute(
            'entity.taxonomy_term.canonical',
            ['taxonomy_term' => $tid['target_id']]
          )->toString(),
        ];
      }
      else {
        $terms[] = $term->getName();
      }
    }

    // Return an array of term names.
    return $terms;
  }

  /**
   * {@inheritDoc}
   */
  public function uwGetTermsFromEntityField(EntityReferenceFieldItemListInterface $values, string $type = NULL): array {

    // Array to hold the terms, need to set to
    // null in case there are no terms to be
    // returned.
    // Step through each of the values which is a
    // list of referenced taxonomy terms.

      // Get the term entity, which is the same as
      // loading the term.
      // If there is an entity, set the variable.

        // If this is a tags term type, we have to include
        // url and title.  If not just the tag name.

          // Set the variables.  By default function
          // toUrl on entity uses canonical url.
          $terms[] = [
            'title' => $term_entity->getName(),
            'url' => $term_entity->toUrl()->toString(),
          ];
        }
        else {
          $terms[] = $term_entity->getName();
        }
      }
    }

    // Return an array of term names.