Skip to content
Snippets Groups Projects
UWService.php 16.1 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\simplify_menu\MenuItems;
use Drupal\path_alias\AliasManager;
use Symfony\Component\HttpFoundation\RequestStack;
 * 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;

  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private $requestStack;

  /**
   * 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.
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   The request stack.
  public function __construct(EntityTypeManagerInterface $entityTypeManager, Connection $database, MenuItems $simplifyMenu, AliasManager $pathAliasManager, RequestStack $requestStack) {
    $this->entityTypeManager = $entityTypeManager;
    $this->database = $database;
    $this->simplifyMenu = $simplifyMenu;
    $this->pathAliasManager = $pathAliasManager;
    $this->requestStack = $requestStack;
  public function getCropImageStyles(string $type, bool $get_all = FALSE): array {

    // Image styles for portrait.
    // Image styles for responsive.
    $image_styles['responsive'] = [
      'uw_is_media_x_large',
      'uw_is_media_x_small',
      'uw_is_media_medium',
      'uw_is_media_large',
      'uw_is_media_small',
    ];

    // If the flag to get all the image styles is set,
    // return all of them.  If not return the
    // specific image style.
    if ($get_all) {
      return $image_styles;
    }
    else {
      return $image_styles[$type];
    }
  public function prepareResponsiveImage(?EntityInterface $entity, string $image_style): array {
    // Ensure that we can load an entity on the media.
    if ($entity && isset($entity->field_media_image->entity)) {

      // 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;

        // This 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) {

          $srcset = $source->storage()['srcset']->value();
          $srcset_parts = explode('/', $srcset);

          foreach ($srcset_parts as $srcset_part) {
            if (strpos($srcset_part, 'uw_is') !== FALSE) {
              $style = $srcset_part;
              break;
            }
          }

            'media' => $source->storage()['media']->value(),
            'type' => $source->storage()['type']->value(),
  /**
   * {@inheritDoc}
   */
  public function uwGetResponsiveImageStyles(): array {
    return [
      'uw_is_media_x_large',
      'uw_is_media_large',
      'uw_is_media_medium',
      'uw_is_media_small',
      'uw_is_media_x_small',
      'uw_is_portrait',
  public function uwGetNodePreprocessing(string $type): array {

    // Ensure that we return at least empty array.
    $preprocess = [];

    // Get the array of things to be proprocessed based
    // on the type.
    switch ($type) {

      case 'full':
        $preprocess = [
          'uw_ct_blog',
          'uw_ct_catalog_item',
          'uw_ct_contact',
          'uw_ct_expand_collapse_group',
        ];
        break;

      case 'layout_container':
        $preprocess = [
          'uw_ct_blog',
          'uw_ct_contact',
        ];
        break;

      case 'teaser':
        $preprocess = [
          'uw_ct_blog',
          'uw_ct_catalog_item',
          'uw_ct_contact',
          'uw_ct_opportunity',
          'uw_ct_blog',
          'uw_ct_event',
          'uw_ct_news_item',
  public function uwCheckNodeForMedia(Node $node): string {

    // Set the node type.
    $node_type = $node->getType();

    // Get the list of content types that are allowed to have
    // hero from our service.
    $media = $this->uwGetNodePreprocessing('media');
    // If node is allowed to have a media, make sure that
    // node actually has a media.
    if (in_array($node_type, $media)) {
      // Ensure that the node has the type of media field.
      if ($node->hasField('field_uw_type_of_media')) {
        // Get the type of media value from the node.
        $value = $node->field_uw_type_of_media->value;

        // If there is a media present, set the variable so that
        // the page title will not be displayed.
        if ($value) {
          return 'yes';
        }
  /**
   * {@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_contact' => FALSE,
      'uw_ct_event' => TRUE,
      'uw_ct_news_item' => TRUE,
      'uw_ct_opportunity' => FALSE,
      'uw_ct_profile' => FALSE,
      'uw_ct_project' => FALSE,
      'uw_ct_service' => 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.
    // Check that menu links are published and accessible.
    $this->uwCheckMenuItems($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 uwCheckMenuItems(&$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->uwCheckMenuItems($menu[$key]['submenu']);
      }

      // If its inaccessible, remove the menu link.
      if ($m['text'] == 'Inaccessible') {
        unset($menu[$key]);
        // 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');
    $front_page_alias = \Drupal::service('path_alias.manager')->getAliasByPath($front_page_path);
    $node_alias = \Drupal::service('path_alias.manager')->getAliasByPath('/node/' . $nid);
    return $front_page_alias === $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;
    }
  }

  public function getContentTypeUsage(
    array $content_types,
    bool $show_null_content_types = FALSE
  ): array {

    // Node content types array.
    $list = [];

    // Step through the content types and get info.
    foreach ($content_types as $ct) {

      // Query to get all nodes of the content type.
      $query = $this->entityTypeManager->getStorage('node')->getQuery();
      $query->condition('type', $ct);

      // Get the total number of nodes.
      $total = $query->count()->execute();

      // If there are no nodes of the content type,
      // break out of this iteration, as we do not
      // want to display no nodes, however if flag
      // is set to show null nodes we will show them.
      if ($total == 0 && !$show_null_content_types) {
        continue;
      }

      // Load the content type, we need to use current as this
      // will load multiple, current will load the first entry.
      $content_type = current(
        $this->entityTypeManager->getStorage('node_type')
          ->loadByProperties(['type' => $ct])
      );

      // Add the condition of published to query.
      $query->condition('status', 1);

      // Set the number of published nodes.
      $published = $query->count()->execute();

      // Set up the list to be used as rows in the table.
      $list[$ct] = [
        'name' => $content_type->get('name'),
        'total' => $total,
        'published' => $published,
        'unpublished' => $total - $published,
      ];
    }