diff --git a/src/Service/UWService.php b/src/Service/UWService.php index 598b191b3b7b9dca960696cc02dd0e19dc859c04..de7600a29398ac52ab98570f5a3a35d5178898a0 100644 --- a/src/Service/UWService.php +++ b/src/Service/UWService.php @@ -2,12 +2,9 @@ namespace Drupal\uw_cfg_common\Service; -use Drupal\Component\Utility\UrlHelper; 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; @@ -84,376 +81,38 @@ class UWService implements UWServiceInterface { */ 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) { + // Ensure that we can load an entity on the media. + if (isset($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; + // Load in the file object if we have one. + if ($file = $entity->field_media_image->entity) { - // Set the alt for the image. - $variables['alt'] = $entity->field_media_image->alt; + // 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); + // Set the alt for the image. + $variables['alt'] = $entity->field_media_image->alt; - // 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 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; - $get_title = TRUE; - - $featured_image = $this->uwGetNodePreprocessing('featured_image'); - - // Setup flags based on teaser content argument. - if ($content == 'all') { - $get_header = TRUE; - $get_footer = TRUE; - $get_content = TRUE; - - if ($view_mode == 'teaser') { - $get_image = TRUE; - } + // 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); - if ($view_mode == 'full') { - $get_title = FALSE; - - if (in_array($node->getType(), array_keys($featured_image))) { - $get_image = TRUE; - $get_title = TRUE; + // 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(), + ]; } - } - } - else { - if ($content == 'header') { - $get_header = TRUE; - $get_image = TRUE; - } - if ($content == 'footer') { - $get_footer = TRUE; - $get_title = FALSE; + return $variables; } } - // Setup the teaser data array, based on flags. - switch ($node->getType()) { - - case 'uw_ct_blog': - - // The list of tags for blogs. - $tag_list = [ - 'field_uw_blog_tags', - 'field_uw_audience', - ]; - - $content_data = [ - '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, - 'hero' => $get_image ? 'field_uw_hero_image' : NULL, - 'content' => $get_content ? 'field_uw_blog_summary' : NULL, - 'tags' => $get_footer ? $tag_list : NULL, - ]; - break; - - case 'uw_ct_event': - - // The list of tags for events. - $tag_list = [ - 'field_uw_event_tags', - 'field_uw_audience', - 'field_uw_event_type', - ]; - - $content_data = [ - '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, - 'hero' => $get_image ? 'field_uw_hero_image' : NULL, - 'tags' => $get_footer ? $tag_list : NULL, - 'host' => $get_footer ? 'field_uw_event_host' : NULL, - 'event_website' => $get_footer ? 'field_uw_event_website' : NULL, - 'cost' => $get_footer ? 'field_uw_event_cost' : NULL, - 'map' => $get_footer ? 'field_uw_event_location_coord' : NULL, - 'address' => $get_footer ? 'field_uw_event_location_address' : NULL, - 'map_link' => $get_footer ? 'field_uw_event_map' : NULL, - ]; - break; - - case 'uw_ct_news_item': - - // The list of tags for news. - $tag_list = [ - 'field_uw_news_tags', - 'field_uw_audience', - ]; - - $content_data = [ - '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, - 'hero' => $get_image ? 'field_uw_hero_image' : NULL, - 'content' => $get_content ? 'field_uw_news_summary' : NULL, - 'tags' => $get_footer ? $tag_list : NULL, - ]; - break; - - 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': - - $tags = [ - 'Category' => 'field_uw_catalog_category', - 'Faculty' => 'field_uw_catalog_faculty', - 'Audience' => 'field_uw_audience', - ]; - - $content_data = [ - 'title' => $get_title ? TRUE : NULL, - 'content' => $get_content ? 'layout_builder__layout' : NULL, - 'catalog_tags' => $get_footer ? $tags : NULL, - ]; - break; - - case 'uw_ct_contact': - - $content_data = [ - 'title' => $get_title ? TRUE : NULL, - 'position' => $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, - 'position' => $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, - 'sources' => $get_image ? '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, - 'url' => TRUE, - ]; - break; - } - - return $this->uwGetNodeData($node, $view_mode, $content_data); - } - - /** - * {@inheritDoc} - */ - 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. - $node_data = []; - - // 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'], - ]; - } - break; - - case 'address': - $node_data['address'] = NULL; - $address = $node->$data->getValue(); - if (isset($address[0])) { - $node_data['address'] = $address[0]; - } - break; - - case 'author': - $node_data['author'] = $this->uwGetAuthor($node); - break; - - case 'content': - if ($view_mode == 'teaser') { - $node_data['content'] = [ - '#type' => 'processed_text', - '#text' => $node->$data->value, - '#format' => $node->$data->format, - ]; - } - break; - - case 'date': - $node_data['date'] = $this->uwGetDates($node, $data, $view_mode); - break; - - case 'audience': - case 'category': - case 'faculty': - case 'groups': - $node_data[$index] = $this->uwGetTermsFromEntityField($node->$data, 'tags'); - break; - - case 'image': - $node_data['image'] = $this->uwGetImage($node, $data); - break; - - case 'event_website': - case 'host': - case 'link_profile': - case 'map_link'; - case 'personal_webpage': - $node_data[$index] = $this->uwGetLinkInfo($node, $data); - break; - - case 'map': - // Set the map initially to null, if there are - // coordinates, then will be replaced. - $node_data['map'] = NULL; - - // If there are coordinates, set the map. - if ($node->$data->getValue()) { - $display = [ - 'type' => 'leaflet_formatter_default', - 'label' => 'visually_hidden', - ]; - $node_data['map'] = $node->$data->view($display); - } - break; - - case 'sources': - $node_data['image'] = $this->uwGetSources($node, $data); - break; - - case 'hero': - $node_data['hero'] = $this->uwGetSources($node, $data); - break; - - case 'catalog_tags': - - // Empty arrays so that we don't get undefined - // index errors. - $tabs = []; - $tags = []; - - // Get the entity and values for the catalog, - // which is the taxonomy term catalog. - $catalog_entity = $node->field_uw_catalog_catalog->entity; - $tabs_values = $catalog_entity->field_uw_catalog_tabs_display->getValue(); - - // Setup the array that we can use for in_array, - // which is the tabs to be displayed. - foreach ($tabs_values as $tab_value) { - $tabs[] = $tab_value['value']; - } - - // If there are tabs, then get them. - if (!empty($tabs)) { - foreach ($data as $key => $field) { - if (in_array($key, $tabs)) { - $tags_to_add = $this->uwGetTermsFromEntityField($node->$field, 'tags'); - - if (!empty($tags_to_add)) { - $tags[$key] = $this->uwGetTermsFromEntityField($node->$field, 'tags'); - } - } - } - } - - $node_data[$index] = $tags; - break; - - case 'tags': - $tags = []; - foreach ($data as $field) { - $tags_to_add = $this->uwGetTermsFromEntityField($node->$field, 'tags'); - $tags = array_merge($tags, $this->uwGetTermsFromEntityField($node->$field, 'tags')); - } - $node_data[$index] = [$tags]; - break; - - case 'title': - $node_data['title'] = $node->getTitle(); - break; - - case 'url': - $node_data['url'] = $node->toUrl()->toString(); - break; - - default: - $node_data[$index] = $node->$data->value; - break; - } - } - } - - return $node_data; + return []; } /** @@ -550,179 +209,6 @@ class UWService implements UWServiceInterface { return 'no'; } - /** - * {@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) { - - // Get correct uri, if external just use uri from node - // value, if not, then generate url from uri. - if (UrlHelper::isExternal($link_data[0]['uri'])) { - $return_link_data['uri'] = $link_data[0]['uri']; - } - else { - $return_link_data['uri'] = URL::fromUri($link_data[0]['uri'])->toString(); - } - $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. - $mid = $node->$field_name->getValue(); - - // 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, string $view_mode): 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(); - - // Get the date query parameter. - $date_parameter = $this->requestStack->getCurrentRequest()->query->get('date'); - - // If there is a date query parameter, convert - // to timestamp so we can compare against dates - // in the event. If there is no parameter, set - // the timestamp todays date. - if ($date_parameter) { - $check_date = strtotime($date_parameter['value']); - } - else { - $check_date = strtotime("now"); - } - - // Step through each of the dates and get - // out correct values. - foreach ($dates as $date) { - - // ISTWCMS-5088: we need to ensure that at least - // some dates show on the node page, so let's just - // display them all. - // If not node page, only get dates in the future. - if ($view_mode == 'full') { - - $return_dates[] = $this->UwGetDate($date, 'event'); - } - else { - - // Ensure that the dates are greater than timestamp - // that we generated above. - if ($date['end_value'] > $check_date) { - $return_dates[] = $this->UwGetDate($date, 'event'); - } - } - } - } - - return $return_dates; - } - - /** - * {@inheritDoc} - */ - public function uwGetDate(array $date, string $type): string { - - // The all day case, duration is always 1439. - if ($date['duration'] == '1439') { - $return_date = date('l, F j, Y', $date['value']) . ' (all day)'; - } - else { - - // 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_date = $start_date . ' - ' . $end_date . ' ' . date('T', $date['end_value']); - } - - return $return_date; - } - - /** - * {@inheritDoc} - */ - public function uwGetSources(Node $node, string $field_name): array { - - $return_sources = []; - - if ($node->$field_name) { - // 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} */ @@ -984,119 +470,4 @@ class UWService implements UWServiceInterface { } } - /** - * {@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'], - ]; - } - - return $author; - } - - /** - * {@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. - $terms = []; - - // Step through each of the values which is a - // list of referenced taxonomy terms. - foreach ($values as $term_ref) { - - // Get the term entity, which is the same as - // loading the term. - $term_entity = $term_ref->entity; - - // If there is an entity, set the variable. - if ($term_entity) { - - // If this is a tags term type, we have to include - // url and title. If not just the tag name. - if ($type === 'tags') { - - // 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. - return $terms; - } - } diff --git a/src/Service/UWServiceInterface.php b/src/Service/UWServiceInterface.php index a9c02b6310317fd38c5885b7b0eb62158837bb1d..6641302bc7a9a86fc2accdf3e0567d5d11cd1fd1 100644 --- a/src/Service/UWServiceInterface.php +++ b/src/Service/UWServiceInterface.php @@ -3,7 +3,6 @@ namespace Drupal\uw_cfg_common\Service; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\node\Entity\Node; /** @@ -28,36 +27,6 @@ interface UWServiceInterface { */ public function prepareResponsiveImage(EntityInterface $entity, string $image_style): array; - /** - * Prepares teaser. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $view_mode - * The view mode (i.e. node, teaser, etc). - * @param string $content - * The type of content to get, values are all, header or footer. - * - * @return array - * Array of variables and their values. - */ - public function uwGetNodeContent(Node $node, string $view_mode, string $content = 'all'): array; - - /** - * Gets teaser data. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $view_mode - * The view mode (i.e. node, teaser, etc). - * @param array $content_data - * An array of all the data to get for the teaser. - * - * @return array - * Array of node values. - */ - public function uwGetNodeData(Node $node, string $view_mode, array $content_data): array; - /** * Gets content types that have feature images. * @@ -80,73 +49,6 @@ interface UWServiceInterface { */ public function uwCheckNodeForFeaturedImage(Node $node): string; - /** - * Gets dates from node. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $field_name - * The field name that has the date(s). - * @param string $view_mode - * The view mode of the node. - * - * @return array - * Array of dates. - */ - public function uwGetDates(Node $node, string $field_name, string $view_mode): array; - - /** - * Get a date in the proper format. - * - * @param array $date - * An array of date info. - * @param string $type - * The type of date. - * - * @return string - * A converted date to a string. - */ - public function uwGetDate(array $date, string $type): string; - - /** - * Gets image from node. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $field_name - * The field name that has the date(s). - * - * @return array - * array with image information. - */ - public function uwGetImage(Node $node, string $field_name): array; - - /** - * Gets sources from node. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $field_name - * The field name that has the date(s). - * - * @return array - * Either array with responsive image. - */ - public function uwGetSources(Node $node, string $field_name): array; - - /** - * Gets link info from node. - * - * @param \Drupal\node\Node $node - * Node entity. - * @param string $field_name - * The field name that has the date(s). - * - * @return array - * Array with link info. - */ - public function uwGetLinkInfo(Node $node, string $field_name): array; - /** * A function to get or check the attached sidebar. * @@ -272,43 +174,4 @@ interface UWServiceInterface { */ public function uwMonthNameShort(int $month = NULL); - /** - * A function get the taxonomy terms. - * - * @param array $tids - * An array of term ids (tids). - * @param string $type - * The type of terms to get, if none provided just term name returned. - * - * @return array - * An array of terms with name and link. - */ - public function uwGetTerms(array $tids, string $type = NULL): array; - - /** - * A function to get the footer data for a node/content type. - * - * @param \Drupal\node\Entity\Node $node - * The node object. - * - * @return array - * An array of author name and link. - */ - public function uwGetAuthor(Node $node): array; - - /** - * Function that parses terms and returns a list. - * - * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $values - * List of values for the provided field. - * @param string|null $type - * The type of terms to get, if none provided just term name returned. - * - * @return array - * List of terms with name and link. - * - * @throws \Drupal\Core\Entity\EntityMalformedException - */ - public function uwGetTermsFromEntityField(EntityReferenceFieldItemListInterface $values, string $type = NULL): array; - } diff --git a/src/Service/UwNodeContent.php b/src/Service/UwNodeContent.php new file mode 100644 index 0000000000000000000000000000000000000000..1ce9c2eb511c8d12f83dcf7b9a5bae4c9a377154 --- /dev/null +++ b/src/Service/UwNodeContent.php @@ -0,0 +1,535 @@ +<?php + +namespace Drupal\uw_cfg_common\Service; + +use Drupal\node\Entity\Node; + +/** + * Class UwNodeContent. + * + * Gets the content out of a node. + * + * @package Drupal\uw_cfg_common\Service + */ +class UwNodeContent { + + /** + * The UW node data service. + * + * @var UwNodeData + */ + private $uwNodeData; + + /** + * Default constructor. + * + * @param UwNodeData $uwNodeData + * The UW node data service. + */ + public function __construct(UwNodeData $uwNodeData) { + $this->uwNodeData = $uwNodeData; + } + + /** + * Gets the content of a node. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode. + * @param string $content + * The content to get (either layout builder or summary). + * + * @return array + * Array of content to get from the node. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getNodeContent(Node $node, string $view_mode, string $content): array { + + // Get the flags for the node. + $node_flags = $this->getNodeFlags($node, $view_mode, $content); + + // Setup the node data array, based on flags. + switch ($node->getType()) { + + case 'uw_ct_blog': + $content_data = $this->getBlogContent($node_flags); + break; + + case 'uw_ct_event': + $content_data = $this->getEventContent($node_flags); + break; + + case 'uw_ct_news_item': + $content_data = $this->getNewsContent($node_flags); + break; + + case 'uw_ct_web_page': + $content_data = $this->getWebPageContent($node_flags); + break; + + case 'uw_ct_catalog_item': + $content_data = $this->getCatalogItemContent($node_flags); + break; + + case 'uw_ct_contact': + $content_data = $this->getContactContent($node_flags); + break; + + case 'uw_ct_profile': + $content_data = $this->getProfileContent($node_flags); + break; + } + + return $this->uwNodeData->getNodeData($node, $view_mode, $content_data); + } + + /** + * Get the content types that have hero images. + * + * @return string[] + * Array of content types that can have hero images. + */ + public function getHeroImageContentTypes(): array { + return [ + 'uw_ct_blog' => 'field_uw_hero_image', + 'uw_ct_event' => 'field_uw_hero_image', + 'uw_ct_news_item' => 'field_uw_hero_image', + ]; + } + + /** + * Get the flags for the node. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode. + * @param string $content + * The content to get (layout builder or summary). + * + * @return array + * Array of flags for the node. + */ + public function getNodeFlags(Node $node, string $view_mode, string $content): array { + + // Flags for getting teaser content. + $node_flags['get_header'] = FALSE; + $node_flags['get_footer'] = FALSE; + $node_flags['get_image'] = FALSE; + $node_flags['get_content'] = FALSE; + $node_flags['get_title'] = FALSE; + $node_flags['get_hero'] = FALSE; + $node_flags['get_listing_image'] = FALSE; + + // Setup flags based on teaser content argument. + if ($content == 'all') { + $node_flags['get_header'] = TRUE; + $node_flags['get_footer'] = TRUE; + $node_flags['get_content'] = TRUE; + + if ($view_mode == 'full') { + $node_flags['get_title'] = TRUE; + $node_flags['get_hero'] = TRUE; + } + elseif ($view_mode == 'teaser') { + $node_flags['get_footer'] = FALSE; + $node_flags['get_listing_image'] = TRUE; + $node_flags['get_title'] = TRUE; + } + } + else { + if ($content == 'header') { + $node_flags['get_header'] = TRUE; + $node_flags['get_title'] = TRUE; + $node_flags['get_hero'] = TRUE; + } + + if ($content == 'footer') { + $node_flags['get_footer'] = TRUE; + $node_flags['get_title'] = FALSE; + } + } + + return $node_flags; + } + + /** + * Common elements for content data. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of common elements for content data. + */ + public function setupContentData(array $node_flags): array { + + $content_data['url'] = [ + 'type' => 'url', + ]; + + $content_data['header'] = [ + 'has_children' => TRUE, + ]; + + if ($node_flags['get_title']) { + $content_data['header']['title'] = [ + 'type' => 'title', + ]; + } + + return $content_data; + } + + /** + * Functiont to add to content data array. + * + * @param string $type + * The type of field. + * @param mixed $field_name + * The actual field name(s). + * @param string|null $label + * The label to be used with the field. + * + * @return string[] + * Array to add to the content data. + */ + public function addToContentData(string $type, $field_name, string $label = NULL): array { + return [ + 'type' => $type, + 'field' => $field_name, + 'label' => $label, + ]; + } + + /** + * Get the node content for blog content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getBlogContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the header content. + if ($node_flags['get_header']) { + $content_data['header']['date'] = $this->addToContentData('date', 'field_uw_blog_date'); + $content_data['header']['author'] = $this->addToContentData('author', 'field_author'); + } + + // Get the hero image. + if ($node_flags['get_hero']) { + $content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image'); + } + + // Get the listing image. + if ($node_flags['get_listing_image']) { + $content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_blog_listing_page_image'); + } + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_blog_summary'); + } + + // Setup the footer. + if ($node_flags['get_footer']) { + + $terms = [ + 'field_uw_blog_tags', + 'field_uw_audience', + ]; + + $content_data['footer']['tags'] = $this->addToContentData('terms', $terms); + } + + return $content_data; + } + + /** + * Get the node content for event content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getEventContent(array $node_flags): array { + + // Setup the content data array. + $content_data = $this->setupContentData($node_flags); + + // Setup the header content. + if ($node_flags['get_header']) { + $content_data['header']['date'] = $this->addToContentData('date', 'field_uw_event_date'); + } + + // Get hero image. + if ($node_flags['get_hero']) { + $content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image'); + } + + // Get listing image. + if ($node_flags['get_listing_image']) { + $content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_event_listing_page_img'); + } + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_event_summary'); + } + + // Setup the footer content. + if ($node_flags['get_footer']) { + + $content_data['footer']['additional_info'] = [ + 'has_children' => TRUE, + 'host' => $this->addToContentData('link', 'field_uw_event_host', 'Host'), + 'event_website' => $this->addToContentData('link', 'field_uw_event_website', 'Event website'), + 'cost' => $this->addToContentData('plain_text', 'field_uw_event_cost', 'Cost'), + ]; + + $content_data['footer']['location_info'] = [ + 'has_children' => TRUE, + 'address' => $this->addToContentData('address', 'field_uw_event_location_address', 'Location address'), + 'map' => $this->addToContentData('map', 'field_uw_event_location_coord', 'Location coordinates'), + ]; + + $content_data['footer']['tags'] = $this->addToContentData( + 'terms', + [ + 'field_uw_event_tags', + 'field_uw_audience', + 'field_uw_event_type', + ] + ); + } + + return $content_data; + } + + /** + * Get the node content for news content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getNewsContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the header content. + if ($node_flags['get_header']) { + $content_data['header']['date'] = $this->addToContentData('date', 'field_uw_news_date'); + } + + // Get hero image. + if ($node_flags['get_hero']) { + $content_data['hero_image'] = $this->addToContentData('sources', 'field_uw_hero_image'); + } + + // Get listing image. + if ($node_flags['get_listing_image']) { + $content_data['listing_image'] = $this->addToContentData('sources', 'field_uw_news_listing_page_image'); + } + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_news_summary'); + } + + // Get the footer content. + if ($node_flags['get_footer']) { + $content_data['footer']['tags'] = $this->addToContentData( + 'terms', + [ + 'field_uw_news_tags', + 'field_uw_audience', + ] + ); + } + + return $content_data; + } + + /** + * Get the node content for web page content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getWebPageContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'layout_builder__layout'); + } + + return $content_data; + } + + /** + * Get the node content for catalog item content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getCatalogItemContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_news_summary'); + } + + // Get the footer for catalog items. + if ($node_flags['get_footer']) { + + // Get the catalog terms. + $content_data['footer']['additional_info']['has_children'] = TRUE; + $content_data['footer']['additional_info']['tags'] = $this->addToContentData( + 'catalog_terms', + [ + 'Category' => 'field_uw_catalog_category', + 'Faculty' => 'field_uw_catalog_faculty', + 'Audience' => 'field_uw_audience', + ] + ); + } + + return $content_data; + } + + /** + * Get the node content for catalog item content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getContactContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the header content. + if ($node_flags['get_header']) { + $content_data['header']['position'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_title'); + } + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_news_summary'); + } + + // Get the footer data. + if ($node_flags['get_footer']) { + + // Get the additional info. + $content_data['footer']['additional_info']['has_children'] = TRUE; + $content_data['footer']['additional_info']['info'] = $this->addToContentData('formatted_text', 'field_uw_ct_contact_info'); + + // Get the contact information. + $content_data['footer']['contact_info']['has_children'] = TRUE; + $content_data['footer']['contact_info']['email'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_email'); + $content_data['footer']['contact_info']['phone'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_phone'); + $content_data['footer']['contact_info']['location'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_location', 'Location'); + + // Get the links for the profile. + $content_data['footer']['links']['has_children'] = TRUE; + $content_data['footer']['links']['profile'] = $this->addToContentData('link', 'field_uw_ct_contact_link_profile', 'Link to profile'); + $content_data['footer']['links']['webpage'] = $this->addToContentData('link', 'field_uw_ct_contact_link_persona', 'Link to personal webpage'); + + // Get the contact for, for the profile. + $content_data['footer']['contact_for']['has_children'] = TRUE; + $content_data['footer']['contact_for']['contact'] = $this->addToContentData('plain_text', 'field_uw_ct_contact_contact_for'); + + // Get the groups for the profile. + $content_data['footer']['groups']['has_children'] = TRUE; + $content_data['footer']['groups']['groups'] = $this->addToContentData('terms', ['field_uw_ct_contact_group']); + } + + return $content_data; + } + + /** + * Get the node content for profile content type. + * + * @param array $node_flags + * The flags for the node. + * + * @return array + * Array of content to get from the node. + */ + public function getProfileContent(array $node_flags): array { + + // Get the content data. + $content_data = $this->setupContentData($node_flags); + + // Setup the header content. + if ($node_flags['get_header']) { + $content_data['header']['position'] = $this->addToContentData('plain_text', 'field_uw_ct_profile_title'); + } + + // Setup the actual content. + if ($node_flags['get_content']) { + $content_data['content'] = $this->addToContentData('content', 'field_uw_profile_summary'); + } + + // Get the footer for the profile. + if ($node_flags['get_footer']) { + $content_data['footer']['links']['has_children'] = TRUE; + $content_data['footer']['links']['profile'] = $this->addToContentData('link', 'field_uw_ct_profile_info_link'); + $content_data['footer']['links']['webpage'] = $this->addToContentData('link', 'field_uw_ct_profile_link_persona'); + $content_data['footer']['tags'] = $this->addToContentData( + 'terms', + [ + 'field_uw_ct_profile_type', + ] + ); + } + + return $content_data; + } + + /** + * Gets the most recent date. + * + * @param array $date + * The date. + * @param string $type + * The type of date. + * + * @return string + * The actual date with proper format. + */ + public function getDate(array $date, string $type): string { + return $this->uwNodeData->getDate($date, $type); + } + +} diff --git a/src/Service/UwNodeData.php b/src/Service/UwNodeData.php new file mode 100644 index 0000000000000000000000000000000000000000..ea1e71b6478cba9eb3665ade6ac0ffc758be7ece --- /dev/null +++ b/src/Service/UwNodeData.php @@ -0,0 +1,246 @@ +<?php + +namespace Drupal\uw_cfg_common\Service; + +use Drupal\node\Entity\Node; + +/** + * Class UwNodeData. + * + * UW node data gets all the actual data from a specific node. + * + * @package Drupal\uw_cfg_common\Service + */ +class UwNodeData { + + /** + * UW field value service. + * + * @var \Drupal\uw_cfg_common\Service\UwNodeFieldValue + */ + protected $uwNodeFieldValue; + + /** + * Default constructor. + * + * @param \Drupal\uw_cfg_common\Service\UwNodeFieldValue $uwNodeFieldValue + * Entity Type Manager from core. + */ + public function __construct(UwNodeFieldValue $uwNodeFieldValue) { + $this->uwNodeFieldValue = $uwNodeFieldValue; + } + + /** + * Get out the actual data from a node. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode. + * @param array $content_data + * Array of data to pull from the node. + * + * @return array + * Array of data pulled from the node. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getNodeData(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. + $node_data = []; + + foreach ($content_data as $index => $cdata) { + if ($index == 'footer') { + $node_data['footer'] = $this->getFooterData($node, $view_mode, $cdata); + } + else { + if (isset($cdata['has_children']) && $cdata['has_children']) { + foreach ($cdata as $sub_index => $data) { + if ($sub_index !== 'has_children') { + $node_data[$index][$sub_index] = $this->uwNodeFieldValue->getFieldValue( + $node, + $view_mode, + $data['type'], + $data['field'] ?? NULL + ); + } + } + } + else { + $node_data[$index] = $this->uwNodeFieldValue->getFieldValue( + $node, + $view_mode, + $cdata['type'], + $cdata['field'] ?? NULL + ); + } + } + } + + return $this->cleanNodeData($node_data); + } + + /** + * Get the footer data for the node. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode. + * @param array $content_data + * Array of data to pull from the node. + * + * @return array + * Array of data pulled from the node. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getFooterData(Node $node, string $view_mode, array $content_data): array { + + $node_data = []; + foreach ($content_data as $index => $cdata) { + if (isset($cdata['has_children']) && $cdata['has_children']) { + foreach ($cdata as $sub_index => $data) { + if ($sub_index !== 'has_children') { + $node_data[$index][$sub_index] = $this->uwNodeFieldValue->getFieldValue( + $node, + $view_mode, + $data['type'], + $data['field'] ?? NULL + ); + } + } + } + else { + $node_data[$index] = $this->uwNodeFieldValue->getFieldValue( + $node, + $view_mode, + $cdata['type'], + $cdata['field'] ?? NULL + ); + } + } + return $node_data; + } + + /** + * Function to clean the node data array of nulls. + * + * @param array $node_data + * The array of node data. + * + * @return array + * The cleaned array of node data. + */ + public function cleanNodeData(array $node_data): array { + + // Step through the node data array and check for nulls. + foreach ($node_data as $index => $cdata) { + + // If we are on the footer, clean it by itself, + // since it is 3D array. + if ($index == 'footer') { + $node_data['footer'] = $this->cleanFooterNodeData($node_data['footer']); + } + + // If the element is an array, step through all the + // sub elements and check if null. + if (is_array($cdata)) { + + // Step through each of the children and check if null. + foreach ($cdata as $sub_index => $data) { + + // If still array check all its children. + if (is_array($data)) { + + // Step through each children and if empty, + // unset it. + foreach ($data as $sub_sub_index => $d) { + if ($d == NULL && empty($d)) { + unset($node_data[$index][$sub_index][$sub_sub_index]); + } + } + } + else { + + // If the element is empty, unset it. + if ($data == NULL && empty($data)) { + unset($node_data[$index]); + } + } + } + } + else { + + // If the element is empty or null, unset it. + if ($cdata == NULL || empty($cdata)) { + unset($node_data[$index]); + } + } + } + + return $node_data; + } + + /** + * Function to clean the footer array. + * + * @param array $node_data + * The node data for the footer. + * + * @return array + * The array of data for the footer. + */ + public function cleanFooterNodeData(array $node_data): array { + + // Step through each of the footer elements. + foreach ($node_data as $index => $cdata) { + + // If the element is an array, step through its elements + // and ensure that we have data. + if (is_array($cdata)) { + + // Step through all the sub elements and if it is + // and empty array, unset it. + foreach ($cdata as $sub_index => $data) { + if (empty($data)) { + unset($node_data[$index][$sub_index]); + } + } + + // Now check if the parent is empty and if so + // unset the parent. + if (empty($node_data[$index])) { + unset($node_data[$index]); + } + } + else { + + // If the data is null, unset it. + if ($cdata == NULL) { + unset($node_data[$index]); + } + } + } + + return $node_data; + } + + /** + * Gets the most recent date. + * + * @param array $date + * The date. + * @param string $type + * The type of date. + * + * @return string + * The actual date with proper format. + */ + public function getDate(array $date, string $type): string { + return $this->uwNodeFieldValue->getDate($date, $type); + } + +} diff --git a/src/Service/UwNodeFieldValue.php b/src/Service/UwNodeFieldValue.php new file mode 100644 index 0000000000000000000000000000000000000000..8639d8b124d7b464a2e8bc3d670f3bd1977c7cee --- /dev/null +++ b/src/Service/UwNodeFieldValue.php @@ -0,0 +1,655 @@ +<?php + +namespace Drupal\uw_cfg_common\Service; + +use Drupal\Component\Utility\UrlHelper; +use Drupal\Core\Field\EntityReferenceFieldItemListInterface; +use Drupal\Core\Url; +use Drupal\node\Entity\Node; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Symfony\Component\HttpFoundation\RequestStack; + +/** + * Class UwFieldValue. + * + * Gets the data out from individual fields of a node. + * + * @package Drupal\uw_cfg_common\Service + */ +class UwNodeFieldValue { + + // Date format: "Thursday, December 2, 2021". + const DATE_FORMAT_DATE_ONLY = 'l, F j, Y'; + // Time format: "10:00 AM". + const DATE_FORMAT_TIME_ONLY = 'g:i A'; + // Date and time format: "Thursday, December 2, 2021 10:00 AM". + const DATE_FORMAT_DATE_TIME = 'l, F j, Y g:i A'; + + /** + * Entity type manager from core. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The current request stack. + * + * @var \Symfony\Component\HttpFoundation\RequestStack + */ + protected $requestStack; + + /** + * The UW Service. + * + * @var UWServiceInterface + */ + protected $uwService; + + /** + * Default constructor. + * + * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack + * The current request stack. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + * @param \Drupal\uw_cfg_common\Service\UWServiceInterface $uwService + * The UW Service. + */ + public function __construct(RequestStack $requestStack, EntityTypeManagerInterface $entityTypeManager, UWServiceInterface $uwService) { + $this->requestStack = $requestStack; + $this->entityTypeManager = $entityTypeManager; + $this->uwService = $uwService; + } + + /** + * Function to get the value of a node field. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode of the bnode. + * @param string $type + * The type of field. + * @param mixed $field_name + * The name of the field. + * + * @return array|\Drupal\Core\GeneratedUrl|mixed|string|void|null + * Array of the value of the field. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getFieldValue(Node $node, string $view_mode, string $type, $field_name = NULL) { + + // Address field type. + if ($type == 'address') { + return $this->getAddressField($node, $field_name); + } + + // Author field type. + if ($type == 'author') { + return $this->getAuthor($node); + } + + // Long text field type with a text format. + if ($type == 'formatted_text') { + return $this->getFormattedText($node, $field_name); + } + + // Only content, either layout builder or summary. + if ($type == 'content') { + return $this->getContentField($node, $view_mode, $field_name); + } + + // Office hours field type. + if ($type == 'hours') { + return $node->$field_name->view(); + } + + // Date field type (smart dates). + if ($type == 'date') { + return $this->getDates($node, $field_name, $view_mode); + } + + // Taxonomy terms field type. + if ($type == 'terms') { + return $this->getTermsField($node, $field_name); + } + + // Image field type. + if ($type == 'image') { + return $this->getImage($node, $field_name); + } + + // Link field type. + if ($type == 'link') { + return $this->getLinkInfo($node, $field_name); + } + + // Map (leaflet) field type. + if ($type == 'map') { + return $this->getMapField($node, $field_name); + } + + // Plain text field type (textbox). + if ($type == 'plain_text') { + return $node->$field_name->value; + } + + // Source or hero image field type. + if ($type == 'sources' || $type == 'hero') { + return $this->getSources($node, $field_name); + } + + // Catalog tags, this is a special type of terms, since we + // need to worry about the tabs that go along with them. + if ($type == 'catalog_terms') { + return $this->getCatalogTags($node, $field_name); + } + + // Title of the node. + if ($type == 'title') { + return $node->getTitle(); + } + + // URL of the node. + if ($type == 'url') { + return $node->toUrl()->toString(); + } + } + + /** + * Function to get the formatted text. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $field_name + * The name of the field to get. + * + * @return array + * Render array for formatted text. + */ + public function getFormattedText(Node $node, string $field_name): array { + + // Get the value of the field. + $value = $node->$field_name->value; + + // If the value is not null, then return the + // formatted text render array. + if ($value !== NULL) { + return [ + '#type' => 'processed_text', + '#text' => $value, + '#format' => $node->$field_name->format, + ]; + } + + // If we get here there is no value, so + // return an empty array and our clean + // node data function will handle it. + return []; + } + + /** + * Function to get catalog tags. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param array $field_name + * The field name. + * + * @return array + * Array of values for the field. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getCatalogTags(Node $node, array $field_name): array { + + // Empty arrays so that we don't get undefined + // index errors. + $tabs = []; + $tags = []; + + // Get the entity and values for the catalog, + // which is the taxonomy term catalog. + $catalog_entity = $node->field_uw_catalog_catalog->entity; + $tabs_values = $catalog_entity->field_uw_catalog_tabs_display->getValue(); + + // Setup the array that we can use for in_array, + // which is the tabs to be displayed. + foreach ($tabs_values as $tab_value) { + $tabs[] = $tab_value['value']; + } + + // If there are tabs, then get them. + if (!empty($tabs)) { + foreach ($field_name as $key => $field) { + if (in_array($key, $tabs)) { + $tags_to_add = $this->getTermsFromEntityField($node->$field, 'tags'); + + if (!empty($tags_to_add)) { + $tags[$key] = $this->getTermsFromEntityField($node->$field, 'tags'); + } + } + } + } + + return $tags; + } + + /** + * Prepares image for theme. + * + * @param \Drupal\node\Entity\Node $node + * Node entity. + * @param string $field_name + * Field name. + * + * @return array + * Array of data such as url, alt. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function getImage(Node $node, string $field_name): array { + + $image = []; + + // Get the media id. + $mid = $node->$field_name->getValue(); + + // If there is an image, process it. + if ($mid) { + + // Load in the media item. + /** @var \Drupal\media\Entity\Media $media */ + $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; + } + + /** + * Get the value of a map field. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $field_name + * The field name. + * + * @return array|null + * Array of field value or NULL. + */ + public function getMapField(Node $node, string $field_name) { + + // Set the map initially to null, if there are + // coordinates, then will be replaced. + $map = NULL; + + // If there are coordinates, set the map. + if ($node->$field_name->getValue()) { + $display = [ + 'type' => 'leaflet_formatter_default', + 'label' => 'visually_hidden', + ]; + $map = $node->$field_name->view($display); + } + + return $map; + } + + /** + * Get the value of an content field. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $view_mode + * The view mode. + * @param string $field_name + * The field name. + * + * @return array|null + * Array of field value or NULL. + */ + public function getContentField(Node $node, string $view_mode, string $field_name) { + + // If on the teaser, return the summary field values. + if ($view_mode == 'teaser') { + return $this->getFormattedText($node, $field_name); + } + + return NULL; + } + + /** + * Get the taxonomy terms field(s) value. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param array $field_name + * Array of field names. + * + * @return array + * Array of taxonomy term values. + * + * @throws \Drupal\Core\Entity\EntityMalformedException + */ + public function getTermsField(Node $node, array $field_name): array { + + // Need empty array in case there are no terms. + $tags = []; + + // Step through each of the terms and add to array. + foreach ($field_name as $field) { + $tags = array_merge($tags, $this->getTermsFromEntityField($node->$field, 'tags')); + } + + // Return array of terms. + return $tags; + } + + /** + * Get the value of an address field. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * @param string $field_name + * The field name. + * + * @return mixed + * Array of field value or NULL. + */ + public function getAddressField(Node $node, string $field_name) { + + $address = $node->$field_name->getValue(); + if (isset($address[0])) { + return $address[0]; + } + + return NULL; + } + + /** + * Get the author of the node. + * + * @param \Drupal\node\Entity\Node $node + * The node. + * + * @return array + * Array of the author info. + */ + public function getAuthor(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(), + ]; + } + + // 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(); + + $author['name'] = $author_name; + + if (!empty($link)) { + $author['link'] = $link[0]['uri']; + } + } + + return $author; + } + + /** + * Gets dates from node. + * + * @param \Drupal\node\Entity\Node $node + * Node entity. + * @param string $field_name + * The field name that has the date(s). + * @param string $view_mode + * The view mode of the node. + * + * @return array + * Array of dates. + */ + public function getDates(Node $node, string $field_name, string $view_mode): 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(); + + // Get the date query parameter. + $date_parameter = $this->requestStack->getCurrentRequest()->query->get('date'); + + // If there is a date query parameter, convert + // to timestamp so we can compare against dates + // in the event. If there is no parameter, set + // the timestamp todays date. + if ($date_parameter) { + $check_date = strtotime($date_parameter['value']); + } + else { + $check_date = strtotime("now"); + } + + // Step through each of the dates and get + // out correct values. + foreach ($dates as $date) { + + // ISTWCMS-5088: we need to ensure that at least + // some dates show on the node page, so let's just + // display them all. + // If not node page, only get dates in the future. + if ($view_mode == 'full') { + + $return_dates[] = $this->getDate($date, 'event'); + } + else { + + // Ensure that the dates are greater than timestamp + // that we generated above. + if ($date['end_value'] > $check_date) { + $return_dates[] = $this->getDate($date, 'event'); + } + } + } + } + + return $return_dates; + } + + /** + * Function that parses terms and returns a list. + * + * @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $values + * List of values for the provided field. + * @param string|null $type + * The type of terms to get, if none provided just term name returned. + * + * @return array + * List of terms with name and link. + */ + public function getTermsFromEntityField(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. + $terms = []; + + // Step through each of the values which is a + // list of referenced taxonomy terms. + foreach ($values as $term_ref) { + + // Get the term entity, which is the same as + // loading the term. + $term_entity = $term_ref->entity; + + // If there is an entity, set the variable. + if ($term_entity) { + + // If this is a tags term type, we have to include + // url and title. If not just the tag name. + if ($type === 'tags') { + + // 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. + return $terms; + } + + /** + * Gets sources from node. + * + * @param \Drupal\node\Entity\Node $node + * Node entity. + * @param string $field_name + * The field name that has the date(s). + * + * @return array + * Either array with responsive image. + */ + public function getSources(Node $node, string $field_name): array { + + $return_sources = []; + + if ($node->$field_name) { + // Get the image entity. + $image = $node->$field_name->entity; + + // If there is an image, get the responsive image sources. + if ($image) { + $sources = $this->uwService->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; + } + + /** + * Get a date in the proper format. + * + * @param array $date + * An array of date info. + * @param string $type + * The type of date. + * + * @return string + * A converted date to a string. + */ + public function getDate(array $date, string $type): string { + $return_date = ''; + + if ($type == 'event') { + // If this is the same day, get the date and the start and end times. + if ($date['duration'] < '1439') { + $start_date = date(self::DATE_FORMAT_DATE_TIME, $date['value']); + $end_date = date(self::DATE_FORMAT_TIME_ONLY, $date['end_value']); + + $return_date = $start_date . ' - ' . $end_date . ' ' . date('T', $date['end_value']); + } + // This is not the day, get the start and end date with time. + elseif ($date['duration'] > '1439') { + $start_date = date(self::DATE_FORMAT_DATE_TIME, $date['value']); + $end_date = date(self::DATE_FORMAT_DATE_TIME, $date['end_value']); + + $return_date = $start_date . ' - ' . $end_date . ' ' . date('T', $date['end_value']); + } + // The all date case, duration is always 1439. + else { + $return_date = date(self::DATE_FORMAT_DATE_ONLY, $date['value']) . ' (all day)'; + } + } + return $return_date; + } + + /** + * Gets link info from node. + * + * @param \Drupal\node\Entity\Node $node + * Node entity. + * @param string $field_name + * The field name that has the date(s). + * + * @return array + * Array with link info. + */ + public function getLinkInfo(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) { + + // Step through each link and get the info. + foreach ($link_data as $ld) { + + // Get correct uri, if external just use uri from node + // value, if not, then generate url from uri. + if (UrlHelper::isExternal($ld['uri'])) { + $link_info['uri'] = $ld['uri']; + } + else { + $link_info['uri'] = URL::fromUri($ld['uri'])->toString(); + } + $link_info['title'] = $ld['title']; + + $return_link_data[] = $link_info; + } + } + + return $return_link_data; + } + +} diff --git a/uw_cfg_common.services.yml b/uw_cfg_common.services.yml index d98dafb91c967ea1f5b5fce5a745e38ff0418093..e787861646999974cfc12aa360a4a5f27c2265db 100644 --- a/uw_cfg_common.services.yml +++ b/uw_cfg_common.services.yml @@ -5,6 +5,15 @@ services: uw_cfg_common.uw_service: class: Drupal\uw_cfg_common\Service\UWService arguments: ['@entity_type.manager', '@database', '@simplify_menu.menu_items', '@path_alias.manager', '@request_stack'] + uw_cfg_common.uw_node_data: + class: Drupal\uw_cfg_common\Service\UwNodeData + arguments: ['@uw_cfg_common.uw_node_field_value'] + uw_cfg_common.uw_node_content: + class: Drupal\uw_cfg_common\Service\UwNodeContent + arguments: ['@uw_cfg_common.uw_node_data'] + uw_cfg_common.uw_node_field_value: + class: Drupal\uw_cfg_common\Service\UwNodeFieldValue + arguments: ['@request_stack', '@entity_type.manager', '@uw_cfg_common.uw_service'] uw_cfg_common.route_subscriber: class: Drupal\uw_cfg_common\Routing\UwNodeAccessRouteSubscriber tags: