Newer
Older
Eric Bremner
committed
<?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;
Eric Bremner
committed
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 {
Eric Bremner
committed
/**
* Entity type manager from core.
Eric Bremner
committed
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
Eric Bremner
committed
*/
protected $entityTypeManager;
Eric Bremner
committed
/**
* The current request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The UW Service.
*
* @var UWServiceInterface
*/
protected $uwService;
Eric Bremner
committed
/**
* Default constructor.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The current request stack.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
Eric Bremner
committed
* @param \Drupal\uw_cfg_common\Service\UWServiceInterface $uwService
* The UW Service.
*/
public function __construct(RequestStack $requestStack, EntityTypeManagerInterface $entityTypeManager, UWServiceInterface $uwService) {
Eric Bremner
committed
$this->requestStack = $requestStack;
$this->entityTypeManager = $entityTypeManager;
Eric Bremner
committed
$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);
Eric Bremner
committed
}
// 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);
Eric Bremner
committed
}
// Only content, either layout builder or summary.
if ($type == 'content') {
return $this->getContentField($node, $view_mode, $field_name);
Eric Bremner
committed
}
// 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);
Eric Bremner
committed
}
// Image field type.
if ($type == 'image') {
return $this->getImage($node, $field_name);
Eric Bremner
committed
}
// 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);
Eric Bremner
committed
}
// 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);
}
Eric Bremner
committed
// Title of the node.
if ($type == 'title') {
return $node->getTitle();
}
Eric Bremner
committed
// URL of the node.
if ($type == 'url') {
return $node->toUrl()->toString();
}
}
Eric Bremner
committed
/**
* 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 {
return [
'#type' => 'processed_text',
'#text' => $node->$field_name->value,
'#format' => $node->$field_name->format,
];
}
/**
* 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'];
}
Eric Bremner
committed
// 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');
Eric Bremner
committed
if (!empty($tags_to_add)) {
$tags[$key] = $this->getTermsFromEntityField($node->$field, 'tags');
Eric Bremner
committed
}
}
}
}
return $tags;
}
Eric Bremner
committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/**
* {@inheritDoc}
*/
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.
$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 mixed
* 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);
Eric Bremner
committed
}
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 mixed
* 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);
Eric Bremner
committed
}
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
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 taxomoy 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];
Eric Bremner
committed
}
Eric Bremner
committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
}
/**
* 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(),
'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;
}
/**
* 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 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.
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
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 {
// 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;
}
/**
* 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;
}
}