Skip to content

Commit 9239248

Browse files
authored
Merge branch 'develop' into feature/eventdatabasen-v2
2 parents b9c2596 + 571cc61 commit 9239248

File tree

5 files changed

+207
-69
lines changed

5 files changed

+207
-69
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.
66

77
- [#231](https://github.com/os2display/display-api-service/pull/231)
88
- Adds new feed source: Eventdatabasen v2.
9+
- [#233](https://github.com/os2display/display-api-service/pull/233)
10+
- Added calendar api feed source tests for modifiers.
11+
- Changed to use PCRE pattern instead of custom pattern building and fixed modifier bugs for calendar api feed source.
12+
13+
## [2.2.0] - 2025-03-17
14+
915
- [#229](https://github.com/os2display/display-api-service/pull/229)
1016
- Adds options to set paths to component and admin files from path to the json config file.
1117
- [#225](https://github.com/os2display/display-api-service/pull/225)
@@ -20,6 +26,11 @@ All notable changes to this project will be documented in this file.
2026
- Adds create, update, delete operations to feed-source endpoint.
2127
- Adds data validation for feed source.
2228

29+
## [2.1.4] - 2025-01-14
30+
31+
- [#230](https://github.com/os2display/display-api-service/pull/230)
32+
- Adds options to set paths to component and admin files from path to the json config file.
33+
2334
## [2.1.3] - 2024-10-25
2435

2536
- [#220](https://github.com/os2display/display-api-service/pull/220)

docs/calender-api-feed.md

+13-17
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,19 @@ Modifiers can be set up to modify the output of the feed.
136136

137137
Two types of modifiers are available:
138138

139-
* EXCLUDE_IF_TITLE_NOT_CONTAINS: Removes entries from the feed if the title not contain the trigger word.
140-
* REPLACE_TITLE_IF_CONTAINS: Changes the title if it contains the trigger word.
139+
* EXCLUDE_IF_TITLE_NOT_CONTAINS: Removes entries from the feed if the title does not contain the pattern.
140+
* REPLACE_TITLE_IF_CONTAINS: Changes the title if it contains the pattern.
141141

142142
Parameters:
143143

144144
* type: EXCLUDE_IF_TITLE_NOT_CONTAINS or REPLACE_TITLE_IF_CONTAINS
145145
* id: Unique identifier for the modifier.
146146
* title: Display name when showing the modifier in the admin.
147-
* description: Help text for the modifier.
147+
* description: Description of the modifier.
148148
* activateInFeed: Should this filter be optional? If false the rule will always apply.
149-
* trigger: The string that should trigger the modifier.
150-
* replacement: The string to replace the title with.
151149
* removeTrigger: Should the trigger word be filtered from the title?
152-
* caseSensitive: Should the trigger word be case-sensitive?
150+
* pattern: The PCRE regular expression. See <https://www.php.net/manual/en/reference.pcre.pattern.syntax.php>.
151+
* replacement: The string to replace the title with. See <https://www.php.net/manual/en/function.preg-replace.php>.
153152

154153
Examples of modifiers:
155154

@@ -161,29 +160,26 @@ Examples of modifiers:
161160
"title": "Vis kun begivenheder med (liste) i titlen.",
162161
"description": "Denne mulighed fjerner begivenheder, der IKKE har (liste) i titlen. Den fjerner også (liste) fra titlen.",
163162
"activateInFeed": true,
164-
"trigger": "(liste)",
165-
"removeTrigger": true,
166-
"caseSensitive": false
163+
"pattern": "\/\\(liste\\)\/i",
164+
"removeTrigger": true
167165
},
168166
{
169167
"type": "REPLACE_TITLE_IF_CONTAINS",
170-
"id": "replaceIfContainsOptaget",
171168
"activateInFeed": false,
172-
"trigger": "(optaget)",
169+
"id": "replaceIfContainsOptaget",
170+
"pattern": "\/\\(optaget\\)\/i",
173171
"replacement": "Optaget",
174-
"removeTrigger": true,
175-
"caseSensitive": false
172+
"removeTrigger": true
176173
},
177174
{
178175
"type": "REPLACE_TITLE_IF_CONTAINS",
179-
"id": "onlyShowAsOptaget",
180176
"activateInFeed": true,
177+
"id": "onlyShowAsOptaget",
181178
"title": "Overskriv alle titler med Optaget",
182179
"description": "Denne mulighed viser alle titler som Optaget.",
183-
"trigger": "",
180+
"pattern": "\/\/",
184181
"replacement": "Optaget",
185-
"removeTrigger": false,
186-
"caseSensitive": false
182+
"removeTrigger": false
187183
}
188184
]
189185
```

src/Feed/CalendarApiFeedType.php

+64-52
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ public function __construct(
6363
public function getData(Feed $feed): array
6464
{
6565
try {
66-
$results = [];
67-
6866
$configuration = $feed->getConfiguration();
6967

7068
$enabledModifiers = $configuration['enabledModifiers'] ?? [];
@@ -76,62 +74,28 @@ public function getData(Feed $feed): array
7674
}
7775

7876
$resources = $configuration['resources'];
79-
foreach ($resources as $resource) {
80-
$events = $this->getResourceEvents($resource);
81-
82-
/** @var CalendarEvent $event */
83-
foreach ($events as $event) {
84-
$title = $event->title;
85-
86-
// Modify title according to event modifiers.
87-
foreach ($this->eventModifiers as $modifier) {
88-
// Make it configurable in the Feed if the modifiers should be enabled.
89-
if ($modifier['activateInFeed'] && !in_array($modifier['id'], $enabledModifiers)) {
90-
continue;
91-
}
92-
93-
if (self::EXCLUDE_IF_TITLE_NOT_CONTAINS == $modifier['type']) {
94-
$match = preg_match('/'.$modifier['trigger'].'/'.(!$modifier['caseSensitive'] ? 'i' : ''), $title);
95-
96-
if ($modifier['removeTrigger']) {
97-
$title = str_replace($modifier['trigger'], '', $title);
98-
}
99-
100-
if (!$match) {
101-
continue;
102-
}
103-
}
104-
105-
if (self::REPLACE_TITLE_IF_CONTAINS == $modifier['type']) {
106-
$match = preg_match('/'.$modifier['trigger'].'/'.(!$modifier['caseSensitive'] ? 'i' : ''), $title);
107-
108-
if ($modifier['removeTrigger']) {
109-
$title = str_replace($modifier['trigger'], '', $title);
110-
}
111-
112-
if ($match) {
113-
$title = $modifier['replacement'];
114-
}
115-
}
116-
}
11777

118-
$title = trim($title);
78+
$events = [];
11979

120-
$results[] = [
121-
'id' => Ulid::generate(),
122-
'title' => $title,
123-
'startTime' => $event->startTimeTimestamp,
124-
'endTime' => $event->endTimeTimestamp,
125-
'resourceTitle' => $event->resourceDisplayName,
126-
'resourceId' => $event->resourceId,
127-
];
128-
}
80+
foreach ($resources as $resource) {
81+
$events += $this->getResourceEvents($resource);
12982
}
13083

84+
$modifiedResults = static::applyModifiersToEvents($events, $this->eventModifiers, $enabledModifiers);
85+
86+
$resultsAsArray = array_map(fn (CalendarEvent $event) => [
87+
'id' => Ulid::generate(),
88+
'title' => $event->title,
89+
'startTime' => $event->startTimeTimestamp,
90+
'endTime' => $event->endTimeTimestamp,
91+
'resourceTitle' => $event->resourceDisplayName,
92+
'resourceId' => $event->resourceId,
93+
], $modifiedResults);
94+
13195
// Sort bookings by start time.
132-
usort($results, fn (array $a, array $b) => $a['startTime'] > $b['startTime'] ? 1 : -1);
96+
usort($resultsAsArray, fn (array $a, array $b) => $a['startTime'] > $b['startTime'] ? 1 : -1);
13397

134-
return $results;
98+
return $resultsAsArray;
13599
} catch (\Throwable $throwable) {
136100
$this->logger->error('{code}: {message}', [
137101
'code' => $throwable->getCode(),
@@ -142,6 +106,54 @@ public function getData(Feed $feed): array
142106
return [];
143107
}
144108

109+
public static function applyModifiersToEvents(array $events, array $eventModifiers, array $enabledModifiers): array
110+
{
111+
$results = [];
112+
113+
/** @var CalendarEvent $event */
114+
foreach ($events as $event) {
115+
$title = $event->title;
116+
117+
// Modify title according to event modifiers.
118+
foreach ($eventModifiers as $modifier) {
119+
// Make it configurable in the Feed if the modifiers should be enabled.
120+
if ($modifier['activateInFeed'] && !in_array($modifier['id'], $enabledModifiers)) {
121+
continue;
122+
}
123+
124+
$pattern = $modifier['pattern'];
125+
126+
if (self::EXCLUDE_IF_TITLE_NOT_CONTAINS == $modifier['type']) {
127+
$match = preg_match($pattern, $title);
128+
129+
if (!$match) {
130+
continue 2;
131+
}
132+
133+
if ($modifier['removeTrigger']) {
134+
$title = preg_replace($pattern, '', $title);
135+
}
136+
}
137+
138+
if (self::REPLACE_TITLE_IF_CONTAINS == $modifier['type']) {
139+
$match = preg_match($pattern, $title);
140+
141+
if ($match) {
142+
$title = $modifier['replacement'];
143+
}
144+
}
145+
}
146+
147+
$title = trim($title);
148+
149+
$event->title = $title;
150+
151+
$results[] = $event;
152+
}
153+
154+
return $results;
155+
}
156+
145157
/**
146158
* {@inheritDoc}
147159
*/
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests\Feed;
6+
7+
use App\Model\CalendarEvent;
8+
9+
class CalendarApiFeedTypeData
10+
{
11+
public array $events = [];
12+
public array $modifiers = [];
13+
14+
public function __construct()
15+
{
16+
$this->events[] = new CalendarEvent(
17+
'id1',
18+
'title1',
19+
1,
20+
2,
21+
'resourse1',
22+
'Resource 1'
23+
);
24+
$this->events[] = new CalendarEvent(
25+
'id2',
26+
'title2 (optaget)',
27+
3,
28+
4,
29+
'resourse1',
30+
'Resource 1'
31+
);
32+
$this->events[] = new CalendarEvent(
33+
'id3',
34+
'title3 (lISTe)',
35+
5,
36+
6,
37+
'resourse1',
38+
'Resource 1'
39+
);
40+
$this->events[] = new CalendarEvent(
41+
'id4',
42+
'title4 (lISTe) (optaGET)',
43+
7,
44+
8,
45+
'resourse1',
46+
'Resource 1'
47+
);
48+
49+
$this->modifiers[] = [
50+
'type' => 'EXCLUDE_IF_TITLE_NOT_CONTAINS',
51+
'id' => 'excludeIfNotContainsListe',
52+
'title' => 'Vis kun begivenheder med (liste) i titlen.',
53+
'description' => 'Denne mulighed fjerner begivenheder, der IKKE har (liste) i titlen. Den fjerner også (liste) fra titlen.',
54+
'activateInFeed' => true,
55+
'pattern' => '/\(liste\)/i',
56+
'removeTrigger' => true,
57+
];
58+
59+
$this->modifiers[] = [
60+
'type' => 'REPLACE_TITLE_IF_CONTAINS',
61+
'activateInFeed' => false,
62+
'id' => 'replaceIfContainsOptaget',
63+
'pattern' => '/\(optaget\)/i',
64+
'replacement' => 'Optaget',
65+
'removeTrigger' => true,
66+
];
67+
68+
$this->modifiers[] = [
69+
'type' => 'REPLACE_TITLE_IF_CONTAINS',
70+
'activateInFeed' => true,
71+
'id' => 'onlyShowAsOptaget',
72+
'title' => 'Overskriv alle titler med Optaget',
73+
'description' => 'Denne mulighed viser alle titler som Optaget.',
74+
'pattern' => '//',
75+
'replacement' => 'Optaget',
76+
'removeTrigger' => false,
77+
];
78+
}
79+
}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests\Feed;
6+
7+
use App\Feed\CalendarApiFeedType;
8+
use App\Tests\AbstractBaseApiTestCase;
9+
10+
class CalendarApiFeedTypeTest extends AbstractBaseApiTestCase
11+
{
12+
public function testApplyModifiersToEvents(): void
13+
{
14+
$data = new CalendarApiFeedTypeData();
15+
16+
$result = CalendarApiFeedType::applyModifiersToEvents($data->events, $data->modifiers, ['excludeIfNotContainsListe']);
17+
18+
$this->assertEquals(2, count($result));
19+
$this->assertEquals('title3', $result[0]->title);
20+
$this->assertEquals('Optaget', $result[1]->title);
21+
22+
$data = new CalendarApiFeedTypeData();
23+
24+
$result = CalendarApiFeedType::applyModifiersToEvents($data->events, $data->modifiers, ['onlyShowAsOptaget']);
25+
26+
$this->assertEquals(4, count($result));
27+
$this->assertEquals('Optaget', $result[0]->title);
28+
$this->assertEquals('Optaget', $result[1]->title);
29+
$this->assertEquals('Optaget', $result[2]->title);
30+
$this->assertEquals('Optaget', $result[3]->title);
31+
32+
$data = new CalendarApiFeedTypeData();
33+
34+
$result = CalendarApiFeedType::applyModifiersToEvents($data->events, $data->modifiers, ['excludeIfNotContainsListe', 'onlyShowAsOptaget']);
35+
36+
$this->assertEquals(2, count($result));
37+
$this->assertEquals('Optaget', $result[0]->title);
38+
$this->assertEquals('Optaget', $result[1]->title);
39+
}
40+
}

0 commit comments

Comments
 (0)