Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -1066,9 +1066,9 @@ public function exportCalendar(int $calendarId, int $calendarType = self::CALEND
* @param int $calendarType
* @return array
*/
public function getLimitedCalendarObjects(int $calendarId, int $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
public function getLimitedCalendarObjects(int $calendarId, int $calendarType = self::CALENDAR_TYPE_CALENDAR, array $fields = []):array {
$query = $this->db->getQueryBuilder();
$query->select(['id','uid', 'etag', 'uri', 'calendardata'])
$query->select($fields ?: ['id', 'uid', 'etag', 'uri', 'calendardata'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
Expand All @@ -1077,12 +1077,7 @@ public function getLimitedCalendarObjects(int $calendarId, int $calendarType = s

$result = [];
while (($row = $stmt->fetch()) !== false) {
$result[$row['uid']] = [
'id' => $row['id'],
'etag' => $row['etag'],
'uri' => $row['uri'],
'calendardata' => $row['calendardata'],
];
$result[$row['uid']] = $row;
}
$stmt->closeCursor();

Expand Down
44 changes: 27 additions & 17 deletions apps/dav/lib/CalDAV/Import/ImportService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
*/
class ImportService {

/** @var resource */
private $source;

public function __construct(
private CalDavBackend $backend,
) {
Expand All @@ -44,18 +41,15 @@ public function import($source, CalendarImpl $calendar, CalendarImportOptions $o
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}

$this->source = $source;

switch ($options->getFormat()) {
case 'ical':
return $this->importProcess($calendar, $options, $this->importText(...));
return $this->importProcess($source, $calendar, $options, $this->importText(...));
break;
case 'jcal':
return $this->importProcess($calendar, $options, $this->importJson(...));
return $this->importProcess($source, $calendar, $options, $this->importJson(...));
break;
case 'xcal':
return $this->importProcess($calendar, $options, $this->importXml(...));
return $this->importProcess($source, $calendar, $options, $this->importXml(...));
break;
default:
throw new InvalidArgumentException('Invalid import format');
Expand All @@ -65,10 +59,15 @@ public function import($source, CalendarImpl $calendar, CalendarImportOptions $o
/**
* Generates object stream from a text formatted source (ical)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importText(): Generator {
$importer = new TextImporter($this->source);
public function importText($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
$importer = new TextImporter($source);
$structure = $importer->structure();
$sObjectPrefix = $importer::OBJECT_PREFIX;
$sObjectSuffix = $importer::OBJECT_SUFFIX;
Expand Down Expand Up @@ -113,10 +112,15 @@ private function importText(): Generator {
/**
* Generates object stream from a xml formatted source (xcal)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importXml(): Generator {
$importer = new XmlImporter($this->source);
public function importXml($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
$importer = new XmlImporter($source);
$structure = $importer->structure();
$sObjectPrefix = $importer::OBJECT_PREFIX;
$sObjectSuffix = $importer::OBJECT_SUFFIX;
Expand Down Expand Up @@ -155,11 +159,16 @@ private function importXml(): Generator {
/**
* Generates object stream from a json formatted source (jcal)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importJson(): Generator {
public function importJson($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
/** @var VCALENDAR $importer */
$importer = Reader::readJson($this->source);
$importer = Reader::readJson($source);
// calendar time zones
$timezones = [];
foreach ($importer->VTIMEZONE as $timezone) {
Expand Down Expand Up @@ -212,17 +221,18 @@ private function findTimeZones(VCalendar $vObject): array {
*
* @since 32.0.0
*
* @param resource $source
* @param CalendarImportOptions $options
* @param callable $generator<CalendarImportOptions>: Generator<\Sabre\VObject\Component\VCalendar>
*
* @return array<string,array<string,string|array<string>>>
*/
public function importProcess(CalendarImpl $calendar, CalendarImportOptions $options, callable $generator): array {
public function importProcess($source, CalendarImpl $calendar, CalendarImportOptions $options, callable $generator): array {
$calendarId = $calendar->getKey();
$calendarUri = $calendar->getUri();
$principalUri = $calendar->getPrincipalUri();
$outcome = [];
foreach ($generator() as $vObject) {
foreach ($generator($source) as $vObject) {
$components = $vObject->getBaseComponents();
// determine if the object has no base component types
if (count($components) === 0) {
Expand Down
52 changes: 17 additions & 35 deletions apps/dav/lib/CalDAV/WebcalCaching/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use OCP\Http\Client\LocalServerException;
use OCP\IAppConfig;
use Psr\Log\LoggerInterface;
use Sabre\VObject\Reader;

class Connection {
public function __construct(
Expand All @@ -26,8 +25,10 @@ public function __construct(

/**
* gets webcal feed from remote server
*
* @return array{data: resource, format: string}|null
*/
public function queryWebcalFeed(array $subscription): ?string {
public function queryWebcalFeed(array $subscription): ?array {
$subscriptionId = $subscription['id'];
$url = $this->cleanURL($subscription['source']);
if ($url === null) {
Expand All @@ -54,6 +55,7 @@ public function queryWebcalFeed(array $subscription): ?string {
'User-Agent' => $uaString,
'Accept' => 'text/calendar, application/calendar+json, application/calendar+xml',
],
'stream' => true,
];

$user = parse_url($subscription['source'], PHP_URL_USER);
Expand All @@ -77,42 +79,22 @@ public function queryWebcalFeed(array $subscription): ?string {
return null;
}

$body = $response->getBody();

$contentType = $response->getHeader('Content-Type');
$contentType = explode(';', $contentType, 2)[0];
switch ($contentType) {
case 'application/calendar+json':
try {
$jCalendar = Reader::readJson($body, Reader::OPTION_FORGIVING);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $jCalendar->serialize();

case 'application/calendar+xml':
try {
$xCalendar = Reader::readXML($body);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $xCalendar->serialize();

case 'text/calendar':
default:
try {
$vCalendar = Reader::read($body);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $vCalendar->serialize();

$format = match ($contentType) {
'application/calendar+json' => 'jcal',
'application/calendar+xml' => 'xcal',
default => 'ical',
};

// With 'stream' => true, getBody() returns the underlying stream resource
$stream = $response->getBody();
if (!is_resource($stream)) {
return null;
}

return ['data' => $stream, 'format' => $format];
}

/**
Expand Down
Loading
Loading