<?php namespace Drupal\uw_cfg_common\Service; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\node\NodeInterface; 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; // 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 []; } /** * {@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) { // Get all the image variables, including the sources using the // prepareResponsiveImage function. $image_variables = $this->prepareResponsiveImage($image, 'uw_ris_media'); // 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; case 'tags': // Set the field name for the tags which is // field_uw_<content_type>_tags. $field_name = 'field_uw_' . trim($teaser_type) . '_tags'; // Get all the taxonomy terms for the blog. // Step through each taxonomy term and get the tag info. foreach ($node->$field_name as $tag) { // Set the tags in the teaser content variables. $variables['tags'][] = [ 'title' => $tag->entity->name->value, 'url' => $tag->entity->toUrl()->toString(), ]; } 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; } } return $variables; } /** * {@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; } /** * {@inheritDoc} */ public function uwGetMenu(string $menu_name = 'main', bool $count_menu_items = FALSE, bool $include_parent_in_count = FALSE): array { // 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; // 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. $menu = $menu['menu_tree']; // Step through each menu and ensure that it is published. foreach ($menu as $key => $m) { // 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]); } } } // 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 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. $menu_items_count = 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; } } } return $menus; } /** * {@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; } } }