Fix so birthdays are exported with correct year and recurrence definition (T855)
Summary: Refactored birthdays handling code. The "all birthdays" request is detected and for this case year is not modified and recurrence rule is added. Reviewers: #roundcube_kolab_plugins_developers, vanmeeuwen Reviewed By: #roundcube_kolab_plugins_developers, vanmeeuwen Differential Revision: https://git.kolab.org/D117
This commit is contained in:
parent
9d883ed07d
commit
a7f5885d8d
1 changed files with 112 additions and 106 deletions
|
@ -632,9 +632,9 @@ abstract class calendar_driver
|
||||||
$cache = $rcmail->get_cache('calendar.birthdays', 'db', 3600);
|
$cache = $rcmail->get_cache('calendar.birthdays', 'db', 3600);
|
||||||
$cache->expunge();
|
$cache->expunge();
|
||||||
|
|
||||||
$alarm_type = $rcmail->config->get('calendar_birthdays_alarm_type', '');
|
$alarm_type = $rcmail->config->get('calendar_birthdays_alarm_type', '');
|
||||||
$alarm_offset = $rcmail->config->get('calendar_birthdays_alarm_offset', '-1D');
|
$alarm_offset = $rcmail->config->get('calendar_birthdays_alarm_offset', '-1D');
|
||||||
$alarms = $alarm_type ? $alarm_offset . ':' . $alarm_type : null;
|
$alarms = $alarm_type ? $alarm_offset . ':' . $alarm_type : null;
|
||||||
|
|
||||||
// let the user select the address books to consider in prefs
|
// let the user select the address books to consider in prefs
|
||||||
$selected_sources = $rcmail->config->get('calendar_birthday_adressbooks');
|
$selected_sources = $rcmail->config->get('calendar_birthday_adressbooks');
|
||||||
|
@ -655,72 +655,56 @@ abstract class calendar_driver
|
||||||
|
|
||||||
// iterate over (cached) contacts
|
// iterate over (cached) contacts
|
||||||
foreach (($cached ?: $abook->search('*', '', 2, true, true, array('birthday'))) as $contact) {
|
foreach (($cached ?: $abook->search('*', '', 2, true, true, array('birthday'))) as $contact) {
|
||||||
if (is_array($contact) && !empty($contact['birthday'])) {
|
$event = self::parse_contact($contact, $source);
|
||||||
try {
|
|
||||||
if (is_array($contact['birthday']))
|
|
||||||
$contact['birthday'] = reset($contact['birthday']);
|
|
||||||
|
|
||||||
$bday = $contact['birthday'] instanceof DateTime ? $contact['birthday'] :
|
if (empty($event)) {
|
||||||
new DateTime($contact['birthday'], new DateTimezone('UTC'));
|
continue;
|
||||||
$birthyear = $bday->format('Y');
|
}
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
// add stripped record to cache
|
||||||
rcube::raise_error(array(
|
if (empty($cached)) {
|
||||||
'code' => 600, 'type' => 'php',
|
$cache_records[] = array(
|
||||||
'file' => __FILE__, 'line' => __LINE__,
|
'ID' => $contact['ID'],
|
||||||
'message' => 'BIRTHDAY PARSE ERROR: ' . $e),
|
'name' => $event['_displayname'],
|
||||||
true, false);
|
'birthday' => $event['start']->format('Y-m-d'),
|
||||||
continue;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter by search term (only name is involved here)
|
||||||
|
if (!empty($search) && strpos(mb_strtolower($event['title']), $search) === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bday = clone $event['start'];
|
||||||
|
$byear = $bday->format('Y');
|
||||||
|
|
||||||
|
// quick-and-dirty recurrence computation: just replace the year
|
||||||
|
$bday->setDate($year, $bday->format('n'), $bday->format('j'));
|
||||||
|
$bday->setTime(12, 0, 0);
|
||||||
|
$this_year = $year;
|
||||||
|
|
||||||
|
// date range reaches over multiple years: use end year if not in range
|
||||||
|
if (($bday > $end || $bday < $start) && $year2 != $year) {
|
||||||
|
$bday->setDate($year2, $bday->format('n'), $bday->format('j'));
|
||||||
|
$this_year = $year2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// birthday is within requested range
|
||||||
|
if ($bday <= $end && $bday >= $start) {
|
||||||
|
unset($event['_displayname']);
|
||||||
|
$event['alarms'] = $alarms;
|
||||||
|
|
||||||
|
// if this is not the first occurence modify event details
|
||||||
|
// but not when this is "all birthdays feed" request
|
||||||
|
if ($year2 - $year < 10 && ($age = ($this_year - $byear))) {
|
||||||
|
$event['description'] = $rcmail->gettext(array('name' => 'birthdayage', 'vars' => array('age' => $age)), 'calendar');
|
||||||
|
$event['start'] = $bday;
|
||||||
|
$event['end'] = clone $bday;
|
||||||
|
unset($event['recurrence']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$display_name = rcube_addressbook::compose_display_name($contact);
|
// add the main instance
|
||||||
$event_title = $rcmail->gettext(array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name)), 'calendar');
|
$events[] = $event;
|
||||||
|
|
||||||
// add stripped record to cache
|
|
||||||
if (empty($cached)) {
|
|
||||||
$cache_records[] = array(
|
|
||||||
'ID' => $contact['ID'],
|
|
||||||
'name' => $display_name,
|
|
||||||
'birthday' => $bday->format('Y-m-d'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by search term (only name is involved here)
|
|
||||||
if (!empty($search) && strpos(mb_strtolower($event_title), $search) === false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// quick-and-dirty recurrence computation: just replace the year
|
|
||||||
$bday->setDate($year, $bday->format('n'), $bday->format('j'));
|
|
||||||
$bday->setTime(12, 0, 0);
|
|
||||||
$this_year = $year;
|
|
||||||
|
|
||||||
// date range reaches over multiple years: use end year if not in range
|
|
||||||
if (($bday > $end || $bday < $start) && $year2 != $year) {
|
|
||||||
$bday->setDate($year2, $bday->format('n'), $bday->format('j'));
|
|
||||||
$this_year = $year2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// birthday is within requested range
|
|
||||||
if ($bday <= $end && $bday >= $start) {
|
|
||||||
$age = $this_year - $birthyear;
|
|
||||||
$uid = rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $this_year);
|
|
||||||
$event = array(
|
|
||||||
'id' => $uid,
|
|
||||||
'uid' => $uid,
|
|
||||||
'calendar' => self::BIRTHDAY_CALENDAR_ID,
|
|
||||||
'title' => $event_title,
|
|
||||||
'description' => $rcmail->gettext(array('name' => 'birthdayage', 'vars' => array('age' => $age)), 'calendar'),
|
|
||||||
// Add more contact information to description block?
|
|
||||||
'allday' => true,
|
|
||||||
'start' => $bday,
|
|
||||||
'alarms' => $alarms,
|
|
||||||
);
|
|
||||||
$event['end'] = clone $bday;
|
|
||||||
$event['end']->add(new DateInterval('PT1H'));
|
|
||||||
|
|
||||||
$events[] = $event;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,50 +728,72 @@ abstract class calendar_driver
|
||||||
$rcmail = rcmail::get_instance();
|
$rcmail = rcmail::get_instance();
|
||||||
|
|
||||||
if ($source && $contact_id && ($abook = $rcmail->get_address_book($source))) {
|
if ($source && $contact_id && ($abook = $rcmail->get_address_book($source))) {
|
||||||
$contact = $abook->get_record($contact_id, true);
|
if ($contact = $abook->get_record($contact_id, true)) {
|
||||||
|
return self::parse_contact($contact, $source);
|
||||||
if (is_array($contact) && !empty($contact['birthday'])) {
|
|
||||||
try {
|
|
||||||
if (is_array($contact['birthday']))
|
|
||||||
$contact['birthday'] = reset($contact['birthday']);
|
|
||||||
|
|
||||||
$bday = $contact['birthday'] instanceof DateTime ? $contact['birthday'] :
|
|
||||||
new DateTime($contact['birthday'], new DateTimezone('UTC'));
|
|
||||||
$birthyear = $bday->format('Y');
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
rcube::raise_error(array(
|
|
||||||
'code' => 600, 'type' => 'php',
|
|
||||||
'file' => __FILE__, 'line' => __LINE__,
|
|
||||||
'message' => 'BIRTHDAY PARSE ERROR: ' . $e),
|
|
||||||
true, false);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$display_name = rcube_addressbook::compose_display_name($contact);
|
|
||||||
$event_title = $rcmail->gettext(array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name)), 'calendar');
|
|
||||||
$uid = rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $birthyear);
|
|
||||||
|
|
||||||
$event = array(
|
|
||||||
'id' => $uid,
|
|
||||||
'uid' => $uid,
|
|
||||||
'calendar' => self::BIRTHDAY_CALENDAR_ID,
|
|
||||||
'title' => $event_title,
|
|
||||||
'description' => '',
|
|
||||||
'allday' => true,
|
|
||||||
'start' => $bday,
|
|
||||||
'recurrence' => array('FREQ' => 'YEARLY', 'INTERVAL' => 1),
|
|
||||||
'free_busy' => 'free',
|
|
||||||
);
|
|
||||||
$event['end'] = clone $bday;
|
|
||||||
$event['end']->add(new DateInterval('PT1H'));
|
|
||||||
|
|
||||||
return $event;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
/**
|
||||||
|
* Parse contact and create an event for its birthday
|
||||||
|
*
|
||||||
|
* @param array $contact Contact data
|
||||||
|
* @param string $source Addressbook source ID
|
||||||
|
*
|
||||||
|
* @return array Birthday event data
|
||||||
|
*/
|
||||||
|
public static function parse_contact($contact, $source)
|
||||||
|
{
|
||||||
|
if (!is_array($contact)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($contact['birthday'])) {
|
||||||
|
$contact['birthday'] = reset($contact['birthday']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($contact['birthday'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$bday = $contact['birthday'];
|
||||||
|
if (!$bday instanceof DateTime) {
|
||||||
|
$bday = new DateTime($bday, new DateTimezone('UTC'));
|
||||||
|
}
|
||||||
|
$bday->_dateonly = true;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
rcube::raise_error(array(
|
||||||
|
'code' => 600, 'type' => 'php',
|
||||||
|
'file' => __FILE__, 'line' => __LINE__,
|
||||||
|
'message' => 'BIRTHDAY PARSE ERROR: ' . $e->getMessage()),
|
||||||
|
true, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rcmail = rcmail::get_instance();
|
||||||
|
$birthyear = $bday->format('Y');
|
||||||
|
$display_name = rcube_addressbook::compose_display_name($contact);
|
||||||
|
$label = array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name));
|
||||||
|
$event_title = $rcmail->gettext($label, 'calendar');
|
||||||
|
$uid = rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $birthyear);
|
||||||
|
|
||||||
|
$event = array(
|
||||||
|
'id' => $uid,
|
||||||
|
'uid' => $uid,
|
||||||
|
'calendar' => self::BIRTHDAY_CALENDAR_ID,
|
||||||
|
'title' => $event_title,
|
||||||
|
'description' => '',
|
||||||
|
'allday' => true,
|
||||||
|
'start' => $bday,
|
||||||
|
'end' => clone $bday,
|
||||||
|
'recurrence' => array('FREQ' => 'YEARLY', 'INTERVAL' => 1),
|
||||||
|
'free_busy' => 'free',
|
||||||
|
'_displayname' => $display_name,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue