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:
Aleksander Machniak 2016-04-14 11:42:04 +02:00 committed by Jeroen van Meeuwen (Kolab Systems)
parent 9d883ed07d
commit a7f5885d8d

View file

@ -655,41 +655,29 @@ 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'));
$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);
continue; continue;
} }
$display_name = rcube_addressbook::compose_display_name($contact);
$event_title = $rcmail->gettext(array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name)), 'calendar');
// add stripped record to cache // add stripped record to cache
if (empty($cached)) { if (empty($cached)) {
$cache_records[] = array( $cache_records[] = array(
'ID' => $contact['ID'], 'ID' => $contact['ID'],
'name' => $display_name, 'name' => $event['_displayname'],
'birthday' => $bday->format('Y-m-d'), 'birthday' => $event['start']->format('Y-m-d'),
); );
} }
// filter by search term (only name is involved here) // filter by search term (only name is involved here)
if (!empty($search) && strpos(mb_strtolower($event_title), $search) === false) { if (!empty($search) && strpos(mb_strtolower($event['title']), $search) === false) {
continue; continue;
} }
$bday = clone $event['start'];
$byear = $bday->format('Y');
// quick-and-dirty recurrence computation: just replace the year // quick-and-dirty recurrence computation: just replace the year
$bday->setDate($year, $bday->format('n'), $bday->format('j')); $bday->setDate($year, $bday->format('n'), $bday->format('j'));
$bday->setTime(12, 0, 0); $bday->setTime(12, 0, 0);
@ -703,24 +691,20 @@ abstract class calendar_driver
// birthday is within requested range // birthday is within requested range
if ($bday <= $end && $bday >= $start) { if ($bday <= $end && $bday >= $start) {
$age = $this_year - $birthyear; unset($event['_displayname']);
$uid = rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $this_year); $event['alarms'] = $alarms;
$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; // 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']);
} }
// add the main instance
$events[] = $event;
} }
} }
@ -744,29 +728,55 @@ 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 { * Parse contact and create an event for its birthday
if (is_array($contact['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']); $contact['birthday'] = reset($contact['birthday']);
}
$bday = $contact['birthday'] instanceof DateTime ? $contact['birthday'] : if (empty($contact['birthday'])) {
new DateTime($contact['birthday'], new DateTimezone('UTC')); return;
$birthyear = $bday->format('Y'); }
try {
$bday = $contact['birthday'];
if (!$bday instanceof DateTime) {
$bday = new DateTime($bday, new DateTimezone('UTC'));
}
$bday->_dateonly = true;
} }
catch (Exception $e) { catch (Exception $e) {
rcube::raise_error(array( rcube::raise_error(array(
'code' => 600, 'type' => 'php', 'code' => 600, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__, 'file' => __FILE__, 'line' => __LINE__,
'message' => 'BIRTHDAY PARSE ERROR: ' . $e), 'message' => 'BIRTHDAY PARSE ERROR: ' . $e->getMessage()),
true, false); true, false);
return;
return null;
} }
$rcmail = rcmail::get_instance();
$birthyear = $bday->format('Y');
$display_name = rcube_addressbook::compose_display_name($contact); $display_name = rcube_addressbook::compose_display_name($contact);
$event_title = $rcmail->gettext(array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name)), 'calendar'); $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); $uid = rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $birthyear);
$event = array( $event = array(
@ -777,18 +787,14 @@ abstract class calendar_driver
'description' => '', 'description' => '',
'allday' => true, 'allday' => true,
'start' => $bday, 'start' => $bday,
'end' => clone $bday,
'recurrence' => array('FREQ' => 'YEARLY', 'INTERVAL' => 1), 'recurrence' => array('FREQ' => 'YEARLY', 'INTERVAL' => 1),
'free_busy' => 'free', 'free_busy' => 'free',
'_displayname' => $display_name,
); );
$event['end'] = clone $bday;
$event['end']->add(new DateInterval('PT1H'));
return $event; return $event;
} }
}
return null;
}
/** /**
* Store alarm dismissal for birtual birthay events * Store alarm dismissal for birtual birthay events