Skip to content

fix(dav): fix event birthday alarms not being updated - #39977

Merged
susnux merged 3 commits into
masterfrom
dav-fix-birthday-sync
Nov 6, 2026
Merged

susnux merged 3 commits into
masterfrom
dav-fix-birthday-sync

Conversation

@tcitworld

Copy link
Copy Markdown
Member

In #33251 the default offset for a birthday event alarm was changed to 9AM on the day of the event.

However the birthdayEvenChanged method did not account for alarm changes, so it was never propagated to existing birthday events, which were kept on midnight.

Checklist

@tcitworld tcitworld added bug 3. to review Waiting for reviews feature: caldav Related to CalDAV internals feature: carddav Related to CardDAV internals labels Aug 19, 2023
@tcitworld tcitworld added this to the Nextcloud 28 milestone Aug 19, 2023
@tcitworld
tcitworld requested a review from a team August 19, 2023 09:47
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||
($newCalendarData->VEVENT->VALARM && $existingBirthday->VEVENT->VALARM && $newCalendarData->VEVENT->VALARM->TRIGGER->getValue() !== $existingBirthday->VEVENT->VALARM->TRIGGER->getValue())

Check failure

Code scanning / Psalm

UndefinedPropertyFetch

Instance property Sabre\VObject\Property::$VALARM is not defined
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||
($newCalendarData->VEVENT->VALARM && $existingBirthday->VEVENT->VALARM && $newCalendarData->VEVENT->VALARM->TRIGGER->getValue() !== $existingBirthday->VEVENT->VALARM->TRIGGER->getValue())

Check failure

Code scanning / Psalm

UndefinedPropertyFetch

Instance property Sabre\VObject\Property::$VALARM is not defined
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

PossiblyNullPropertyFetch

Cannot get property on possibly null variable $newCalendarData->VEVENT of type Sabre\VObject\Property|null
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

UndefinedPropertyFetch

Instance property Sabre\VObject\Property::$SUMMARY is not defined
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

PossiblyNullReference

Cannot call method getValue on possibly null value
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

PossiblyNullPropertyFetch

Cannot get property on possibly null variable $existingBirthday->VEVENT of type Sabre\VObject\Property|null
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

UndefinedPropertyFetch

Instance property Sabre\VObject\Property::$SUMMARY is not defined
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||

Check notice

Code scanning / Psalm

PossiblyNullReference

Cannot call method getValue on possibly null value
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||
($newCalendarData->VEVENT->VALARM && $existingBirthday->VEVENT->VALARM && $newCalendarData->VEVENT->VALARM->TRIGGER->getValue() !== $existingBirthday->VEVENT->VALARM->TRIGGER->getValue())

Check notice

Code scanning / Psalm

PossiblyNullPropertyFetch

Cannot get property on possibly null variable $newCalendarData->VEVENT of type Sabre\VObject\Property|null
Comment thread apps/dav/lib/CalDAV/BirthdayService.php Outdated
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue() ||
($newCalendarData->VEVENT->VALARM && $existingBirthday->VEVENT->VALARM && $newCalendarData->VEVENT->VALARM->TRIGGER->getValue() !== $existingBirthday->VEVENT->VALARM->TRIGGER->getValue())

Check notice

Code scanning / Psalm

PossiblyNullPropertyFetch

Cannot get property on possibly null variable $existingBirthday->VEVENT of type Sabre\VObject\Property|null

@nfebe nfebe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@miaulalala
miaulalala force-pushed the dav-fix-birthday-sync branch from 03a300c to f3ccb5d Compare August 28, 2023 10:35
@tcitworld
tcitworld force-pushed the dav-fix-birthday-sync branch from f3ccb5d to 24e6ef5 Compare October 2, 2023 09:33
@tcitworld

Copy link
Copy Markdown
Member Author

Should we add a repair job just like RegenerateBirthdayCalendars to fix all existing events? Or just edit the app config value from regeneratedBirthdayCalendarsForYearFix to something like regeneratedBirthdayCalendarsForAlarmFix so that it's triggered again?

@miaulalala

