mirror of
https://github.com/nextcloud/server.git
synced 2026-06-29 10:39:13 -04:00
Extract CLASS property from calendar object and store it in the database
This commit is contained in:
parent
aca4ea12c1
commit
fbdec59f22
3 changed files with 69 additions and 26 deletions
|
|
@ -272,6 +272,12 @@ CREATE TABLE calendarobjects (
|
|||
<type>text</type>
|
||||
<length>255</length>
|
||||
</field>
|
||||
<field>
|
||||
<comments>0 - public, 1 - private, 2 - confidential</comments>
|
||||
<name>classification</name>
|
||||
<type>int</type>
|
||||
<default>0</default>
|
||||
</field>
|
||||
<index>
|
||||
<name>calobjects_index</name>
|
||||
<unique>true</unique>
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
|
|||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\PropPatch;
|
||||
use Sabre\HTTP\URLUtil;
|
||||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\Reader;
|
||||
use Sabre\VObject\RecurrenceIterator;
|
||||
use Sabre\VObject\Recur\EventIterator;
|
||||
|
||||
/**
|
||||
* Class CalDavBackend
|
||||
|
|
@ -61,6 +62,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
*/
|
||||
const MAX_DATE = '2038-01-01';
|
||||
|
||||
const CLASSIFICATION_PUBLIC = 0;
|
||||
const CLASSIFICATION_PRIVATE = 1;
|
||||
const CLASSIFICATION_CONFIDENTIAL = 2;
|
||||
|
||||
/**
|
||||
* List of CalDAV properties, and how they map to database field names
|
||||
* Add your own properties by simply adding on to this array.
|
||||
|
|
@ -395,10 +400,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @param PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
|
||||
function updateCalendar($calendarId, PropPatch $propPatch) {
|
||||
$supportedProperties = array_keys($this->propertyMap);
|
||||
$supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
|
||||
|
||||
|
|
@ -618,6 +623,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
'componenttype' => $query->createNamedParameter($extraData['componentType']),
|
||||
'firstoccurence' => $query->createNamedParameter($extraData['firstOccurence']),
|
||||
'lastoccurence' => $query->createNamedParameter($extraData['lastOccurence']),
|
||||
'classification' => $query->createNamedParameter($extraData['classification']),
|
||||
'uid' => $query->createNamedParameter($extraData['uid']),
|
||||
])
|
||||
->execute();
|
||||
|
|
@ -657,6 +663,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
->set('componenttype', $query->createNamedParameter($extraData['componentType']))
|
||||
->set('firstoccurence', $query->createNamedParameter($extraData['firstOccurence']))
|
||||
->set('lastoccurence', $query->createNamedParameter($extraData['lastOccurence']))
|
||||
->set('classification', $query->createNamedParameter($extraData['classification']))
|
||||
->set('uid', $query->createNamedParameter($extraData['uid']))
|
||||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
|
||||
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
|
||||
|
|
@ -667,6 +674,18 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
return '"' . $extraData['etag'] . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $calendarObjectId
|
||||
* @param int $classification
|
||||
*/
|
||||
public function setClassification($calendarObjectId, $classification) {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->update('calendarobjects')
|
||||
->set('classification', $query->createNamedParameter($classification))
|
||||
->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId)))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
|
|
@ -1086,10 +1105,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $subscriptionId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @param PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) {
|
||||
function updateSubscription($subscriptionId, PropPatch $propPatch) {
|
||||
$supportedProperties = array_keys($this->subscriptionPropertyMap);
|
||||
$supportedProperties[] = '{http://calendarserver.org/ns/}source';
|
||||
|
||||
|
|
@ -1280,14 +1299,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
* @param string $calendarData
|
||||
* @return array
|
||||
*/
|
||||
protected function getDenormalizedData($calendarData) {
|
||||
public function getDenormalizedData($calendarData) {
|
||||
|
||||
$vObject = Reader::read($calendarData);
|
||||
$componentType = null;
|
||||
$component = null;
|
||||
$firstOccurence = null;
|
||||
$lastOccurence = null;
|
||||
$firstOccurrence = null;
|
||||
$lastOccurrence = null;
|
||||
$uid = null;
|
||||
$classification = self::CLASSIFICATION_PUBLIC;
|
||||
foreach($vObject->getComponents() as $component) {
|
||||
if ($component->name!=='VTIMEZONE') {
|
||||
$componentType = $component->name;
|
||||
|
|
@ -1303,23 +1323,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
// Finding the last occurrence is a bit harder
|
||||
if (!isset($component->RRULE)) {
|
||||
if (isset($component->DTEND)) {
|
||||
$lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
|
||||
$lastOccurrence = $component->DTEND->getDateTime()->getTimeStamp();
|
||||
} elseif (isset($component->DURATION)) {
|
||||
$endDate = clone $component->DTSTART->getDateTime();
|
||||
$endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
|
||||
$lastOccurence = $endDate->getTimeStamp();
|
||||
$lastOccurrence = $endDate->getTimeStamp();
|
||||
} elseif (!$component->DTSTART->hasTime()) {
|
||||
$endDate = clone $component->DTSTART->getDateTime();
|
||||
$endDate->modify('+1 day');
|
||||
$lastOccurence = $endDate->getTimeStamp();
|
||||
$lastOccurrence = $endDate->getTimeStamp();
|
||||
} else {
|
||||
$lastOccurence = $firstOccurence;
|
||||
$lastOccurrence = $firstOccurence;
|
||||
}
|
||||
} else {
|
||||
$it = new RecurrenceIterator($vObject, (string)$component->UID);
|
||||
$it = new EventIterator($vObject, (string)$component->UID);
|
||||
$maxDate = new \DateTime(self::MAX_DATE);
|
||||
if ($it->isInfinite()) {
|
||||
$lastOccurence = $maxDate->getTimeStamp();
|
||||
$lastOccurrence = $maxDate->getTimeStamp();
|
||||
} else {
|
||||
$end = $it->getDtEnd();
|
||||
while($it->valid() && $end < $maxDate) {
|
||||
|
|
@ -1327,19 +1347,31 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
$it->next();
|
||||
|
||||
}
|
||||
$lastOccurence = $end->getTimeStamp();
|
||||
$lastOccurrence = $end->getTimeStamp();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ($component->CLASS) {
|
||||
$classification = CalDavBackend::CLASSIFICATION_PRIVATE;
|
||||
switch ($component->CLASS->getValue()) {
|
||||
case 'PUBLIC':
|
||||
$classification = CalDavBackend::CLASSIFICATION_PUBLIC;
|
||||
break;
|
||||
case 'CONFIDENTIAL':
|
||||
$classification = CalDavBackend::CLASSIFICATION_CONFIDENTIAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [
|
||||
'etag' => md5($calendarData),
|
||||
'size' => strlen($calendarData),
|
||||
'componentType' => $componentType,
|
||||
'firstOccurence' => is_null($firstOccurence) ? null : max(0, $firstOccurence),
|
||||
'lastOccurence' => $lastOccurence,
|
||||
'uid' => $uid,
|
||||
'etag' => md5($calendarData),
|
||||
'size' => strlen($calendarData),
|
||||
'componentType' => $componentType,
|
||||
'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
|
||||
'lastOccurence' => $lastOccurrence,
|
||||
'uid' => $uid,
|
||||
'classification' => $classification
|
||||
];
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,15 +464,20 @@ EOD;
|
|||
/**
|
||||
* @dataProvider providesCalDataForGetDenormalizedData
|
||||
*/
|
||||
public function testGetDenormalizedData($expectedFirstOccurance, $calData) {
|
||||
$actual = $this->invokePrivate($this->backend, 'getDenormalizedData', [$calData]);
|
||||
$this->assertEquals($expectedFirstOccurance, $actual['firstOccurence']);
|
||||
public function testGetDenormalizedData($expected, $key, $calData) {
|
||||
$actual = $this->backend->getDenormalizedData($calData);
|
||||
$this->assertEquals($expected, $actual[$key]);
|
||||
}
|
||||
|
||||
public function providesCalDataForGetDenormalizedData() {
|
||||
return [
|
||||
[0, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
[null, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"]
|
||||
'first occurrence before unix epoch starts' => [0, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
'no first occurrence because yearly' => [null, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
|
||||
'CLASS:PRIVATE' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PRIVATE\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
|
||||
'CLASS:PUBLIC' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PUBLIC\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
|
||||
'CLASS:CONFIDENTIAL' => [CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:CONFIDENTIAL\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
|
||||
'no class set -> public' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nTRANSP:OPAQUE\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
|
||||
'unknown class -> private' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:VERTRAULICH\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue