Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace coffin emoji with cross #16722

Merged
merged 1 commit into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 132 additions & 49 deletions apps/dav/lib/CalDAV/BirthdayService.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @copyright Copyright (c) 2016, Georg Ehrke
* @copyright Copyright (c) 2019, Georg Ehrke
*
* @author Achim Königs <garfonso@tratschtante.de>
* @author Georg Ehrke <oc.list@georgehrke.com>
Expand Down Expand Up @@ -33,6 +34,7 @@
use OCA\DAV\DAV\GroupPrincipalBackend;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IL10N;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VCard;
use Sabre\VObject\DateTimeParser;
Expand All @@ -41,6 +43,11 @@
use Sabre\VObject\Property\VCard\DateAndOrTime;
use Sabre\VObject\Reader;

/**
* Class BirthdayService
*
* @package OCA\DAV\CalDAV
*/
class BirthdayService {

const BIRTHDAY_CALENDAR_URI = 'contact_birthdays';
Expand All @@ -60,28 +67,41 @@ class BirthdayService {
/** @var IDBConnection */
private $dbConnection;

/** @var IL10N */
private $l10n;

/**
* BirthdayService constructor.
*
* @param CalDavBackend $calDavBackEnd
* @param CardDavBackend $cardDavBackEnd
* @param GroupPrincipalBackend $principalBackend
* @param IConfig $config;
* @param IConfig $config
* @param IDBConnection $dbConnection
* @param IL10N $l10n
*/
public function __construct(CalDavBackend $calDavBackEnd, CardDavBackend $cardDavBackEnd, GroupPrincipalBackend $principalBackend, IConfig $config, IDBConnection $dbConnection) {
public function __construct(CalDavBackend $calDavBackEnd,
CardDavBackend $cardDavBackEnd,
GroupPrincipalBackend $principalBackend,
IConfig $config,
IDBConnection $dbConnection,
IL10N $l10n) {
$this->calDavBackEnd = $calDavBackEnd;
$this->cardDavBackEnd = $cardDavBackEnd;
$this->principalBackend = $principalBackend;
$this->config = $config;
$this->dbConnection = $dbConnection;
$this->l10n = $l10n;
}

/**
* @param int $addressBookId
* @param string $cardUri
* @param string $cardData
*/
public function onCardChanged($addressBookId, $cardUri, $cardData) {
public function onCardChanged(int $addressBookId,
string $cardUri,
string $cardData) {
if (!$this->isGloballyEnabled()) {
return;
}
Expand All @@ -90,18 +110,19 @@ public function onCardChanged($addressBookId, $cardUri, $cardData) {
$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
$targetPrincipals[] = $book['principaluri'];
$datesToSync = [
['postfix' => '', 'field' => 'BDAY', 'symbol' => '*', 'utfSymbol' => '🎂'],
['postfix' => '-death', 'field' => 'DEATHDATE', 'symbol' => "†", 'utfSymbol' => '⚰️'],
['postfix' => '-anniversary', 'field' => 'ANNIVERSARY', 'symbol' => "⚭", 'utfSymbol' => '💍'],
['postfix' => '', 'field' => 'BDAY'],
['postfix' => '-death', 'field' => 'DEATHDATE'],
['postfix' => '-anniversary', 'field' => 'ANNIVERSARY'],
];

foreach ($targetPrincipals as $principalUri) {
if (!$this->isUserEnabled($principalUri)) {
continue;
}

$calendar = $this->ensureCalendarExists($principalUri);
foreach ($datesToSync as $type) {
$this->updateCalendar($cardUri, $cardData, $book, $calendar['id'], $type);
$this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type);
}
}
}
Expand All @@ -110,7 +131,8 @@ public function onCardChanged($addressBookId, $cardUri, $cardData) {
* @param int $addressBookId
* @param string $cardUri
*/
public function onCardDeleted($addressBookId, $cardUri) {
public function onCardDeleted(int $addressBookId,
string $cardUri) {
if (!$this->isGloballyEnabled()) {
return;
}
Expand All @@ -136,7 +158,7 @@ public function onCardDeleted($addressBookId, $cardUri) {
* @return array|null
* @throws \Sabre\DAV\Exception\BadRequest
*/
public function ensureCalendarExists($principal) {
public function ensureCalendarExists(string $principal):?array {
$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
if (!is_null($calendar)) {
return $calendar;
Expand All @@ -151,14 +173,15 @@ public function ensureCalendarExists($principal) {
}

/**
* @param string $cardData
* @param string $dateField
* @param string $postfix
* @param string $summarySymbol
* @param string $utfSummarySymbol
* @return null|VCalendar
* @param $cardData
* @param $dateField
* @param $postfix
* @return VCalendar|null
* @throws InvalidDataException
*/
public function buildDateFromContact($cardData, $dateField, $postfix, $summarySymbol, $utfSummarySymbol) {
public function buildDateFromContact(string $cardData,
string $dateField,
string $postfix):?VCalendar {
if (empty($cardData)) {
return null;
}
Expand Down Expand Up @@ -224,19 +247,8 @@ public function buildDateFromContact($cardData, $dateField, $postfix, $summarySy
} catch (Exception $e) {
return null;
}
if ($this->dbConnection->supports4ByteText()) {
if ($unknownYear) {
$summary = $utfSummarySymbol . ' ' . $doc->FN->getValue();
} else {
$summary = $utfSummarySymbol . ' ' . $doc->FN->getValue() . " ($originalYear)";
}
} else {
if ($unknownYear) {
$summary = $doc->FN->getValue() . ' ' . $summarySymbol;
} else {
$summary = $doc->FN->getValue() . " ($summarySymbol$originalYear)";
}
}

$summary = $this->formatTitle($dateField, $doc->FN->getValue(), $originalYear, $this->dbConnection->supports4ByteText());

$vCal = new VCalendar();
$vCal->VERSION = '2.0';
Expand Down Expand Up @@ -273,7 +285,7 @@ public function buildDateFromContact($cardData, $dateField, $postfix, $summarySy
/**
* @param string $user
*/
public function resetForUser($user) {
public function resetForUser(string $user):void {
$principal = 'principals/users/'.$user;
$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
$calendarObjects = $this->calDavBackEnd->getCalendarObjects($calendar['id'], CalDavBackend::CALENDAR_TYPE_CALENDAR);
Expand All @@ -285,8 +297,9 @@ public function resetForUser($user) {

/**
* @param string $user
* @throws \Sabre\DAV\Exception\BadRequest
*/
public function syncUser($user) {
public function syncUser(string $user):void {
$principal = 'principals/users/'.$user;
$this->ensureCalendarExists($principal);
$books = $this->cardDavBackEnd->getAddressBooksForUser($principal);
Expand All @@ -303,25 +316,25 @@ public function syncUser($user) {
* @param VCalendar $newCalendarData
* @return bool
*/
public function birthdayEvenChanged($existingCalendarData, $newCalendarData) {
public function birthdayEvenChanged(string $existingCalendarData,
VCalendar $newCalendarData):bool {
try {
$existingBirthday = Reader::read($existingCalendarData);
} catch (Exception $ex) {
return true;
}
if ($newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||

return (
$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
) {
return true;
}
return false;
);
}

/**
* @param integer $addressBookId
* @return mixed
*/
protected function getAllAffectedPrincipals($addressBookId) {
protected function getAllAffectedPrincipals(int $addressBookId) {
$targetPrincipals = [];
$shares = $this->cardDavBackEnd->getShares($addressBookId);
foreach ($shares as $share) {
Expand All @@ -339,14 +352,20 @@ protected function getAllAffectedPrincipals($addressBookId) {

/**
* @param string $cardUri
* @param string $cardData
* @param string $cardData
* @param array $book
* @param int $calendarId
* @param string[] $type
* @param array $type
* @throws InvalidDataException
* @throws \Sabre\DAV\Exception\BadRequest
*/
private function updateCalendar($cardUri, $cardData, $book, $calendarId, $type) {
private function updateCalendar(string $cardUri,
string $cardData,
array $book,
int $calendarId,
array $type):void {
$objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics';
$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix'], $type['symbol'], $type['utfSymbol']);
$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']);
$existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri);
if (is_null($calendarData)) {
if (!is_null($existing)) {
Expand All @@ -368,18 +387,17 @@ private function updateCalendar($cardUri, $cardData, $book, $calendarId, $type)
*
* @return bool
*/
private function isGloballyEnabled() {
$isGloballyEnabled = $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes');
return $isGloballyEnabled === 'yes';
private function isGloballyEnabled():bool {
return $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes') === 'yes';
}

/**
* checks if the user opted-out of birthday calendars
* Checks if the user opted-out of birthday calendars
*
* @param $userPrincipal
* @param string $userPrincipal The user principal to check for
* @return bool
*/
private function isUserEnabled($userPrincipal) {
private function isUserEnabled(string $userPrincipal):bool {
if (strpos($userPrincipal, 'principals/users/') === 0) {
$userId = substr($userPrincipal, 17);
$isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes');
Expand All @@ -390,4 +408,69 @@ private function isUserEnabled($userPrincipal) {
return true;
}

/**
* Formats title of Birthday event
*
* @param string $field Field name like BDAY, ANNIVERSARY, ...
* @param string $name Name of contact
* @param int|null $year Year of birth, anniversary, ...
* @param bool $supports4Byte Whether or not the database supports 4 byte chars
* @return string The formatted title
*/
private function formatTitle(string $field,
string $name,
int $year=null,
bool $supports4Byte=true):string {
if ($supports4Byte) {
switch ($field) {
case 'BDAY':
return implode('', [
'🎂 ',
$name,
$year ? (' (' . $year . ')') : '',
]);

case 'DEATHDATE':
return implode('', [
$this->l10n->t('Death of %s', [$name]),
$year ? (' (' . $year . ')') : '',
]);

case 'ANNIVERSARY':
return implode('', [
'💍 ',
$name,
$year ? (' (' . $year . ')') : '',
]);

default:
return '';
}
} else {
switch($field) {
case 'BDAY':
return implode('', [
$name,
' ',
$year ? ('(*' . $year . ')') : '*',
]);

case 'DEATHDATE':
return implode('', [
$this->l10n->t('Death of %s', [$name]),
$year ? (' (' . $year . ')') : '',
]);

case 'ANNIVERSARY':
return implode('', [
$name,
' ',
$year ? ('(⚭' . $year . ')') : '⚭',
]);

default:
return '';
}
}
}
}
Loading