2025-09-09 12:07:53 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace davigil\sources;
|
|
|
|
|
|
|
|
|
|
require_once('helpers/string.php');
|
|
|
|
|
require_once('helpers/cache.php');
|
|
|
|
|
require_once('helpers/pit.php');
|
|
|
|
|
require_once('helpers/ics.php');
|
2025-09-09 23:17:19 +02:00
|
|
|
require_once('model.php');
|
2025-09-09 12:07:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
class class_source_ics_feed
|
|
|
|
|
implements interface_source
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
private string $url;
|
|
|
|
|
|
|
|
|
|
|
2025-09-09 19:43:23 +02:00
|
|
|
/**
|
|
|
|
|
*/
|
2025-09-09 23:17:19 +02:00
|
|
|
private ?int $lifetime;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
private bool $combine;
|
2025-09-09 19:43:23 +02:00
|
|
|
|
|
|
|
|
|
2025-09-09 12:07:53 +02:00
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(
|
2025-09-09 19:43:23 +02:00
|
|
|
string $url,
|
2025-09-09 23:17:19 +02:00
|
|
|
?int $lifetime,
|
|
|
|
|
bool $combine
|
2025-09-09 12:07:53 +02:00
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
$this->url = $url;
|
2025-09-09 23:17:19 +02:00
|
|
|
$this->lifetime = $lifetime;
|
|
|
|
|
$this->combine = $combine;
|
|
|
|
|
$this->cache_file = \davigil\helpers\call\convey(
|
2025-09-09 12:07:53 +02:00
|
|
|
new \davigil\helpers\cache\class_cache_file('data'),
|
2025-09-09 23:17:19 +02:00
|
|
|
[
|
|
|
|
|
fn($x) => new \davigil\helpers\cache\class_cache_encoded(
|
|
|
|
|
$x,
|
|
|
|
|
fn($value) => \json_encode($value),
|
|
|
|
|
fn($value_encoded) => \json_decode($value_encoded, true)
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
$this->cache_memory = \davigil\helpers\call\convey(
|
|
|
|
|
(new \davigil\helpers\cache\class_cache_memory()),
|
|
|
|
|
[
|
|
|
|
|
]
|
2025-09-09 12:07:53 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
2025-09-09 23:17:19 +02:00
|
|
|
private function vcalendar_to_calendar(
|
|
|
|
|
\davigil\helpers\ics\struct_vcalendar $vcalendar
|
|
|
|
|
) : \davigil\model\struct_calendar
|
2025-09-09 12:07:53 +02:00
|
|
|
{
|
2025-09-09 23:17:19 +02:00
|
|
|
return (
|
|
|
|
|
new \davigil\model\struct_calendar(
|
|
|
|
|
\array_map(
|
|
|
|
|
fn($vevent) => (new \davigil\model\struct_event(
|
|
|
|
|
// id
|
|
|
|
|
$vevent->uid,
|
|
|
|
|
// title
|
|
|
|
|
(
|
|
|
|
|
$this->combine
|
2025-09-09 19:43:23 +02:00
|
|
|
?
|
|
|
|
|
\sprintf(
|
|
|
|
|
'%s%s',
|
|
|
|
|
$vevent->summary,
|
|
|
|
|
\implode(
|
|
|
|
|
'',
|
|
|
|
|
\array_map(
|
|
|
|
|
fn($category) => \sprintf(' (%s)', $category),
|
|
|
|
|
$vevent->categories
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
:
|
|
|
|
|
$vevent->summary
|
|
|
|
|
),
|
2025-09-09 23:17:19 +02:00
|
|
|
// begin
|
|
|
|
|
\davigil\helpers\ics\datetime_to_unix_timestamp($vevent->dtstart->value),
|
|
|
|
|
// end
|
|
|
|
|
(
|
2025-09-09 12:07:53 +02:00
|
|
|
($vevent->dtend === null)
|
|
|
|
|
?
|
|
|
|
|
null
|
|
|
|
|
:
|
|
|
|
|
\davigil\helpers\ics\datetime_to_unix_timestamp($vevent->dtend->value)
|
|
|
|
|
),
|
2025-09-09 23:17:19 +02:00
|
|
|
// location
|
|
|
|
|
$vevent->location,
|
|
|
|
|
// description
|
|
|
|
|
$vevent->description,
|
|
|
|
|
// 'tags
|
|
|
|
|
(
|
|
|
|
|
$this->combine
|
2025-09-09 19:43:23 +02:00
|
|
|
?
|
2025-09-09 23:17:19 +02:00
|
|
|
['combined']
|
2025-09-09 19:43:23 +02:00
|
|
|
:
|
|
|
|
|
$vevent->categories
|
2025-09-09 23:17:19 +02:00
|
|
|
)
|
|
|
|
|
)),
|
2025-09-09 12:07:53 +02:00
|
|
|
$vcalendar->events
|
2025-09-09 23:17:19 +02:00
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
private function retrieve(
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
$client = new \Sabre\HTTP\Client();
|
|
|
|
|
$request = new \Sabre\HTTP\Request(
|
|
|
|
|
'GET',
|
|
|
|
|
$this->url,
|
|
|
|
|
[],
|
|
|
|
|
null
|
|
|
|
|
);
|
|
|
|
|
$response = $client->send($request);
|
|
|
|
|
$status_code = $response->getStatus();
|
|
|
|
|
switch ($status_code)
|
|
|
|
|
{
|
|
|
|
|
case 200:
|
|
|
|
|
{
|
|
|
|
|
$ics = $response->getBody();
|
|
|
|
|
$vcalendar = \davigil\helpers\ics\vcalendar_decode($ics);
|
|
|
|
|
$calendar = $this->vcalendar_to_calendar($vcalendar);
|
|
|
|
|
$calendar_raw = \davigil\model\calendar_to_raw($calendar);
|
|
|
|
|
return $calendar_raw;
|
2025-09-09 12:07:53 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
2025-09-09 23:17:19 +02:00
|
|
|
throw (
|
|
|
|
|
new \Exception(
|
|
|
|
|
\sprintf(
|
|
|
|
|
'unhandled response status code: %u',
|
|
|
|
|
$status_code
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
2025-09-09 12:07:53 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* [implementation]
|
|
|
|
|
*/
|
|
|
|
|
public function get(
|
|
|
|
|
array $parameters
|
2025-09-09 23:17:19 +02:00
|
|
|
) : \davigil\model\struct_calendar
|
2025-09-09 12:07:53 +02:00
|
|
|
{
|
|
|
|
|
$key = $this->url;
|
2025-09-09 23:17:19 +02:00
|
|
|
$f1 = fn() => $this->retrieve();
|
|
|
|
|
$f2 = fn() => \davigil\helpers\cache\get(
|
|
|
|
|
$this->cache_file,
|
|
|
|
|
$key,
|
|
|
|
|
$f1,
|
|
|
|
|
[
|
|
|
|
|
'ttl' => $this->lifetime,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
$f3 = fn() => \davigil\helpers\cache\get(
|
2025-09-09 12:07:53 +02:00
|
|
|
$this->cache_memory,
|
|
|
|
|
$key,
|
2025-09-09 23:17:19 +02:00
|
|
|
$f2,
|
2025-09-09 12:07:53 +02:00
|
|
|
[
|
|
|
|
|
'ttl' => null,
|
|
|
|
|
]
|
|
|
|
|
);
|
2025-09-09 23:17:19 +02:00
|
|
|
return \davigil\model\calendar_from_raw(
|
|
|
|
|
($f3)()
|
|
|
|
|
);
|
2025-09-09 12:07:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
?>
|