From 9b1de8593f006ca8a021b8bdf3e625b0696c2190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B6=C3=9Fl?= Date: Sat, 4 Aug 2012 10:48:25 +0200 Subject: [PATCH 1/2] Change in database scheme --- dav/database-init.inc.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dav/database-init.inc.php b/dav/database-init.inc.php index 7c0d23a3a..527b76714 100644 --- a/dav/database-init.inc.php +++ b/dav/database-init.inc.php @@ -66,7 +66,7 @@ function dav_get_update_statements($from_version) `carddata` mediumtext CHARACTER SET utf8 COLLATE utf8_unicode_ci, `uri` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, `lastmodified` timestamp NULL DEFAULT NULL, - `manually_edited` tinyint(4) NOT NULL DEFAULT '0', + `needs_rebuild` tinyint(4) NOT NULL DEFAULT '0', `manually_deleted` tinyint(4) NOT NULL DEFAULT '0', `etag` varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `size` int(10) unsigned NOT NULL, @@ -206,7 +206,7 @@ function dav_get_create_statements($except = array()) `carddata` mediumtext CHARACTER SET utf8 COLLATE utf8_unicode_ci, `uri` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, `lastmodified` timestamp NULL DEFAULT NULL, - `manually_edited` tinyint(4) NOT NULL DEFAULT '0', + `needs_rebuild` tinyint(4) NOT NULL DEFAULT '0', `manually_deleted` tinyint(4) NOT NULL DEFAULT '0', `etag` varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `size` int(10) unsigned NOT NULL, @@ -241,7 +241,7 @@ function dav_create_tables() $errors = array(); global $db; - foreach ($stms as $st) { + foreach ($stms as $st) { // @TODO Friendica-dependent $db->q($st); if ($db->error) $errors[] = $db->error; } @@ -261,7 +261,7 @@ function dav_upgrade_tables() $errors = array(); global $db; - foreach ($stms as $st) { + foreach ($stms as $st) { // @TODO Friendica-dependent $db->q($st); if ($db->error) $errors[] = $db->error; } From 87d314170bf0e89c8f16ec0d723744b3b09c454a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B6=C3=9Fl?= Date: Fri, 10 Aug 2012 21:41:17 +0200 Subject: [PATCH 2/2] First part of Refactoring to stay compatible with v2.0 of the VObject library --- dav/common/calendar.fnk.php | 64 ++---- dav/common/calendar_rendering.fnk.php | 28 +-- dav/common/dav_caldav_backend_common.inc.php | 20 +- .../dav_carddav_backend_virtual.inc.php | 186 ++++++++++++++---- dav/common/wdcal_backend.inc.php | 16 +- dav/common/wdcal_edit.inc.php | 50 ++--- dav/friendica/database-init.inc.php | 4 +- 7 files changed, 223 insertions(+), 145 deletions(-) diff --git a/dav/common/calendar.fnk.php b/dav/common/calendar.fnk.php index cd5efa57f..10177b347 100644 --- a/dav/common/calendar.fnk.php +++ b/dav/common/calendar.fnk.php @@ -99,51 +99,6 @@ class vcard_source_data public $photo; } -; - - -/** - * @param vcard_source_data $vcardsource - * @return string - */ -function vcard_source_compile($vcardsource) -{ - $str = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\n"; - $str .= "N:" . str_replace(";", ",", $vcardsource->name_last) . ";" . str_replace(";", ",", $vcardsource->name_first) . ";" . str_replace(";", ",", $vcardsource->name_middle) . ";;\r\n"; - $str .= "FN:" . str_replace(";", ",", $vcardsource->name_first) . " " . str_replace(";", ",", $vcardsource->name_middle) . " " . str_replace(";", ",", $vcardsource->name_last) . "\r\n"; - $str .= "REV:" . str_replace(" ", "T", $vcardsource->last_update) . "Z\r\n"; - - $item_count = 0; - for ($i = 0; $i < count($vcardsource->homepages); $i++) { - if ($i == 0) $str .= "URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n"; - else { - $c = ++$item_count; - $str .= "item$c.URL;type=" . $vcardsource->homepages[0]->type . ":" . $vcardsource->homepages[0]->homepage . "\r\n"; - $str .= "item$c.X-ABLabel:_\$!!\$_\r\n"; - } - } - - if (is_object($vcardsource->photo)) { - $data = base64_encode($vcardsource->photo->binarydata); - $str .= "PHOTO;ENCODING=BASE64;TYPE=" . $vcardsource->photo->type . ":" . $data . "\r\n"; - } - - if (isset($vcardsource->socialnetworks) && is_array($vcardsource->socialnetworks)) foreach ($vcardsource->socialnetworks as $netw) switch ($netw->type) { - case "dfrn": - $str .= "X-SOCIALPROFILE;type=dfrn;x-user=" . $netw->nick . ":" . $netw->url . "\r\n"; - break; - case "facebook": - $str .= "X-SOCIALPROFILE;type=facebook;x-user=" . $netw->nick . ":" . $netw->url . "\r\n"; - break; - case "twitter": - $str .= "X-SOCIALPROFILE;type=twitter;x-user=" . $netw->nick . ":" . $netw->url . "\r\n"; - break; - } - - $str .= "END:VCARD\r\n"; - return $str; -} - /** * @param int $phpDate (UTC) @@ -237,7 +192,7 @@ function dav_create_server($force_authentication = false, $needs_caldav = true, if (CALDAV_URL_PREFIX != "") $server->setBaseUri(CALDAV_URL_PREFIX); - $authPlugin = new Sabre_DAV_Auth_Plugin(Sabre_DAV_Auth_Backend_Std::getInstance(), 'SabreDAV'); + $authPlugin = new Sabre_DAV_Auth_Plugin(Sabre_DAV_Auth_Backend_Std::getInstance(), DAV_APPNAME); $server->addPlugin($authPlugin); if ($needs_caldav) { @@ -253,6 +208,10 @@ function dav_create_server($force_authentication = false, $needs_caldav = true, $aclPlugin = new $GLOBALS["CALDAV_ACL_PLUGIN_CLASS"](); $aclPlugin->defaultUsernamePath = "principals/users"; $server->addPlugin($aclPlugin); + } else { + $aclPlugin = new Sabre_DAVACL_Plugin(); + $aclPlugin->defaultUsernamePath = "principals/users"; + $server->addPlugin($aclPlugin); } if ($force_authentication) $server->broadcastEvent('beforeMethod', array("GET", "/")); // Make it authenticate @@ -298,7 +257,7 @@ function dav_get_current_user_calendars(&$server, $with_privilege = "") * @param Sabre_CalDAV_Calendar $calendar * @param string $calendarobject_uri * @param string $with_privilege - * @return null|Sabre_VObject_Component_VCalendar + * @return null|Sabre\VObject\Component\VCalendar */ function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "") { @@ -314,7 +273,7 @@ function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobje if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) return null; $data = $obj->get(); - $vObject = Sabre_VObject_Reader::read($data); + $vObject = Sabre\VObject\Reader::read($data); return $vObject; } @@ -342,20 +301,19 @@ function dav_get_current_user_calendar_by_id(&$server, $id, $with_privilege = "" /** * @param string $uid - * @return Sabre_VObject_Component_VCalendar $vObject + * @return Sabre\VObject\Component\VCalendar $vObject */ function dav_create_empty_vevent($uid = "") { - $a = get_app(); if ($uid == "") $uid = uniqid(); - return Sabre_VObject_Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . dav_compat_get_hostname() . + return Sabre\VObject\Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . dav_compat_get_hostname() . "\r\nDTSTAMP:" . date("Ymd") . "T" . date("His") . "Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"); } /** - * @param Sabre_VObject_Component_VCalendar $vObject - * @return Sabre_VObject_Component_VEvent|null + * @param Sabre\VObject\Component\VCalendar $vObject + * @return Sabre\VObject\Component\VEvent|null */ function dav_get_eventComponent(&$vObject) { diff --git a/dav/common/calendar_rendering.fnk.php b/dav/common/calendar_rendering.fnk.php index f82247957..6481c1019 100644 --- a/dav/common/calendar_rendering.fnk.php +++ b/dav/common/calendar_rendering.fnk.php @@ -3,8 +3,8 @@ /** - * @param Sabre_VObject_Component_VAlarm $alarm - * @param Sabre_VObject_Component_VEvent|Sabre_VObject_Component_VTodo $parent + * @param Sabre\VObject\Component\VAlarm $alarm + * @param Sabre\VObject\Component\VEvent|Sabre\VObject\Component\VTodo $parent * @return DateTime|null * @throws Sabre_DAV_Exception */ @@ -12,12 +12,12 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent) { $trigger = $alarm->__get("TRIGGER"); if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') { - $triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger->value); + $triggerDuration = Sabre\VObject\DateTimeParser::parseDuration($trigger->value); $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START'; if ($related === 'START') { - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $parent->__get("DTSTART"); $effectiveTrigger = $dtstart->getDateTime(); $effectiveTrigger->add($triggerDuration); @@ -28,14 +28,14 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent) $endProp = 'DTEND'; } - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $parent->__get("DTSTART"); if (isset($parent->$endProp)) { $effectiveTrigger = clone $parent->$endProp->getDateTime(); $effectiveTrigger->add($triggerDuration); } elseif ($parent->__get("DURATION") != "") { $effectiveTrigger = clone $dtstart->getDateTime(); - $duration = Sabre_VObject_DateTimeParser::parseDuration($parent->__get("DURATION")); + $duration = Sabre\VObject\DateTimeParser::parseDuration($parent->__get("DURATION")); $effectiveTrigger->add($duration); $effectiveTrigger->add($triggerDuration); } else { @@ -58,10 +58,10 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent) */ function renderCalDavEntry_data(&$calendar, &$calendarobject) { - /** @var Sabre_VObject_Component_VCalendar $vObject */ - $vObject = Sabre_VObject_Reader::read($calendarobject["calendardata"]); + /** @var Sabre\VObject\Component\VCalendar $vObject */ + $vObject = Sabre\VObject\Reader::read($calendarobject["calendardata"]); $componentType = null; - /** @var Sabre_VObject_Component_VEvent $component */ + /** @var Sabre\VObject\Component\VEvent $component */ $component = null; foreach ($vObject->getComponents() as $component) { if ($component->name !== 'VTIMEZONE') { @@ -86,18 +86,18 @@ function renderCalDavEntry_data(&$calendar, &$calendarobject) ); $recurring = ($component->__get("RRULE") ? 1 : 0); - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $component->__get("DTSTART"); - $allday = ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE ? 1 : 0); + $allday = ($dtstart->getDateType() == Sabre\VObject\Property\DateTime::DATE ? 1 : 0); - /** @var array|Sabre_VObject_Component_VAlarm[] $alarms */ + /** @var array|Sabre\VObject\Component\VAlarm[] $alarms */ $alarms = array(); foreach ($component->getComponents() as $a_component) if ($a_component->name == "VALARM") { - /** var Sabre_VObject_Component_VAlarm $component */ + /** var Sabre\VObject\Component_VAlarm $component */ $alarms[] = $a_component; } - $it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID")); + $it = new Sabre\VObject\RecurrenceIterator($vObject, (string)$component->__get("UID")); $last_end = 0; $max_ts = mktime(0, 0, 0, 1, 1, CALDAV_MAX_YEAR * 1); $first = true; diff --git a/dav/common/dav_caldav_backend_common.inc.php b/dav/common/dav_caldav_backend_common.inc.php index 99fcb6c10..97d5722a9 100644 --- a/dav/common/dav_caldav_backend_common.inc.php +++ b/dav/common/dav_caldav_backend_common.inc.php @@ -81,22 +81,22 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract /** * @static - * @param Sabre_VObject_Component_VEvent $component + * @param Sabre\VObject\Component\VEvent $component * @return int */ public static function getDtEndTimeStamp(&$component) { - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $component->__get("DTSTART"); if ($component->__get("DTEND")) { - /** @var Sabre_VObject_Property_DateTime $dtend */ + /** @var Sabre\VObject\Property\DateTime $dtend */ $dtend = $component->__get("DTEND"); return $dtend->getDateTime()->getTimeStamp(); } elseif ($component->__get("DURATION")) { $endDate = clone $dtstart->getDateTime(); - $endDate->add(Sabre_VObject_DateTimeParser::parse($component->__get("DURATION")->value)); + $endDate->add(Sabre\VObject\DateTimeParser::parse($component->__get("DURATION")->value)); return $endDate->getTimeStamp(); - } elseif ($dtstart->getDateType() === Sabre_VObject_Property_DateTime::DATE) { + } elseif ($dtstart->getDateType() === Sabre\VObject\Property\DateTime::DATE) { $endDate = clone $dtstart->getDateTime(); $endDate->modify('+1 day'); return $endDate->getTimeStamp(); @@ -124,8 +124,8 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract */ protected function getDenormalizedData($calendarData) { - /** @var Sabre_VObject_Component_VEvent $vObject */ - $vObject = Sabre_VObject_Reader::read($calendarData); + /** @var Sabre\VObject\Component\VEvent $vObject */ + $vObject = Sabre\VObject\Reader::read($calendarData); $componentType = null; $component = null; $firstOccurence = null; @@ -141,15 +141,15 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } if ($componentType === 'VEVENT') { - /** @var Sabre_VObject_Component_VEvent $component */ - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Component\VEvent $component */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $component->__get("DTSTART"); $firstOccurence = $dtstart->getDateTime()->getTimeStamp(); // Finding the last occurence is a bit harder if (!$component->__get("RRULE")) { $lastOccurence = self::getDtEndTimeStamp($component); } else { - $it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID")); + $it = new Sabre\VObject\RecurrenceIterator($vObject, (string)$component->__get("UID")); $maxDate = new DateTime(CALDAV_MAX_YEAR . "-01-01"); if ($it->isInfinite()) { $lastOccurence = $maxDate->getTimeStamp(); diff --git a/dav/common/dav_carddav_backend_virtual.inc.php b/dav/common/dav_carddav_backend_virtual.inc.php index 98597c694..f81a0a48c 100644 --- a/dav/common/dav_carddav_backend_virtual.inc.php +++ b/dav/common/dav_carddav_backend_virtual.inc.php @@ -16,65 +16,147 @@ abstract class Sabre_CardDAV_Backend_Virtual extends Sabre_CardDAV_Backend_Commo /** * @static - * @param int $uid - * @param int $namespace + * @param int $addressbookId */ - static public function invalidateCache($uid = 0, $namespace = 0) { - q("DELETE FROM %s%sadd_virtual_object_sync WHERE `uid` = %d AND `namespace` = %d", - CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($uid), IntVal($namespace)); + static public function invalidateCache($addressbookId) { + q("UPDATE %s%saddressbooks SET `needs_rebuild` = 1 WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressbookId)); } /** * @static * @abstract * @param int $addressbookId + * @param bool $force */ - static abstract protected function createCache_internal($addressbookId); + static abstract protected function createCache_internal($addressbookId, $force = false); + + /** + * @param int $addressbookId + * @param null|array $addressbook + * @param bool $force + */ + public function createCache($addressbookId, $addressbook = null, $force = false) { + $addressbookId = IntVal($addressbookId); + + if (!$addressbook) { + $add = q("SELECT `needs_rebuild`, `uri` FROM %s%saddressbooks WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + $addressbook = $add[0]; + } + if ($addressbook["needs_rebuild"] == 1 || $force) { + static::createCache_internal($addressbookId, $force); + q("UPDATE %s%saddressbooks SET `needs_rebuild` = 0, `ctag` = `ctag` + 1 WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + } + } /** * @static + * @abstract * @param int $addressbookId + * @param int $contactId + * @param bool $force */ - static protected function createCache($addressbookId) { - $addressbookId = IntVal($addressbookId); - q("DELETE FROM %s%saddressbookobjects WHERE `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); - static::createCache_internal($addressbookId); - q("REPLACE INTO %s%sadd_virtual_object_sync (`addressbook_id`, `date`) VALUES (%d, NOW())", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); - } - + static abstract protected function createCardCache($addressbookId, $contactId, $force = false); /** - * @param string $addressbookId + * @param int $addressbookId * @return array */ public function getCards($addressbookId) { $addressbookId = IntVal($addressbookId); - $r = q("SELECT COUNT(*) n FROM %s%sadd_virtual_object_sync WHERE `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + $add = q("SELECT * FROM %s%saddressbooks WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + if ($add[0]["needs_rebuild"]) { + static::createCache_internal($addressbookId); + q("UPDATE %s%saddressbooks SET `needs_rebuild` = 0, `ctag` = `ctag` + 1 WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + $add[0]["needs_rebuild"] = 0; + $add[0]["ctag"]++; + } - if ($r[0]["n"] == 0) static::createCache($addressbookId); + $ret = array(); + $x = q("SELECT * FROM %s%saddressbookobjects WHERE `addressbook_id` = %d AND `manually_deleted` = 0", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + foreach ($x as $y) $ret[] = self::getCard($addressbookId, $add[0]["uri"], $add[0], $y); - return q("SELECT * FROM %s%saddressbookobjects WHERE `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + return $ret; + } + + /** + * Replaces the x-prop_name value. Replaces the prop_name value IF the old value is the same as the old value of x-prop_name (meaning: the user has not manually changed it) + * + * @param Sabre\VObject\Component $component + * @param string $prop_name + * @param string $prop_value + * @param array $parameters + * @return void + */ + static public function card_set_automatic_value(&$component, $prop_name, $prop_value, $parameters = array()) { + $automatic = $component->select("X-" . $prop_name); + $curr = $component->select($prop_name); + + if (count($automatic) == 0) { + $prop = new Sabre\VObject\Property('X-' . $prop_name, $prop_value); + foreach ($parameters as $key=>$val) $prop->add($key, $val); + $component->children[] = $prop; + + if (count($curr) == 0) { + $prop = new Sabre\VObject\Property($prop_name, $prop_value); + foreach ($parameters as $key=>$val) $prop->add($key, $val); + $component->children[] = $prop; + } + + } else foreach ($automatic as $auto_prop) { + /** @var Sabre\VObject\Property $auto_prop */ + /** @var Sabre\VObject\Property $actual_prop */ + foreach ($curr as $actual_prop) { + if ($auto_prop->value == $actual_prop->value) $actual_prop->setValue($prop_value); + } + $auto_prop->setValue($prop_value); + } + } + + + + /** + * Deletes the x-prop_name value. Deletes the prop_name value IF the old value is the same as the old value of x-prop_name (meaning: the user has not manually changed it) + * + * @param Sabre\VObject\Component $component + * @param string $prop_name + * @param array $parameters + */ + static public function card_del_automatic_value(&$component, $prop_name, $parameters = array()) { + // @TODO } /** - * @param string $addressbookId + * @param int $addressbookId * @param string $objectUri + * @param array $book + * @param array $obj * @throws Sabre_DAV_Exception_NotFound * @return array */ - public function getCard($addressbookId, $objectUri) + public function getCard($addressbookId, $objectUri, $book = null, $obj = null) { $addressbookId = IntVal($addressbookId); - $r = q("SELECT COUNT(*) n FROM %s%sadd_virtual_object_sync WHERE `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressbookId)); - if ($r[0]["n"] == 0) static::createCache($addressbookId); + if ($book == null) { + $add = q("SELECT `needs_rebuild`, `uri` FROM %s%saddressbooks WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + $book = $add[0]; + } + if ($book["needs_rebuild"] == 1) { + static::createCache_internal($addressbookId); + q("UPDATE %s%saddressbooks SET `needs_rebuild` = 0, `ctag` = `ctag` + 1 WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $addressbookId); + $add[0]["needs_rebuild"] = 0; + } - $r = q("SELECT * FROM %s%saddressbookobjects WHERE `uri` = '%s' AND `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($objectUri), IntVal($addressbookId)); - if (count($r) == 0) throw new Sabre_DAV_Exception_NotFound(); + if ($obj == null) { + $r = q("SELECT * FROM %s%saddressbookobjects WHERE `uri` = '%s' AND `addressbook_id` = %d AND `manually_deleted` = 0", + CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($objectUri), IntVal($addressbookId)); + if (count($r) == 0) throw new Sabre_DAV_Exception_NotFound(); + $obj = $r[0]; + if ($obj["needs_rebuild"] == 1) $obj = static::createCardCache($addressbookId, $obj["contact"]); + } - $obj = $r[0]; $ret = array( "id" => IntVal($obj["uri"]), "carddata" => $obj["carddata"], @@ -125,26 +207,62 @@ abstract class Sabre_CardDAV_Backend_Virtual extends Sabre_CardDAV_Backend_Commo } /** - * @param string $addressbookId - * @param string $objectUri + * Updates a card. + * + * The addressbook id will be passed as the first argument. This is the + * same id as it is returned from the getAddressbooksForUser method. + * + * The cardUri is a base uri, and doesn't include the full path. The + * cardData argument is the vcard body, and is passed as a string. + * + * It is possible to return an ETag from this method. This ETag should + * match that of the updated resource, and must be enclosed with double + * quotes (that is: the string itself must contain the actual quotes). + * + * You should only return the ETag if you store the carddata as-is. If a + * subsequent GET request on the same card does not have the same body, + * byte-by-byte and you did return an ETag here, clients tend to get + * confused. + * + * If you don't return an ETag, you can just return null. + * + * @param string $addressBookId + * @param string $cardUri * @param string $cardData * @throws Sabre_DAV_Exception_Forbidden - * @return null|string|void + * @return string|null */ - function updateCard($addressbookId, $objectUri, $cardData) + public function updateCard($addressBookId, $cardUri, $cardData) { - throw new Sabre_DAV_Exception_Forbidden(); + echo "Die!"; die(); // @TODO + $x = explode("-", $addressBookId); + + $etag = md5($cardData); + q("UPDATE %s%scards SET carddata = '%s', lastmodified = %d, etag = '%s', size = %d, manually_edited = 1 WHERE uri = '%s' AND namespace = %d AND namespace_id =%d", + CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($cardData), time(), $etag, strlen($cardData), dbesc($cardUri), IntVal($x[10]), IntVal($x[1]) + ); + q('UPDATE %s%saddressbooks_community SET ctag = ctag + 1 WHERE uid = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[1])); + + return '"' . $etag . '"'; } + + + /** - * @param string $addressbookId - * @param string $objectUri + * Deletes a card + * + * @param string $addressBookId + * @param string $cardUri * @throws Sabre_DAV_Exception_Forbidden - * @return void + * @return bool */ - function deleteCard($addressbookId, $objectUri) + public function deleteCard($addressBookId, $cardUri) { - throw new Sabre_DAV_Exception_Forbidden(); + q("UPDATE %s%scards SET `manually_deleted` = 1 WHERE `addressbook_id` = %d AND `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId), dbesc($cardUri)); + q('UPDATE %s%saddressbooks SET ctag = ctag + 1 WHERE `id` = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId)); + + return true; } diff --git a/dav/common/wdcal_backend.inc.php b/dav/common/wdcal_backend.inc.php index 9233da6e2..330f29889 100644 --- a/dav/common/wdcal_backend.inc.php +++ b/dav/common/wdcal_backend.inc.php @@ -97,12 +97,12 @@ function wdcal_print_feed($base_path = "") $component = dav_get_eventComponent($item); $component->add("SUMMARY", icalendar_sanitize_string(dav_compat_parse_text_serverside("CalendarTitle"))); - if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE; - else $type = Sabre_VObject_Property_DateTime::LOCALTZ; + if (isset($_REQUEST["allday"])) $type = Sabre\VObject\Property\DateTime::DATE; + else $type = Sabre\VObject\Property\DateTime::LOCALTZ; - $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART"); + $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART"); $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type); - $datetime_end = new Sabre_VObject_Property_DateTime("DTEND"); + $datetime_end = new Sabre\VObject\Property\DateTime("DTEND"); $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type); $component->add($datetime_start); @@ -179,12 +179,12 @@ function wdcal_print_feed($base_path = "") killme(); } - if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE; - else $type = Sabre_VObject_Property_DateTime::LOCALTZ; + if (isset($_REQUEST["allday"])) $type = Sabre\VObject\Property\DateTime::DATE; + else $type = Sabre\VObject\Property\DateTime::LOCALTZ; - $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART"); + $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART"); $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type); - $datetime_end = new Sabre_VObject_Property_DateTime("DTEND"); + $datetime_end = new Sabre\VObject\Property\DateTime("DTEND"); $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type); $component->__unset("DTSTART"); diff --git a/dav/common/wdcal_edit.inc.php b/dav/common/wdcal_edit.inc.php index dac493683..d507a9000 100644 --- a/dav/common/wdcal_edit.inc.php +++ b/dav/common/wdcal_edit.inc.php @@ -29,7 +29,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $calendar_id, $uri) if ($component == null) return t('Could not open component for editing'); - /** @var Sabre_VObject_Property_DateTime $dtstart */ + /** @var Sabre\VObject\Property\DateTime $dtstart */ $dtstart = $component->__get("DTSTART"); $event = array( "id" => IntVal($uri), @@ -44,7 +44,7 @@ function wdcal_getEditPage_str(&$localization, $baseurl, $calendar_id, $uri) $exdates = $component->select("EXDATE"); $recurrentce_exdates = array(); - /** @var Sabre_VObject_Property_MultiDateTime $x */ + /** @var Sabre\VObject\Property\MultiDateTime $x */ foreach ($exdates as $x) { /** @var DateTime $y */ $z = $x->getDateTimes(); @@ -511,15 +511,15 @@ function wdcal_set_component_date(&$component, &$localization) if (isset($_REQUEST["allday"])) { $ts_start = $localization->date_local2timestamp($_REQUEST["start_date"] . " 00:00"); $ts_end = $localization->date_local2timestamp($_REQUEST["end_date"] . " 00:00"); - $type = Sabre_VObject_Property_DateTime::DATE; + $type = Sabre\VObject\Property\DateTime::DATE; } else { $ts_start = $localization->date_local2timestamp($_REQUEST["start_date"] . " " . $_REQUEST["start_time"]); $ts_end = $localization->date_local2timestamp($_REQUEST["end_date"] . " " . $_REQUEST["end_time"]); - $type = Sabre_VObject_Property_DateTime::LOCALTZ; + $type = Sabre\VObject\Property\DateTime::LOCALTZ; } - $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART"); + $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART"); $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_start)), $type); - $datetime_end = new Sabre_VObject_Property_DateTime("DTEND"); + $datetime_end = new Sabre\VObject\Property\DateTime("DTEND"); $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_end)), $type); $component->__unset("DTSTART"); @@ -539,7 +539,7 @@ function wdcal_set_component_date(&$component, &$localization) function wdcal_set_component_recurrence_special(&$component, $str) { $ret = ""; - /** @var Sabre_VObject_Property_DateTime $start */ + /** @var Sabre\VObject\Property\DateTime $start */ $start = $component->__get("DTSTART"); $dayMap = array( 0 => 'SU', @@ -595,8 +595,8 @@ function wdcal_set_component_recurrence(&$component, &$localization) case "date": $date = $localization->date_local2timestamp($_REQUEST["rec_until_date"]); $part_until = ";UNTIL=" . date("Ymd", $date); - $datetime_until = new Sabre_VObject_Property_DateTime("UNTIL"); - $datetime_until->setDateTime(new DateTime(date("Y-m-d H:i:s", $date)), Sabre_VObject_Property_DateTime::DATE); + $datetime_until = new Sabre\VObject\Property\DateTime("UNTIL"); + $datetime_until->setDateTime(new DateTime(date("Y-m-d H:i:s", $date)), Sabre\VObject\Property\DateTime::DATE); break; case "count": $part_until = ";COUNT=" . IntVal($_REQUEST["rec_until_count"]); @@ -626,7 +626,7 @@ function wdcal_set_component_recurrence(&$component, &$localization) $part_freq .= wdcal_set_component_recurrence_special($component, $_REQUEST["rec_monthly_day"]); break; case "yearly": - /** @var Sabre_VObject_Property_DateTime $start */ + /** @var Sabre\VObject\Property\DateTime $start */ $start = $component->__get("DTSTART"); $part_freq = "FREQ=YEARLY"; $part_freq .= ";BYMONTH=" . $start->getDateTime()->format("n"); @@ -645,20 +645,20 @@ function wdcal_set_component_recurrence(&$component, &$localization) foreach ($_REQUEST["rec_exceptions"] as $except) { $arr[] = new DateTime(date("Y-m-d H:i:s", $except)); } - /** @var Sabre_VObject_Property_MultiDateTime $prop */ - $prop = Sabre_VObject_Property::create("EXDATE"); + /** @var Sabre\VObject\Property\MultiDateTime $prop */ + $prop = Sabre\VObject\Property::create("EXDATE"); $prop->setDateTimes($arr); $component->add($prop); } $rrule = $part_freq . $part_until; - $component->add(new Sabre_VObject_Property("RRULE", $rrule)); + $component->add(new Sabre\VObject\Property("RRULE", $rrule)); } /** - * @param Sabre_VObject_Component_VEvent $component + * @param Sabre\VObject\Component\VEvent $component * @param wdcal_local $localization * @param string $summary * @param int $dtstart @@ -671,12 +671,12 @@ function wdcal_set_component_alerts(&$component, &$localization, $summary, $dtst $component->__unset("VALARM"); foreach ($prev_alarms as $al) { - /** @var Sabre_VObject_Component_VAlarm $al */ + /** @var Sabre\VObject\Component\VAlarm $al */ // @TODO Parse notifications that have been there before; e.g. from Lightning } foreach (array_keys($_REQUEST["noti_type"]) as $key) if (is_numeric($key) || ($key == "new" && $_REQUEST["new_alarm"] == 1)) { - $alarm = new Sabre_VObject_Component_VAlarm("VALARM"); + $alarm = new Sabre\VObject\Component\VAlarm("VALARM"); switch ($_REQUEST["noti_type"][$key]) { case "email": @@ -686,15 +686,15 @@ function wdcal_set_component_alerts(&$component, &$localization, $summary, $dtst $localization->date_timestamp2local($dtstart), $summary, ), t("The event #name# will start at #date")); - $alarm->add(new Sabre_VObject_Property("ACTION", "EMAIL")); - $alarm->add(new Sabre_VObject_Property("SUMMARY", $summary)); - $alarm->add(new Sabre_VObject_Property("DESCRIPTION", $mailtext)); - $alarm->add(new Sabre_VObject_Property("ATTENDEE", "MAILTO:" . $a->user["email"])); + $alarm->add(new Sabre\VObject\Property("ACTION", "EMAIL")); + $alarm->add(new Sabre\VObject\Property("SUMMARY", $summary)); + $alarm->add(new Sabre\VObject\Property("DESCRIPTION", $mailtext)); + $alarm->add(new Sabre\VObject\Property("ATTENDEE", "MAILTO:" . $a->user["email"])); break; case "display": - $alarm->add(new Sabre_VObject_Property("ACTION", "DISPLAY")); + $alarm->add(new Sabre\VObject\Property("ACTION", "DISPLAY")); $text = str_replace("#name#", $summary, t("#name# is about to begin.")); - $alarm->add(new Sabre_VObject_Property("DESCRIPTION", $text)); + $alarm->add(new Sabre\VObject\Property("DESCRIPTION", $text)); break; default: continue; @@ -706,7 +706,7 @@ function wdcal_set_component_alerts(&$component, &$localization, $summary, $dtst $trigger_val .= "-P"; if (in_array($_REQUEST["noti_unit"][$key], array("H", "M", "S"))) $trigger_val .= "T"; $trigger_val .= IntVal($_REQUEST["noti_value"][$key]) . $_REQUEST["noti_unit"][$key]; - $alarm->add(new Sabre_VObject_Property($trigger_name, $trigger_val)); + $alarm->add(new Sabre\VObject\Property($trigger_name, $trigger_val)); $component->add($alarm); } @@ -785,12 +785,12 @@ function wdcal_getEditPage_exception_selector() foreach ($vObject->getComponents() as $component) { if ($component->name !== 'VTIMEZONE') break; } - /** @var Sabre_VObject_Component_VEvent $component */ + /** @var Sabre\VObject\Component\VEvent $component */ wdcal_set_component_date($component, $localization); wdcal_set_component_recurrence($component, $localization); - $it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID")); + $it = new Sabre\VObject\RecurrenceIterator($vObject, (string)$component->__get("UID")); $max_ts = mktime(0, 0, 0, 1, 1, CALDAV_MAX_YEAR + 1); $last_start = 0; diff --git a/dav/friendica/database-init.inc.php b/dav/friendica/database-init.inc.php index 527b76714..5978fd01e 100644 --- a/dav/friendica/database-init.inc.php +++ b/dav/friendica/database-init.inc.php @@ -54,6 +54,7 @@ function dav_get_update_statements($from_version) `namespace_id` int(11) unsigned NOT NULL, `displayname` varchar(200) NOT NULL, `description` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, + `needs_rebuild` TINYINT NOT NULL DEFAULT '1', `uri` varchar(50) NOT NULL, `ctag` int(11) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`id`) @@ -194,6 +195,7 @@ function dav_get_create_statements($except = array()) `namespace_id` int(11) unsigned NOT NULL, `displayname` varchar(200) NOT NULL, `description` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, + `needs_rebuild` TINYINT NOT NULL DEFAULT '1', `uri` varchar(50) NOT NULL, `ctag` int(11) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`id`) @@ -267,4 +269,4 @@ function dav_upgrade_tables() } return $errors; -} \ No newline at end of file +}