Copy link
Copy Markdown
Contributor

Should we add a repair job just like RegenerateBirthdayCalendars to fix all existing events? Or just edit the app config value from regeneratedBirthdayCalendarsForYearFix to something like regeneratedBirthdayCalendarsForAlarmFix so that it's triggered again?

Repair step sounds good to me.

@tcitworld
tcitworld force-pushed the dav-fix-birthday-sync branch 2 times, most recently from 3ba9335 to c2c2c8b Compare October 2, 2023 15:12
@blizzz
blizzz force-pushed the dav-fix-birthday-sync branch from c2c2c8b to 87c8581 Compare October 11, 2023 13:33
@skjnldsv skjnldsv mentioned this pull request Nov 1, 2023
This was referenced Nov 6, 2023
This was referenced Nov 14, 2023
@blizzz blizzz modified the milestones: Nextcloud 28, Nextcloud 29 Nov 23, 2023
@tcitworld
tcitworld force-pushed the dav-fix-birthday-sync branch from 87c8581 to 4451809 Compare February 1, 2024 17:29
@tcitworld

Copy link
Copy Markdown
Member Author

Rebased

public function run(IOutput $output): void {
// only run once
if ($this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForYearFix') === 'yes') {
if ($this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForYearFix') === 'yes' && $this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForAlarmFix') === 'yes') {

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OCP\IConfig::getAppValue has been marked as deprecated
public function run(IOutput $output): void {
// only run once
if ($this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForYearFix') === 'yes') {
if ($this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForYearFix') === 'yes' && $this->config->getAppValue('dav', 'regeneratedBirthdayCalendarsForAlarmFix') === 'yes') {

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OCP\IConfig::getAppValue has been marked as deprecated

// if all were done, no need to redo the repair during next upgrade
$this->config->setAppValue('dav', 'regeneratedBirthdayCalendarsForYearFix', 'yes');
$this->config->setAppValue('dav', 'regeneratedBirthdayCalendarsForAlarmFix', 'yes');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OCP\IConfig::setAppValue has been marked as deprecated
This was referenced Feb 11, 2026
@blizzz blizzz modified the milestones: Nextcloud 33, Nextcloud 34 Feb 16, 2026
This was referenced Jun 5, 2026
@susnux susnux added the community pull requests from community label Jun 9, 2026
@susnux susnux removed this from the Nextcloud 34.0.1 milestone Jun 9, 2026
@nextcloud nextcloud deleted a comment from tcitworld Nov 6, 2026
In #33251 the default offset for
a birthday event alarm was changed to 9AM on the day of the event.

However the birthdayEvenChanged method did not account for alarm
changes, so it was never propagated to existing birthday events, which
were kept on midnight.

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
…thday calendars

So that birthday calendars are immediately updated and we don't need to wait for user to change a
card or disable/enable the calendar. We reuse the existing RegenerateBirthdayCalendars repair step
instead of adding a new one.

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
@nextcloud nextcloud deleted a comment from tcitworld Nov 6, 2026
@nextcloud nextcloud deleted a comment from tcitworld Nov 6, 2026
@nextcloud nextcloud deleted a comment from tcitworld Nov 6, 2026
The trigger was only compared when both the existing and the new
birthday event had an alarm, so enabling or disabling the reminder
offset never updated existing events. Compare the triggers directly
and mention the reminder update in the repair step name.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
@susnux
susnux force-pushed the dav-fix-birthday-sync branch from 4451809 to df6ecfb Compare November 6, 2026 22:45
@susnux
susnux requested a review from hamza221 as a code owner November 6, 2026 22:45
@susnux susnux added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Nov 6, 2026
@susnux
susnux merged commit 9b1f8ae into master Nov 6, 2026
164 of 168 checks passed
@susnux
susnux deleted the dav-fix-birthday-sync branch November 6, 2026 23:13
@susnux susnux linked an issue Nov 6, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted backport-request bug community pull requests from community feature: caldav Related to CalDAV internals feature: carddav Related to CardDAV internals

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Birthday event alert should happen in the morning, not at midnight