@@ -138,6 +138,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
138138 public const CLASSIFICATION_PRIVATE = 1 ;
139139 public const CLASSIFICATION_CONFIDENTIAL = 2 ;
140140
141+ public const DEFAULT_ALARMS_PART_DAY_PROPERTY = '{ ' . \OCA \DAV \DAV \Sharing \Plugin::NS_NEXTCLOUD . '}default-alarms-part-day ' ;
142+ public const DEFAULT_ALARMS_FULL_DAY_PROPERTY = '{ ' . \OCA \DAV \DAV \Sharing \Plugin::NS_NEXTCLOUD . '}default-alarms-full-day ' ;
143+
144+ /** @var string[] DB columns for calendar properties outside propertyMap (custom serialization). */
145+ private const SERIALIZED_CALENDAR_DB_COLUMNS = [
146+ 'default_alarms_pday ' ,
147+ 'default_alarms_fday ' ,
148+ ];
149+
141150 /**
142151 * List of CalDAV properties, and how they map to database field names and their type
143152 * Add your own properties by simply adding on to this array.
@@ -326,7 +335,7 @@ public function getCalendarsForUser($principalUri) {
326335 return $ this ->atomic (function () use ($ principalUri ) {
327336 $ principalUriOriginal = $ principalUri ;
328337 $ principalUri = $ this ->convertPrincipal ($ principalUri , true );
329- $ fields = array_column ( $ this ->propertyMap , 0 );
338+ $ fields = $ this ->getCalendarMergeSerializedProperties ( );
330339 $ fields [] = 'id ' ;
331340 $ fields [] = 'uri ' ;
332341 $ fields [] = 'synctoken ' ;
@@ -382,10 +391,9 @@ public function getCalendarsForUser($principalUri) {
382391 $ principals = array_merge ($ principals , $ this ->principalBackend ->getCircleMembership ($ principalUriOriginal ));
383392 $ principals [] = $ principalUri ;
384393
385- $ fields = array_column ($ this ->propertyMap , 0 );
386394 $ fields = array_map (function (string $ field ) {
387395 return 'a. ' . $ field ;
388- }, $ fields );
396+ }, $ this -> getCalendarMergeSerializedProperties () );
389397 $ fields [] = 'a.id ' ;
390398 $ fields [] = 'a.uri ' ;
391399 $ fields [] = 'a.synctoken ' ;
@@ -468,7 +476,7 @@ public function getCalendarsForUser($principalUri) {
468476 */
469477 public function getUsersOwnCalendars ($ principalUri ) {
470478 $ principalUri = $ this ->convertPrincipal ($ principalUri , true );
471- $ fields = array_column ( $ this ->propertyMap , 0 );
479+ $ fields = $ this ->getCalendarMergeSerializedProperties ( );
472480 $ fields [] = 'id ' ;
473481 $ fields [] = 'uri ' ;
474482 $ fields [] = 'synctoken ' ;
@@ -514,7 +522,7 @@ public function getUsersOwnCalendars($principalUri) {
514522 * @return array
515523 */
516524 public function getPublicCalendars () {
517- $ fields = array_column ( $ this -> propertyMap , 0 );
525+ $ fields = array_map ( static fn ( string $ field ): string => ' a. ' . $ field , $ this -> getCalendarMergeSerializedProperties () );
518526 $ fields [] = 'a.id ' ;
519527 $ fields [] = 'a.uri ' ;
520528 $ fields [] = 'a.synctoken ' ;
@@ -572,7 +580,7 @@ public function getPublicCalendars() {
572580 * @throws NotFound
573581 */
574582 public function getPublicCalendar ($ uri ) {
575- $ fields = array_column ( $ this -> propertyMap , 0 );
583+ $ fields = array_map ( static fn ( string $ field ): string => ' a. ' . $ field , $ this -> getCalendarMergeSerializedProperties () );
576584 $ fields [] = 'a.id ' ;
577585 $ fields [] = 'a.uri ' ;
578586 $ fields [] = 'a.synctoken ' ;
@@ -631,7 +639,7 @@ public function getPublicCalendar($uri) {
631639 * @return array|null
632640 */
633641 public function getCalendarByUri ($ principal , $ uri ) {
634- $ fields = array_column ( $ this ->propertyMap , 0 );
642+ $ fields = $ this ->getCalendarMergeSerializedProperties ( );
635643 $ fields [] = 'id ' ;
636644 $ fields [] = 'uri ' ;
637645 $ fields [] = 'synctoken ' ;
@@ -681,7 +689,7 @@ public function getCalendarByUri($principal, $uri) {
681689 * @return array|null
682690 */
683691 public function getCalendarById (int $ calendarId ): ?array {
684- $ fields = array_column ( $ this ->propertyMap , 0 );
692+ $ fields = $ this ->getCalendarMergeSerializedProperties ( );
685693 $ fields [] = 'id ' ;
686694 $ fields [] = 'uri ' ;
687695 $ fields [] = 'synctoken ' ;
@@ -850,9 +858,29 @@ public function createCalendar($principalUri, $calendarUri, array $properties) {
850858 foreach ($ this ->propertyMap as $ xmlName => [$ dbName , $ type ]) {
851859 if (isset ($ properties [$ xmlName ])) {
852860 $ values [$ dbName ] = $ properties [$ xmlName ];
861+ if ($ dbName === 'default_alarm_pday ' ) {
862+ $ values ['default_alarms_pday ' ] = DefaultCalendarAlarms::encodeFromLegacyInt (
863+ $ properties [$ xmlName ] !== null ? (int )$ properties [$ xmlName ] : null ,
864+ );
865+ } elseif ($ dbName === 'default_alarm_fday ' ) {
866+ $ values ['default_alarms_fday ' ] = DefaultCalendarAlarms::encodeFromLegacyInt (
867+ $ properties [$ xmlName ] !== null ? (int )$ properties [$ xmlName ] : null ,
868+ );
869+ }
853870 }
854871 }
855872
873+ if (isset ($ properties [self ::DEFAULT_ALARMS_PART_DAY_PROPERTY ])) {
874+ $ encoded = DefaultCalendarAlarms::validateAndEncode ($ properties [self ::DEFAULT_ALARMS_PART_DAY_PROPERTY ]);
875+ $ values ['default_alarms_pday ' ] = $ encoded ;
876+ $ values ['default_alarm_pday ' ] = DefaultCalendarAlarms::legacyIntFromJson ($ encoded );
877+ }
878+ if (isset ($ properties [self ::DEFAULT_ALARMS_FULL_DAY_PROPERTY ])) {
879+ $ encoded = DefaultCalendarAlarms::validateAndEncode ($ properties [self ::DEFAULT_ALARMS_FULL_DAY_PROPERTY ]);
880+ $ values ['default_alarms_fday ' ] = $ encoded ;
881+ $ values ['default_alarm_fday ' ] = DefaultCalendarAlarms::legacyIntFromJson ($ encoded );
882+ }
883+
856884 [$ calendarId , $ calendarData ] = $ this ->atomic (function () use ($ values ) {
857885 $ query = $ this ->db ->getQueryBuilder ();
858886 $ query ->insert ('calendars ' );
@@ -891,18 +919,42 @@ public function createCalendar($principalUri, $calendarUri, array $properties) {
891919 public function updateCalendar ($ calendarId , PropPatch $ propPatch ) {
892920 $ supportedProperties = array_keys ($ this ->propertyMap );
893921 $ supportedProperties [] = '{ ' . Plugin::NS_CALDAV . '}schedule-calendar-transp ' ;
922+ $ supportedProperties [] = self ::DEFAULT_ALARMS_PART_DAY_PROPERTY ;
923+ $ supportedProperties [] = self ::DEFAULT_ALARMS_FULL_DAY_PROPERTY ;
894924
895925 $ propPatch ->handle ($ supportedProperties , function ($ mutations ) use ($ calendarId ) {
926+ $ storedDefaultAlarmsJson = $ this ->getCalendarDefaultAlarmsJson ($ calendarId );
896927 $ newValues = [];
897928 foreach ($ mutations as $ propertyName => $ propertyValue ) {
898929 switch ($ propertyName ) {
899930 case '{ ' . Plugin::NS_CALDAV . '}schedule-calendar-transp ' :
900931 $ fieldName = 'transparent ' ;
901932 $ newValues [$ fieldName ] = (int )($ propertyValue ->getValue () === 'transparent ' );
902933 break ;
934+ case self ::DEFAULT_ALARMS_PART_DAY_PROPERTY :
935+ $ encoded = DefaultCalendarAlarms::validateAndEncode ($ propertyValue );
936+ $ newValues ['default_alarms_pday ' ] = $ encoded ;
937+ $ newValues ['default_alarm_pday ' ] = DefaultCalendarAlarms::legacyIntFromJson ($ encoded );
938+ break ;
939+ case self ::DEFAULT_ALARMS_FULL_DAY_PROPERTY :
940+ $ encoded = DefaultCalendarAlarms::validateAndEncode ($ propertyValue );
941+ $ newValues ['default_alarms_fday ' ] = $ encoded ;
942+ $ newValues ['default_alarm_fday ' ] = DefaultCalendarAlarms::legacyIntFromJson ($ encoded );
943+ break ;
903944 default :
904945 $ fieldName = $ this ->propertyMap [$ propertyName ][0 ];
905946 $ newValues [$ fieldName ] = $ propertyValue ;
947+ if ($ fieldName === 'default_alarm_pday ' ) {
948+ $ newValues ['default_alarms_pday ' ] = DefaultCalendarAlarms::mergeLegacyIntIntoJson (
949+ $ storedDefaultAlarmsJson ['default_alarms_pday ' ],
950+ $ propertyValue !== null ? (int )$ propertyValue : null ,
951+ );
952+ } elseif ($ fieldName === 'default_alarm_fday ' ) {
953+ $ newValues ['default_alarms_fday ' ] = DefaultCalendarAlarms::mergeLegacyIntIntoJson (
954+ $ storedDefaultAlarmsJson ['default_alarms_fday ' ],
955+ $ propertyValue !== null ? (int )$ propertyValue : null ,
956+ );
957+ }
906958 break ;
907959 }
908960 }
@@ -3968,9 +4020,56 @@ private function rowToCalendar($row, array $calendar): array {
39684020 }
39694021 $ calendar [$ xmlName ] = $ value ;
39704022 }
4023+
4024+ $ calendar [self ::DEFAULT_ALARMS_PART_DAY_PROPERTY ] = DefaultCalendarAlarms::formatForCalDav (
4025+ isset ($ row ['default_alarms_pday ' ]) ? (string )$ row ['default_alarms_pday ' ] : null ,
4026+ isset ($ row ['default_alarm_pday ' ]) && $ row ['default_alarm_pday ' ] !== null ? (int )$ row ['default_alarm_pday ' ] : null ,
4027+ );
4028+ $ calendar [self ::DEFAULT_ALARMS_FULL_DAY_PROPERTY ] = DefaultCalendarAlarms::formatForCalDav (
4029+ isset ($ row ['default_alarms_fday ' ]) ? (string )$ row ['default_alarms_fday ' ] : null ,
4030+ isset ($ row ['default_alarm_fday ' ]) && $ row ['default_alarm_fday ' ] !== null ? (int )$ row ['default_alarm_fday ' ] : null ,
4031+ );
4032+
39714033 return $ calendar ;
39724034 }
39734035
4036+ /**
4037+ * calendars-table SELECT columns: propertyMap DB fields plus columns for
4038+ * CalDAV properties stored outside propertyMap (custom serialization).
4039+ *
4040+ * @return string[]
4041+ */
4042+ private function getCalendarMergeSerializedProperties (): array {
4043+ return array_merge (
4044+ array_column ($ this ->propertyMap , 0 ),
4045+ self ::SERIALIZED_CALENDAR_DB_COLUMNS ,
4046+ );
4047+ }
4048+
4049+ /**
4050+ * @return array{default_alarms_pday: ?string, default_alarms_fday: ?string}
4051+ */
4052+ private function getCalendarDefaultAlarmsJson (int $ calendarId ): array {
4053+ $ query = $ this ->db ->getQueryBuilder ();
4054+ $ query ->select ('default_alarms_pday ' , 'default_alarms_fday ' )
4055+ ->from ('calendars ' )
4056+ ->where ($ query ->expr ()->eq ('id ' , $ query ->createNamedParameter ($ calendarId , IQueryBuilder::PARAM_INT )))
4057+ ->setMaxResults (1 );
4058+ $ row = $ query ->executeQuery ()->fetchAssociative ();
4059+
4060+ if ($ row === false ) {
4061+ return [
4062+ 'default_alarms_pday ' => null ,
4063+ 'default_alarms_fday ' => null ,
4064+ ];
4065+ }
4066+
4067+ return [
4068+ 'default_alarms_pday ' => $ row ['default_alarms_pday ' ] !== null ? (string )$ row ['default_alarms_pday ' ] : null ,
4069+ 'default_alarms_fday ' => $ row ['default_alarms_fday ' ] !== null ? (string )$ row ['default_alarms_fday ' ] : null ,
4070+ ];
4071+ }
4072+
39744073 /**
39754074 * Amend the subscription info with database row data
39764075 *
0 commit comments