Browse Source

Put calendar invites into the user's first available calendar

If there's no default calendar and we can't find anything with URI
'personal', instead of creating a new one, start by using the first
"real personal calendar" available.

If not, then we create the default one.

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
tags/v25.0.0beta1
Thomas Citharel 2 years ago
parent
commit
8d7154318f
No account linked to committer's email address

+ 8
- 1
apps/dav/lib/CalDAV/Calendar.php View File

@@ -400,7 +400,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
return isset($this->calendarInfo['{http://owncloud.org/ns}public']);
}

protected function isShared() {
public function isShared() {
if (!isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
return false;
}
@@ -412,6 +412,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
return isset($this->calendarInfo['{http://calendarserver.org/ns/}source']);
}

public function isDeleted(): bool {
if (!isset($this->calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT])) {
return false;
}
return $this->calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT] !== null;
}

/**
* @inheritDoc
*/

+ 1
- 1
apps/dav/lib/CalDAV/PublicCalendar.php View File

@@ -84,7 +84,7 @@ class PublicCalendar extends Calendar {
* public calendars are always shared
* @return bool
*/
protected function isShared() {
public function isShared() {
return true;
}
}

+ 39
- 5
apps/dav/lib/CalDAV/Schedule/Plugin.php View File

@@ -30,6 +30,7 @@ namespace OCA\DAV\CalDAV\Schedule;

use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\CalDAV\CalendarHome;
use OCP\IConfig;
use Sabre\CalDAV\ICalendar;
@@ -299,12 +300,14 @@ EOF;
return null;
}

$isResourceOrRoom = strpos($principalUrl, 'principals/calendar-resources') === 0 ||
strpos($principalUrl, 'principals/calendar-rooms') === 0;

if (strpos($principalUrl, 'principals/users') === 0) {
[, $userId] = split($principalUrl);
$uri = $this->config->getUserValue($userId, 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI);
$displayName = CalDavBackend::PERSONAL_CALENDAR_NAME;
} elseif (strpos($principalUrl, 'principals/calendar-resources') === 0 ||
strpos($principalUrl, 'principals/calendar-rooms') === 0) {
} elseif ($isResourceOrRoom) {
$uri = CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI;
$displayName = CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME;
} else {
@@ -316,9 +319,40 @@ EOF;
/** @var CalendarHome $calendarHome */
$calendarHome = $this->server->tree->getNodeForPath($calendarHomePath);
if (!$calendarHome->childExists($uri)) {
$calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
'{DAV:}displayname' => $displayName,
]);
// If the default calendar doesn't exist
if ($isResourceOrRoom) {
$calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
'{DAV:}displayname' => $displayName,
]);
} else {
// And we're not handling scheduling on resource/room booking
$userCalendars = [];
/**
* If the default calendar of the user isn't set and the
* fallback doesn't match any of the user's calendar
* try to find the first "personal" calendar we can write to
* instead of creating a new one.
* A appropriate personal calendar to receive invites:
* - isn't a calendar subscription
* - user can write to it (no virtual/3rd-party calendars)
* - calendar isn't a share
*/
foreach ($calendarHome->getChildren() as $node) {
if ($node instanceof Calendar && !$node->isSubscription() && $node->canWrite() && !$node->isShared() && !$node->isDeleted()) {
$userCalendars[] = $node;
}
}

if (count($userCalendars) > 0) {
// Calendar backend returns calendar by calendarorder property
$uri = $userCalendars[0]->getName();
} else {
// Otherwise if we have really nothing, create a new calendar
$calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
'{DAV:}displayname' => $displayName,
]);
}
}
}

$result = $this->server->getPropertiesForPath($calendarHomePath . '/' . $uri, [], 1);

+ 52
- 8
apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php View File

@@ -27,11 +27,15 @@
namespace OCA\DAV\Tests\unit\CalDAV\Schedule;

use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\CalDAV\CalendarHome;
use OCA\DAV\CalDAV\Plugin as CalDAVPlugin;
use OCA\DAV\CalDAV\Schedule\Plugin;
use OCA\DAV\CalDAV\Trashbin\Plugin as TrashbinPlugin;
use OCP\IConfig;
use OCP\IL10N;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\Tree;
@@ -177,6 +181,15 @@ class PluginTest extends TestCase {
CalDavBackend::PERSONAL_CALENDAR_NAME,
true
],
[
'principals/users/myuser',
'calendars/myuser',
false,
CalDavBackend::PERSONAL_CALENDAR_URI,
CalDavBackend::PERSONAL_CALENDAR_NAME,
false,
true
],
[
'principals/users/myuser',
'calendars/myuser',
@@ -201,6 +214,7 @@ class PluginTest extends TestCase {
CalDavBackend::PERSONAL_CALENDAR_NAME,
true,
false,
false,
],
[
'principals/users/myuser',
@@ -240,14 +254,14 @@ class PluginTest extends TestCase {
/**
* @dataProvider propFindDefaultCalendarUrlProvider
* @param string $principalUri
* @param string $calendarHome
* @param string|null $calendarHome
* @param bool $isResource
* @param string $calendarUri
* @param string $displayName
* @param bool $exists
* @param bool $propertiesForPath
*/
public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $propertiesForPath = true) {
public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $hasExistingCalendars = false, bool $propertiesForPath = true) {
/** @var PropFind $propFind */
$propFind = new PropFind(
$principalUri,
@@ -290,6 +304,7 @@ class PluginTest extends TestCase {
$this->assertNull($propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL));
return;
}

if (!$isResource) {
$this->config->expects($this->once())
->method('getUserValue')
@@ -303,18 +318,47 @@ class PluginTest extends TestCase {
->with($calendarUri)
->willReturn($exists);

$calendarBackend = $this->createMock(CalDavBackend::class);
$calendarUri = $hasExistingCalendars ? 'custom' : $calendarUri;
$displayName = $hasExistingCalendars ? 'Custom Calendar' : $displayName;

$existingCalendars = $hasExistingCalendars ? [
new Calendar(
$calendarBackend,
['uri' => 'deleted', '{DAV:}displayname' => 'A deleted calendar', TrashbinPlugin::PROPERTY_DELETED_AT => 42],
$this->createMock(IL10N::class),
$this->config,
$this->createMock(LoggerInterface::class)
),
new Calendar(
$calendarBackend,
['uri' => $calendarUri, '{DAV:}displayname' => $displayName],
$this->createMock(IL10N::class),
$this->config,
$this->createMock(LoggerInterface::class)
)
] : [];

if (!$exists) {
$calendarBackend = $this->createMock(CalDavBackend::class);
$calendarBackend->expects($this->once())
if (!$hasExistingCalendars) {
$calendarBackend->expects($this->once())
->method('createCalendar')
->with($principalUri, $calendarUri, [
'{DAV:}displayname' => $displayName,
]);

$calendarHomeObject->expects($this->once())
->method('getCalDAVBackend')
->with()
->willReturn($calendarBackend);
$calendarHomeObject->expects($this->once())
->method('getCalDAVBackend')
->with()
->willReturn($calendarBackend);
}

if (!$isResource) {
$calendarHomeObject->expects($this->once())
->method('getChildren')
->with()
->willReturn($existingCalendars);
}
}

/** @var Tree|MockObject $tree */

Loading…
Cancel
Save