332 lines
12 KiB
PHP
332 lines
12 KiB
PHP
|
<?php
|
||
|
|
||
|
class AnimexxCalSourcePrivate extends AnimexxCalSource
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* @return int
|
||
|
*/
|
||
|
public static function getNamespace()
|
||
|
{
|
||
|
return CALDAV_NAMESPACE_PRIVATE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param int $user
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getPermissionsCalendar($user)
|
||
|
{
|
||
|
if ($user == $this->calendarDb->uid) return array("read"=> true, "write"=> true);
|
||
|
return array("read"=> false, "write"=> false);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param int $user
|
||
|
* @param string $item_uri
|
||
|
* @param string $recurrence_uri
|
||
|
* @param null|array $item_arr
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getPermissionsItem($user, $item_uri, $recurrence_uri, $item_arr = null)
|
||
|
{
|
||
|
$cal_perm = $this->getPermissionsCalendar($user);
|
||
|
if (!$cal_perm["read"]) return array("read"=> false, "write"=> false);
|
||
|
if (!$cal_perm["write"]) array("read"=> true, "write"=> false);
|
||
|
|
||
|
if ($item_arr === null) {
|
||
|
$x = q("SELECT `permission_edit` FROM %s%sjqcalendar WHERE `namespace` = %d AND `namespace_id` = %d AND `ical_uri` = '%s' AND `ical_recurr_uri` = '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->getNamespace(), $this->namespace_id, dbesc($item_uri), dbesc($recurrence_uri)
|
||
|
);
|
||
|
if (!$x || count($x) == 0) return array("read"=> false, "write"=> false);
|
||
|
return array("read"=> true, "write"=> ($x[0]["permission_edit"]));
|
||
|
} else {
|
||
|
return array("read"=> true, "write"=> ($item_arr["permission_edit"]));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $uri
|
||
|
* @throws Sabre_DAV_Exception_NotFound
|
||
|
*/
|
||
|
public function removeItem($uri){
|
||
|
$obj_alt = q("SELECT * FROM %s%sjqcalendar WHERE namespace = %d AND namespace_id = %d AND ical_uri = '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->getNamespace(), $this->namespace_id, dbesc($uri));
|
||
|
|
||
|
if (count($obj_alt) == 0) throw new Sabre_DAV_Exception_NotFound("Not found");
|
||
|
|
||
|
$calendarBackend = new Sabre_CalDAV_Backend_Std();
|
||
|
$calendarBackend->deleteCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $obj_alt[0]["ical_uri"]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $uri
|
||
|
* @param array $start
|
||
|
* @param array $end
|
||
|
* @param string $subject
|
||
|
* @param bool $allday
|
||
|
* @param string $description
|
||
|
* @param string $location
|
||
|
* @param null $color
|
||
|
* @param string $timezone
|
||
|
* @param bool $notification
|
||
|
* @param null $notification_type
|
||
|
* @param null $notification_value
|
||
|
* @throws Sabre_DAV_Exception_NotFound
|
||
|
* @throws Sabre_DAV_Exception_Conflict
|
||
|
*/
|
||
|
public function updateItem($uri, $start, $end, $subject = "", $allday = false, $description = "", $location = "", $color = null, $timezone = "", $notification = true, $notification_type = null, $notification_value = null)
|
||
|
{
|
||
|
$a = get_app();
|
||
|
|
||
|
$usr_id = IntVal($this->calendarDb->uid);
|
||
|
|
||
|
$old = q("SELECT * FROM %s%sjqcalendar WHERE `uid` = %d AND `namespace` = %d AND `namespace_id` = %d AND `ical_uri` = '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $usr_id, $this->getNamespace(), $this->namespace_id, dbesc($uri));
|
||
|
if (count($old) == 0) throw new Sabre_DAV_Exception_NotFound("Not Found 1");
|
||
|
$old_obj = new DBClass_friendica_jqcalendar($old[0]);
|
||
|
|
||
|
$calendarBackend = new Sabre_CalDAV_Backend_Std();
|
||
|
$obj = $calendarBackend->getCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $old_obj->ical_uri);
|
||
|
if (!$obj) throw new Sabre_DAV_Exception_NotFound("Not Found 2");
|
||
|
|
||
|
$v = new vcalendar();
|
||
|
$v->setConfig('unique_id', $a->get_hostname());
|
||
|
|
||
|
$v->setMethod('PUBLISH');
|
||
|
$v->setProperty("x-wr-calname", "AnimexxCal");
|
||
|
$v->setProperty("X-WR-CALDESC", "Animexx Calendar");
|
||
|
$v->setProperty("X-WR-TIMEZONE", $a->timezone);
|
||
|
|
||
|
$obj["calendardata"] = icalendar_sanitize_string($obj["calendardata"]);
|
||
|
|
||
|
$v->parse($obj["calendardata"]);
|
||
|
/** @var $vevent vevent */
|
||
|
$vevent = $v->getComponent('vevent');
|
||
|
|
||
|
if (trim($vevent->getProperty('uid')) . ".ics" != $old_obj->ical_uri)
|
||
|
throw new Sabre_DAV_Exception_Conflict("URI != URI: " . $old_obj->ical_uri . " vs. " . trim($vevent->getProperty("uid")));
|
||
|
|
||
|
if ($end["year"] < $start["year"] ||
|
||
|
($end["year"] == $start["year"] && $end["month"] < $start["month"]) ||
|
||
|
($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] < $start["day"]) ||
|
||
|
($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] < $start["hour"]) ||
|
||
|
($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] < $start["minute"]) ||
|
||
|
($end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] == $start["minute"] && $end["second"] < $start["second"])
|
||
|
) {
|
||
|
$end = $start;
|
||
|
if ($end["hour"] < 23) $end["hour"]++;
|
||
|
} // DTEND muss <= DTSTART
|
||
|
|
||
|
if ($start["hour"] == 0 && $start["minute"] == 0 && $end["hour"] == 23 && $end["minute"] == 59) {
|
||
|
$allday = true;
|
||
|
}
|
||
|
|
||
|
if ($allday) {
|
||
|
$vevent->setDtstart($start["year"], $start["month"], $start["day"], FALSE, FALSE, FALSE, FALSE, array("VALUE"=> "DATE"));
|
||
|
$end = mktime(0, 0, 0, $end["month"], $end["day"], $end["year"]) + 3600 * 24;
|
||
|
|
||
|
// If a DST change occurs on the current day
|
||
|
$end += date("Z", ($end - 3600*24)) - date("Z", $end);
|
||
|
|
||
|
$vevent->setDtend(date("Y", $end), date("m", $end), date("d", $end), FALSE, FALSE, FALSE, FALSE, array("VALUE"=> "DATE"));
|
||
|
} else {
|
||
|
$vevent->setDtstart($start["year"], $start["month"], $start["day"], $start["hour"], $start["minute"], $start["second"], FALSE, array("VALUE"=> "DATE-TIME"));
|
||
|
$vevent->setDtend($end["year"], $end["month"], $end["day"], $end["hour"], $end["minute"], $end["second"], FALSE, array("VALUE"=> "DATE-TIME"));
|
||
|
}
|
||
|
|
||
|
if ($subject != "") {
|
||
|
$vevent->setProperty('LOCATION', $location);
|
||
|
$vevent->setProperty('summary', $subject);
|
||
|
$vevent->setProperty('description', $description);
|
||
|
}
|
||
|
if (!is_null($color) && $color >= 0) $vevent->setProperty("X-ANIMEXX-COLOR", $color);
|
||
|
|
||
|
if (!$notification || $notification_type != null) {
|
||
|
$vevent->deleteComponent("VALARM");
|
||
|
|
||
|
if ($notification) {
|
||
|
$valarm = new valarm();
|
||
|
|
||
|
$valarm->setTrigger(
|
||
|
($notification_type == "year" ? $notification_value : 0),
|
||
|
($notification_type == "month" ? $notification_value : 0),
|
||
|
($notification_type == "day" ? $notification_value : 0),
|
||
|
($notification_type == "week" ? $notification_value : 0),
|
||
|
($notification_type == "hour" ? $notification_value : 0),
|
||
|
($notification_type == "minute" ? $notification_value : 0),
|
||
|
($notification_type == "minute" ? $notification_value : 0),
|
||
|
true,
|
||
|
($notification_value > 0)
|
||
|
);
|
||
|
$valarm->setProperty("ACTION", "DISPLAY");
|
||
|
$valarm->setProperty("DESCRIPTION", $subject);
|
||
|
|
||
|
$vevent->setComponent($valarm);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
$v->deleteComponent("vevent");
|
||
|
$v->setComponent($vevent, trim($vevent->getProperty("uid")));
|
||
|
$ical = $v->createCalendar();
|
||
|
|
||
|
$calendarBackend->updateCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $old_obj->ical_uri, $ical);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $start
|
||
|
* @param array $end
|
||
|
* @param string $subject
|
||
|
* @param bool $allday
|
||
|
* @param string $description
|
||
|
* @param string $location
|
||
|
* @param null $color
|
||
|
* @param string $timezone
|
||
|
* @param bool $notification
|
||
|
* @param null $notification_type
|
||
|
* @param null $notification_value
|
||
|
* @return array|string
|
||
|
*/
|
||
|
public function addItem($start, $end, $subject, $allday = false, $description = "", $location = "", $color = null,
|
||
|
$timezone = "", $notification = true, $notification_type = null, $notification_value = null)
|
||
|
{
|
||
|
$a = get_app();
|
||
|
|
||
|
$v = new vcalendar();
|
||
|
$v->setConfig('unique_id', $a->get_hostname());
|
||
|
|
||
|
$v->setProperty('method', 'PUBLISH');
|
||
|
$v->setProperty("x-wr-calname", "AnimexxCal");
|
||
|
$v->setProperty("X-WR-CALDESC", "Animexx Calendar");
|
||
|
$v->setProperty("X-WR-TIMEZONE", $a->timezone);
|
||
|
|
||
|
$vevent = dav_create_vevent($start, $end, $allday);
|
||
|
$vevent->setLocation(icalendar_sanitize_string($location));
|
||
|
$vevent->setSummary(icalendar_sanitize_string($subject));
|
||
|
$vevent->setDescription(icalendar_sanitize_string($description));
|
||
|
|
||
|
if (!is_null($color) && $color >= 0) $vevent->setProperty("X-ANIMEXX-COLOR", $color);
|
||
|
|
||
|
if ($notification && $notification_type == null) {
|
||
|
if ($allday) {
|
||
|
$notification_type = "hour";
|
||
|
$notification_value = 24;
|
||
|
} else {
|
||
|
$notification_type = "minute";
|
||
|
$notification_value = 60;
|
||
|
}
|
||
|
}
|
||
|
if ($notification) {
|
||
|
$valarm = new valarm();
|
||
|
|
||
|
$valarm->setTrigger(
|
||
|
($notification_type == "year" ? $notification_value : 0),
|
||
|
($notification_type == "month" ? $notification_value : 0),
|
||
|
($notification_type == "day" ? $notification_value : 0),
|
||
|
($notification_type == "week" ? $notification_value : 0),
|
||
|
($notification_type == "hour" ? $notification_value : 0),
|
||
|
($notification_type == "minute" ? $notification_value : 0),
|
||
|
($notification_type == "second" ? $notification_value : 0),
|
||
|
true,
|
||
|
($notification_value > 0)
|
||
|
);
|
||
|
$valarm->setAction("DISPLAY");
|
||
|
$valarm->setDescription($subject);
|
||
|
|
||
|
$vevent->setComponent($valarm);
|
||
|
|
||
|
}
|
||
|
|
||
|
$v->setComponent($vevent);
|
||
|
$ical = $v->createCalendar();
|
||
|
$obj_id = trim($vevent->getProperty("UID"));
|
||
|
|
||
|
$calendarBackend = new Sabre_CalDAV_Backend_Std();
|
||
|
$calendarBackend->createCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $obj_id . ".ics", $ical);
|
||
|
|
||
|
return $obj_id . ".ics";
|
||
|
}
|
||
|
|
||
|
private function jqcal2wdcal($row, $usr_id) {
|
||
|
$evo = new DBClass_friendica_jqcalendar($row);
|
||
|
$not = q("SELECT COUNT(*) num FROM %s%snotifications WHERE `ical_uri` = '%s' AND `ical_recurr_uri` = '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($row["ical_uri"]), $row["ical_recurr_uri"]
|
||
|
);
|
||
|
$editable = $this->getPermissionsItem($usr_id, $row["ical_uri"], $row["ical_recurr_uri"], $row);
|
||
|
$recurring = (is_null($evo->RecurringRule) || $evo->RecurringRule == "" || $evo->RecurringRule == "NULL" ? 0 : 1);
|
||
|
|
||
|
$end = wdcal_mySql2PhpTime($evo->EndTime);
|
||
|
if ($evo->IsAllDayEvent) $end -= 1;
|
||
|
|
||
|
$arr = array(
|
||
|
"uri" => $evo->ical_uri,
|
||
|
"subject" => escape_tags($evo->Subject),
|
||
|
"start" => wdcal_mySql2PhpTime($evo->StartTime),
|
||
|
"end" => $end,
|
||
|
"is_allday" => $evo->IsAllDayEvent,
|
||
|
"is_moredays" => 0,
|
||
|
"is_recurring" => $recurring,
|
||
|
"color" => (is_null($evo->Color) || $evo->Color == "" ? $this->calendarDb->calendarcolor : $evo->Color),
|
||
|
"is_editable" => ($editable ? 1 : 0),
|
||
|
"is_editable_quick" => ($editable && !$recurring ? 1 : 0),
|
||
|
"location" => $evo->Location,
|
||
|
"attendees" => '',
|
||
|
"has_notification" => ($not[0]["num"] > 0 ? 1 : 0),
|
||
|
"url_detail" => "/dav/wdcal/" . $evo->ical_uri . "/",
|
||
|
"url_edit" => "/dav/wdcal/" . $evo->ical_uri . "/edit/",
|
||
|
"special_type" => "",
|
||
|
);
|
||
|
return $arr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $sd
|
||
|
* @param string $ed
|
||
|
* @return array
|
||
|
*/
|
||
|
public function listItemsByRange($sd, $ed)
|
||
|
{
|
||
|
|
||
|
$usr_id = IntVal($this->calendarDb->uid);
|
||
|
|
||
|
$von = wdcal_php2MySqlTime($sd);
|
||
|
$bis = wdcal_php2MySqlTime($ed);
|
||
|
|
||
|
// @TODO Events, die früher angefangen haben, aber noch andauern
|
||
|
$evs = q("SELECT * FROM %s%sjqcalendar WHERE `uid` = %d AND `namespace` = %d AND `namespace_id` = %d AND `starttime` between '%s' and '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||
|
$usr_id, $this->getNamespace(), $this->namespace_id, dbesc($von), dbesc($bis));
|
||
|
|
||
|
$events = array();
|
||
|
foreach ($evs as $row) $events[] = $this->jqcal2wdcal($row, $usr_id);
|
||
|
|
||
|
return $events;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $uri
|
||
|
* @throws Sabre_DAV_Exception_NotFound
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getItemByUri($uri)
|
||
|
{
|
||
|
$usr_id = IntVal($this->calendarDb->uid);
|
||
|
$evs = q("SELECT * FROM %s%sjqcalendar WHERE `uid` = %d AND `namespace` = %d AND `namespace_id` = %d AND `ical_uri` = '%s'",
|
||
|
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||
|
$usr_id, $this->getNamespace(), $this->namespace_id, dbesc($uri));
|
||
|
if (count($evs) == 0) throw new Sabre_DAV_Exception_NotFound();
|
||
|
return $this->jqcal2wdcal($evs[0], $usr_id);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @param string $uri
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getItemDetailRedirect($uri) {
|
||
|
return "/dav/wdcal/$uri/edit/";
|
||
|
}
|
||
|
}
|