2022-08-28 18:44:30 +00:00
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace OCA\GPodderSync\Core\PodcastData;
|
|
|
|
|
|
|
|
use DateTime;
|
2022-09-17 15:20:26 +00:00
|
|
|
use JsonSerializable;
|
2022-08-28 18:44:30 +00:00
|
|
|
use SimpleXMLElement;
|
|
|
|
|
2022-09-17 15:20:26 +00:00
|
|
|
class PodcastData implements JsonSerializable {
|
2022-09-17 19:03:14 +00:00
|
|
|
private ?string $title;
|
|
|
|
private ?string $author;
|
|
|
|
private ?string $link;
|
|
|
|
private ?string $description;
|
|
|
|
private ?string $imageUrl;
|
2022-08-28 18:44:30 +00:00
|
|
|
private int $fetchedAtUnix;
|
2022-09-17 19:03:14 +00:00
|
|
|
private ?string $imageBlob;
|
2022-08-28 18:44:30 +00:00
|
|
|
|
|
|
|
public function __construct(
|
2022-09-17 19:03:14 +00:00
|
|
|
?string $title,
|
|
|
|
?string $author,
|
|
|
|
?string $link,
|
|
|
|
?string $description,
|
|
|
|
?string $imageUrl,
|
2022-08-28 18:44:30 +00:00
|
|
|
int $fetchedAtUnix,
|
2022-10-26 20:32:59 +00:00
|
|
|
?string $imageBlob = null
|
2022-08-28 18:44:30 +00:00
|
|
|
) {
|
|
|
|
$this->title = $title;
|
|
|
|
$this->author = $author;
|
|
|
|
$this->link = $link;
|
|
|
|
$this->description = $description;
|
2022-09-17 19:03:14 +00:00
|
|
|
$this->imageUrl = $imageUrl;
|
2022-08-28 18:44:30 +00:00
|
|
|
$this->fetchedAtUnix = $fetchedAtUnix;
|
2022-09-17 19:03:14 +00:00
|
|
|
$this->imageBlob = $imageBlob;
|
2022-08-28 18:44:30 +00:00
|
|
|
}
|
|
|
|
|
2022-09-17 15:20:26 +00:00
|
|
|
/**
|
|
|
|
* @return PodcastData
|
|
|
|
* @throws Exception if the XML data could not be parsed.
|
|
|
|
*/
|
2022-09-17 15:03:02 +00:00
|
|
|
public static function parseRssXml(string $xmlString, ?int $fetchedAtUnix = null): PodcastData {
|
2022-08-28 18:44:30 +00:00
|
|
|
$xml = new SimpleXMLElement($xmlString);
|
|
|
|
$channel = $xml->channel;
|
|
|
|
return new PodcastData(
|
2022-10-27 07:10:16 +00:00
|
|
|
self::stringOrNull($channel->title),
|
|
|
|
self::getXPathContent($xml, '/rss/channel/itunes:author'),
|
|
|
|
self::stringOrNull($channel->link),
|
|
|
|
self::stringOrNull($channel->description),
|
|
|
|
self::getXPathContent($xml, '/rss/channel/image/url')
|
2022-09-17 19:03:14 +00:00
|
|
|
?? self::getXPathAttribute($xml, '/rss/channel/itunes:image/@href'),
|
2022-10-27 07:10:16 +00:00
|
|
|
$fetchedAtUnix ?? (new DateTime())->getTimestamp()
|
2022-08-28 18:44:30 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-10-27 07:10:16 +00:00
|
|
|
private static function stringOrNull($value): ?string {
|
2022-09-17 19:03:14 +00:00
|
|
|
if ($value) {
|
|
|
|
return (string)$value;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-09-17 15:20:26 +00:00
|
|
|
private static function getXPathContent(SimpleXMLElement $xml, string $xpath): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
$match = $xml->xpath($xpath);
|
|
|
|
if ($match) {
|
|
|
|
return (string)$match[0];
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-09-17 15:20:26 +00:00
|
|
|
private static function getXPathAttribute(SimpleXMLElement $xml, string $xpath): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
$match = $xml->xpath($xpath);
|
|
|
|
if ($match) {
|
|
|
|
return (string)$match[0][0];
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return string|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getTitle(): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
return $this->title;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return string|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getAuthor(): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
return $this->author;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return string|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getLink(): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
return $this->link;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return string|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getDescription(): ?string {
|
2022-08-28 18:44:30 +00:00
|
|
|
return $this->description;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return string|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getImageUrl(): ?string {
|
|
|
|
return $this->imageUrl;
|
2022-08-28 18:44:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-09-17 19:03:14 +00:00
|
|
|
* @return int|null
|
2022-08-28 18:44:30 +00:00
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function getFetchedAtUnix(): ?int {
|
2022-08-28 18:44:30 +00:00
|
|
|
return $this->fetchedAtUnix;
|
|
|
|
}
|
|
|
|
|
2022-09-17 19:03:14 +00:00
|
|
|
/**
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
public function getImageBlob(): ?string {
|
|
|
|
return $this->imageBlob;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $blob
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function setImageBlob(?string $blob): void {
|
|
|
|
$this->imageBlob = $blob;
|
|
|
|
}
|
|
|
|
|
2022-09-17 15:03:02 +00:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
2022-09-17 19:03:14 +00:00
|
|
|
public function __toString() : string {
|
|
|
|
return $this->title ?? '/no title/';
|
2022-08-28 18:44:30 +00:00
|
|
|
}
|
|
|
|
|
2022-09-17 15:03:02 +00:00
|
|
|
/**
|
2022-09-17 15:20:26 +00:00
|
|
|
* @return array<string,mixed>
|
2022-09-17 15:03:02 +00:00
|
|
|
*/
|
2022-08-28 18:44:30 +00:00
|
|
|
public function toArray(): array {
|
|
|
|
return
|
|
|
|
[
|
|
|
|
'title' => $this->title,
|
|
|
|
'author' => $this->author,
|
|
|
|
'link' => $this->link,
|
|
|
|
'description' => $this->description,
|
2022-09-17 19:03:14 +00:00
|
|
|
'imageUrl' => $this->imageUrl,
|
|
|
|
'imageBlob' => $this->imageBlob,
|
2022-08-28 18:44:30 +00:00
|
|
|
'fetchedAtUnix' => $this->fetchedAtUnix,
|
|
|
|
];
|
|
|
|
}
|
2022-09-17 15:03:02 +00:00
|
|
|
|
2022-09-17 15:20:26 +00:00
|
|
|
/**
|
|
|
|
* @return array<string,mixed>
|
|
|
|
*/
|
2022-10-27 07:10:16 +00:00
|
|
|
public function jsonSerialize(): array {
|
2022-09-17 15:20:26 +00:00
|
|
|
return $this->toArray();
|
|
|
|
}
|
|
|
|
|
2022-09-17 15:03:02 +00:00
|
|
|
/**
|
|
|
|
* @return PodcastData
|
|
|
|
*/
|
|
|
|
public static function fromArray(array $data): PodcastData {
|
|
|
|
return new PodcastData(
|
2022-10-27 07:10:16 +00:00
|
|
|
$data['title'],
|
|
|
|
$data['author'],
|
|
|
|
$data['link'],
|
|
|
|
$data['description'],
|
|
|
|
$data['imageUrl'],
|
|
|
|
$data['fetchedAtUnix'],
|
|
|
|
$data['imageBlob']
|
2022-09-17 15:03:02 +00:00
|
|
|
);
|
|
|
|
}
|
2022-08-28 18:44:30 +00:00
|
|
|
}
|
|
|
|
|