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