-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creating a legacy Redia RSS feed for events. DDFHER-60
This feed is needed for some legacy apps to continue working. It will not be updated in the future - rather, this is a 1-1 recreation of the old feed. As I've made a custom redia legacy module, i've also moved the legacy opening hours REST api into this module.
- Loading branch information
Showing
11 changed files
with
380 additions
and
2 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
config/sync/core.entity_view_display.media.image.redia_feed_large.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
uuid: 014a5ed5-1c85-432f-a1b8-3814869178fd | ||
langcode: en | ||
status: true | ||
dependencies: | ||
config: | ||
- core.entity_view_mode.media.redia_feed_large | ||
- field.field.media.image.field_byline | ||
- field.field.media.image.field_media_image | ||
- image.style.redia_feed_large | ||
- media.type.image | ||
module: | ||
- image | ||
id: media.image.redia_feed_large | ||
targetEntityType: media | ||
bundle: image | ||
mode: redia_feed_large | ||
content: | ||
field_media_image: | ||
type: image | ||
label: hidden | ||
settings: | ||
image_link: '' | ||
image_style: redia_feed_large | ||
image_loading: | ||
attribute: lazy | ||
third_party_settings: { } | ||
weight: 0 | ||
region: content | ||
hidden: | ||
created: true | ||
field_byline: true | ||
langcode: true | ||
name: true | ||
search_api_excerpt: true | ||
thumbnail: true | ||
uid: true |
36 changes: 36 additions & 0 deletions
36
config/sync/core.entity_view_display.media.image.redia_feed_small.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
uuid: 7cd49745-6747-4b76-b64a-f3e2a22a338e | ||
langcode: en | ||
status: true | ||
dependencies: | ||
config: | ||
- core.entity_view_mode.media.redia_feed_small | ||
- field.field.media.image.field_byline | ||
- field.field.media.image.field_media_image | ||
- image.style.redia_feed_small | ||
- media.type.image | ||
module: | ||
- image | ||
id: media.image.redia_feed_small | ||
targetEntityType: media | ||
bundle: image | ||
mode: redia_feed_small | ||
content: | ||
field_media_image: | ||
type: image | ||
label: hidden | ||
settings: | ||
image_link: '' | ||
image_style: redia_feed_small | ||
image_loading: | ||
attribute: lazy | ||
third_party_settings: { } | ||
weight: 0 | ||
region: content | ||
hidden: | ||
created: true | ||
field_byline: true | ||
langcode: true | ||
name: true | ||
search_api_excerpt: true | ||
thumbnail: true | ||
uid: true |
11 changes: 11 additions & 0 deletions
11
config/sync/core.entity_view_mode.media.redia_feed_large.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
uuid: 74eba980-7ec0-4b81-a6da-5c33830b08d9 | ||
langcode: en | ||
status: true | ||
dependencies: | ||
module: | ||
- media | ||
id: media.redia_feed_large | ||
label: 'Redia feed - large' | ||
description: '' | ||
targetEntityType: media | ||
cache: true |
11 changes: 11 additions & 0 deletions
11
config/sync/core.entity_view_mode.media.redia_feed_small.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
uuid: fd0b39a0-f244-4d82-af84-54c63cf451bc | ||
langcode: en | ||
status: true | ||
dependencies: | ||
module: | ||
- media | ||
id: media.redia_feed_small | ||
label: 'Redia feed - small' | ||
description: '' | ||
targetEntityType: media | ||
cache: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
uuid: 923e70e6-ea34-446d-ae06-2f6ac0ac4f00 | ||
langcode: en | ||
status: true | ||
dependencies: { } | ||
name: redia_feed_large | ||
label: 'Redia feed large' | ||
effects: | ||
71f3eb2a-c6f8-4a85-a16f-651a6e43239e: | ||
uuid: 71f3eb2a-c6f8-4a85-a16f-651a6e43239e | ||
id: image_scale | ||
weight: 1 | ||
data: | ||
width: 2000 | ||
height: null | ||
upscale: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
uuid: 33f9623f-9eea-4b05-8e9c-f1d3ac224119 | ||
langcode: en | ||
status: true | ||
dependencies: { } | ||
name: redia_feed_small | ||
label: 'Redia feed small' | ||
effects: | ||
2cd37185-a9d4-43e1-ba81-66b73d18cae2: | ||
uuid: 2cd37185-a9d4-43e1-ba81-66b73d18cae2 | ||
id: image_scale | ||
weight: 1 | ||
data: | ||
width: 220 | ||
height: null | ||
upscale: true |
9 changes: 9 additions & 0 deletions
9
web/modules/custom/dpl_redia_legacy/dpl_redia_legacy.info.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name: "DPL Redia Legacy feeds" | ||
type: module | ||
description: "Various legacy feeds, used for the Redia App." | ||
package: DPL | ||
core_version_requirement: ^10 | ||
|
||
dependencies: | ||
- dpl_opening_hours:dpl_opening_hours | ||
- drupal:drupal_typed |
9 changes: 9 additions & 0 deletions
9
web/modules/custom/dpl_redia_legacy/dpl_redia_legacy.routing.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
dpl_redia_legacy.events: | ||
path: '/ding-redia-rss/event' | ||
defaults: | ||
_controller: '\Drupal\dpl_redia_legacy\Controller\RssFeeds\EventsController::getFeed' | ||
_title: 'Redia APP Event' | ||
requirements: | ||
_permission: 'access content' | ||
options: | ||
_format: 'xml' | ||
234 changes: 234 additions & 0 deletions
234
web/modules/custom/dpl_redia_legacy/src/Controller/RssFeeds/EventsController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
<?php | ||
|
||
namespace Drupal\dpl_redia_legacy\Controller\RssFeeds; | ||
|
||
use Drupal\Core\Controller\ControllerBase; | ||
use Drupal\Core\Datetime\DrupalDateTime; | ||
use Drupal\Core\Field\FieldItemListInterface; | ||
use Drupal\Core\File\FileUrlGeneratorInterface; | ||
use Drupal\Core\Url; | ||
use Drupal\file\FileInterface; | ||
use Drupal\image\ImageStyleInterface; | ||
use Drupal\media\MediaInterface; | ||
use Drupal\recurring_events\Entity\EventInstance; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use function Safe\filesize; | ||
use function Safe\getimagesize; | ||
|
||
/** | ||
* Building a Redia-legacy RSS feed, showing eventinstances. | ||
*/ | ||
class EventsController extends ControllerBase { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function __construct( | ||
protected FileUrlGeneratorInterface $fileUrlGenerator, | ||
protected RequestStack $requestStack, | ||
) {} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function create(ContainerInterface $container): static { | ||
return new static( | ||
$container->get('file_url_generator'), | ||
$container->get('request_stack'), | ||
|
||
); | ||
} | ||
|
||
/** | ||
* Getting the RSS/XML feed of the items. | ||
*/ | ||
public function getFeed(): Response { | ||
$items = $this->getItems(); | ||
|
||
$rss_content = $this->buildRss($items); | ||
|
||
$response = new Response(); | ||
$response->setContent($rss_content); | ||
$response->headers->set('Content-Type', 'application/rss+xml'); | ||
return $response; | ||
} | ||
|
||
/** | ||
* Loading events, and turning it into a simple array of relevant values. | ||
* | ||
* @return array<mixed> | ||
* An array of necessary item fields, used in buildRss(). | ||
*/ | ||
private function getItems(): array { | ||
|
||
$storage = $this->entityTypeManager()->getStorage('eventinstance'); | ||
$query = $storage->getQuery() | ||
->condition('status', TRUE) | ||
->accessCheck(TRUE) | ||
->sort('date.value'); | ||
|
||
$ids = $query->execute(); | ||
|
||
$events = EventInstance::loadMultiple($ids); | ||
|
||
$items = []; | ||
|
||
foreach ($events as $event) { | ||
/** @var \Drupal\node\NodeInterface[] $branches */ | ||
$branches = $event->get('branch')->referencedEntities(); | ||
$branch = reset($branches); | ||
$event_dates = $event->get('date')->getValue(); | ||
$changed_date = DrupalDateTime::createFromFormat('U', strval($event->getChangedTime())); | ||
|
||
$items[] = [ | ||
'title' => $event->label(), | ||
'description' => $this->getEventDescription($event), | ||
'author' => $event->getOwner()->get('field_author_name')->getString(), | ||
'id' => $event->id(), | ||
'date' => $changed_date->format('r'), | ||
'promoted' => FALSE, | ||
'subtitle' => $event->get('event_description')->getString(), | ||
'start_time' => $event_dates[0]['value'] ?? NULL, | ||
'end_time' => $event_dates[0]['end_value'] ?? NULL, | ||
'media' => $this->getEventImageFields($event, 'redia_feed_large'), | ||
'media_thumbnail' => $this->getEventImageFields($event, 'redia_feed_small'), | ||
'branch' => [ | ||
'label' => $branch ? $branch->label() : NULL, | ||
'id' => $branch ? $branch->id() : NULL, | ||
], | ||
]; | ||
} | ||
|
||
return $items; | ||
} | ||
|
||
/** | ||
* Turning event image into fields that Redia understands. | ||
* | ||
* @return array<mixed>|null | ||
* The fields that Redia understands (or nothing). | ||
*/ | ||
private function getEventImageFields(EventInstance $event, string $image_style) { | ||
$media_field = $event->get('event_image'); | ||
|
||
if (!($media_field instanceof FieldItemListInterface)) { | ||
return NULL; | ||
} | ||
|
||
$media = $media_field->referencedEntities()[0] ?? NULL; | ||
$file_field_name = 'field_media_image'; | ||
|
||
if (!($media instanceof MediaInterface) || !$media->hasField($file_field_name)) { | ||
return NULL; | ||
} | ||
|
||
// @phpstan-ignore-next-line PHPStan does not know that entity is available. | ||
$file = $media->get($file_field_name)->first()?->entity; | ||
|
||
if (!($file instanceof FileInterface)) { | ||
return NULL; | ||
} | ||
|
||
$file_uri = $file->getFileUri(); | ||
$style = $this->entityTypeManager()->getStorage('image_style')->load($image_style); | ||
|
||
if (empty($file_uri) || !($style instanceof ImageStyleInterface)) { | ||
return NULL; | ||
} | ||
|
||
$image_url = $style->buildUrl($file_uri); | ||
$image_sizes = getimagesize($file_uri); | ||
$file_size = filesize($file_uri); | ||
|
||
return [ | ||
// Generating a unique MD5. | ||
'md5' => md5($image_url . $file_size), | ||
'url' => $image_url, | ||
'type' => $file->getMimeType(), | ||
'size' => filesize($file_uri), | ||
'width' => $image_sizes[0] ?? NULL, | ||
'height' => $image_sizes[1] ?? NULL, | ||
]; | ||
} | ||
|
||
/** | ||
* Getting the first paragraph as text, to use as description. | ||
*/ | ||
private function getEventDescription(EventInstance $event): ?string { | ||
/** @var \Drupal\paragraphs\ParagraphInterface[] $paragraphs */ | ||
$paragraphs = $event->get('event_paragraphs')->referencedEntities(); | ||
|
||
foreach ($paragraphs as $paragraph) { | ||
if ($paragraph->bundle() === 'text_body') { | ||
return $paragraph->get('field_body')->getValue()[0]['value'] ?? NULL; | ||
} | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
/** | ||
* Building the actual RSS feed, from the items and site information. | ||
* | ||
* @param array<mixed> $items | ||
* See $this->getItems();. | ||
*/ | ||
private function buildRss(array $items): string { | ||
$config = $this->config('system.site'); | ||
$site_title = $config->get('name'); | ||
$site_url = $this->requestStack->getCurrentRequest()?->getSchemeAndHttpHost(); | ||
$feed_url = Url::fromRoute('dpl_redia_legacy.events'); | ||
$feed_url->setAbsolute(); | ||
$feed_url = $feed_url->toString(); | ||
|
||
$current_date = new DrupalDateTime(); | ||
$date = $current_date->format('r'); | ||
|
||
$rss_feed = '<?xml version="1.0" encoding="UTF-8"?>'; | ||
$rss_feed .= '<rss version="2.0" xml:base="' . $site_url . '" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:content-rss="http://xml.redia.dk/rss">'; | ||
$rss_feed .= '<channel>'; | ||
$rss_feed .= "<title>$site_title</title>"; | ||
$rss_feed .= "<link>$site_url</link>"; | ||
$rss_feed .= '<atom:link rel="self" href="' . $feed_url . '" />'; | ||
$rss_feed .= '<language>da</language>'; | ||
$rss_feed .= "<pubDate>$date</pubDate>"; | ||
$rss_feed .= "<lastBuildDate>$date</lastBuildDate>"; | ||
|
||
foreach ($items as $item) { | ||
$rss_feed .= '<item>'; | ||
$rss_feed .= "<title>{$item['title']}</title>"; | ||
$rss_feed .= "<description>{$item['description']}</description>"; | ||
$rss_feed .= "<author>{$item['author']}</author>"; | ||
$rss_feed .= "<guid isPermaLink=\"false\">{$item['id']}</guid>"; | ||
$rss_feed .= "<pubDate>{$item['date']}</pubDate>"; | ||
$rss_feed .= "<source url=\"$feed_url\">$site_title</source>"; | ||
$rss_feed .= "<media:content url=\"{$item['media']['url']}\" fileSize=\"{$item['media']['size']}\" | ||
type=\"{$item['media']['type']}\" contentmedium=\"image\" | ||
width=\"{$item['media']['width']}\" height=\"{$item['media']['height']}\"> | ||
<media:hash algo=\"md5\">{$item['media']['md5']}</media:hash> | ||
</media:content>"; | ||
|
||
$rss_feed .= "<media:thumbnail url=\"{$item['media_thumbnail']['url']}\" | ||
width=\"{$item['media']['width']}\" height=\"{$item['media']['height']}\" />"; | ||
|
||
$rss_feed .= "<content-rss:subheadline>{$item['subtitle']}</content-rss:subheadline>"; | ||
$rss_feed .= "<content-rss:arrangement-starttime>{$item['start_time']}</content-rss:arrangement-starttime>"; | ||
$rss_feed .= "<content-rss:arrangement-endtime>{$item['end_time']}</content-rss:arrangement-endtime>"; | ||
$rss_feed .= "<content-rss:arrangement-location>{$item['branch']['label']}</content-rss:arrangement-location>"; | ||
$rss_feed .= "<content-rss:library-id>{$item['branch']['id']}</content-rss:library-id>"; | ||
|
||
$promoted_title = $item['promoted'] ? 'Sandt' : 'Falsk'; | ||
$rss_feed .= "<content-rss:promoted>$promoted_title</content-rss:promoted>"; | ||
|
||
$rss_feed .= '</item>'; | ||
} | ||
|
||
$rss_feed .= '</channel>'; | ||
$rss_feed .= '</rss>'; | ||
|
||
return $rss_feed; | ||
} | ||
|
||
} |
Oops, something went wrong.