mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2025-07-10 18:38:49 +00:00
Initial Release of the calendar plugin
This commit is contained in:
parent
45cc9885fc
commit
7115197a33
561 changed files with 189494 additions and 0 deletions
611
dav/common/calendar.fnk.php
Normal file
611
dav/common/calendar.fnk.php
Normal file
|
@ -0,0 +1,611 @@
|
|||
<?php
|
||||
|
||||
|
||||
class vcard_source_data_email
|
||||
{
|
||||
public $email, $type;
|
||||
|
||||
function __construct($type, $email)
|
||||
{
|
||||
$this->email = $email;
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
class vcard_source_data_homepage
|
||||
{
|
||||
public $homepage, $type;
|
||||
|
||||
function __construct($type, $homepage)
|
||||
{
|
||||
$this->homepage = $homepage;
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
class vcard_source_data_telephone
|
||||
{
|
||||
public $telephone, $type;
|
||||
|
||||
function __construct($type, $telephone)
|
||||
{
|
||||
$this->telephone = $telephone;
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
class vcard_source_data_socialnetwork
|
||||
{
|
||||
public $nick, $type, $url;
|
||||
|
||||
function __construct($type, $nick, $url)
|
||||
{
|
||||
$this->nick = $nick;
|
||||
$this->type = $type;
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
||||
|
||||
class vcard_source_data_address
|
||||
{
|
||||
public $street, $street2, $zip, $city, $country, $type;
|
||||
}
|
||||
|
||||
class vcard_source_data_photo
|
||||
{
|
||||
public $binarydata;
|
||||
public $width, $height;
|
||||
public $type;
|
||||
}
|
||||
|
||||
class vcard_source_data
|
||||
{
|
||||
function __construct($name_first, $name_middle, $name_last)
|
||||
{
|
||||
$this->name_first = $name_first;
|
||||
$this->name_middle = $name_middle;
|
||||
$this->name_last = $name_last;
|
||||
}
|
||||
|
||||
public $name_first, $name_middle, $name_last;
|
||||
public $last_update;
|
||||
public $picture_data;
|
||||
|
||||
/** @var array|vcard_source_data_telephone[] $telephones */
|
||||
public $telephones;
|
||||
|
||||
/** @var array|vcard_source_data_homepage[] $homepages */
|
||||
public $homepages;
|
||||
|
||||
/** @var array|vcard_source_data_socialnetwork[] $socialnetworks */
|
||||
public $socialnetworks;
|
||||
|
||||
/** @var array|vcard_source_data_email[] $email */
|
||||
public $emails;
|
||||
|
||||
/** @var array|vcard_source_data_addresses[] $addresses */
|
||||
public $addresses;
|
||||
|
||||
/** @var vcard_source_data_photo */
|
||||
public $photo;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
* @param vcard_source_data $vcardsource
|
||||
* @return string
|
||||
*/
|
||||
function vcard_source_compile($vcardsource)
|
||||
{
|
||||
$str = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Friendica//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:_\$!<HomePage>!\$_\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 array $start
|
||||
* @param array $end
|
||||
* @param bool $allday
|
||||
* @return vevent
|
||||
*/
|
||||
function dav_create_vevent($start, $end, $allday)
|
||||
{
|
||||
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;
|
||||
} // DTEND muss <= DTSTART
|
||||
|
||||
$vevent = new vevent();
|
||||
if ($allday) {
|
||||
$vevent->setDtstart($start["year"], $start["month"], $start["day"], FALSE, FALSE, FALSE, FALSE, array("VALUE"=> "DATE"));
|
||||
$end = IntVal(mktime(0, 0, 0, $end["month"], $end["day"], $end["year"]) + 3600 * 24);
|
||||
|
||||
// If a DST change occurs on the current day
|
||||
$end += IntVal(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"));
|
||||
}
|
||||
return $vevent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $phpDate (UTC)
|
||||
* @return string (Lokalzeit)
|
||||
*/
|
||||
function wdcal_php2MySqlTime($phpDate)
|
||||
{
|
||||
return date("Y-m-d H:i:s", $phpDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sqlDate
|
||||
* @return int
|
||||
*/
|
||||
function wdcal_mySql2PhpTime($sqlDate)
|
||||
{
|
||||
$ts = DateTime::createFromFormat("Y-m-d H:i:s", $sqlDate);
|
||||
return $ts->format("U");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $myqlDate
|
||||
* @return array
|
||||
*/
|
||||
function wdcal_mySql2icalTime($myqlDate)
|
||||
{
|
||||
$x = explode(" ", $myqlDate);
|
||||
$y = explode("-", $x[0]);
|
||||
$ret = array("year"=> $y[0], "month"=> $y[1], "day"=> $y[2]);
|
||||
$y = explode(":", $x[1]);
|
||||
$ret["hour"] = $y[0];
|
||||
$ret["minute"] = $y[1];
|
||||
$ret["second"] = $y[2];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function icalendar_sanitize_string($str = "")
|
||||
{
|
||||
$str = str_replace("\r\n", "\n", $str);
|
||||
$str = str_replace("\n\r", "\n", $str);
|
||||
$str = str_replace("\r", "\n", $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DBClass_friendica_calendars $calendar
|
||||
* @param DBClass_friendica_calendarobjects $calendarobject
|
||||
*/
|
||||
function renderCalDavEntry_data(&$calendar, &$calendarobject)
|
||||
{
|
||||
$a = get_app();
|
||||
|
||||
$v = new vcalendar();
|
||||
$v->setConfig('unique_id', $a->get_hostname());
|
||||
$v->parse($calendarobject->calendardata);
|
||||
$v->sort();
|
||||
|
||||
$eventArray = $v->selectComponents(2009, 1, 1, date("Y") + 2, 12, 30);
|
||||
|
||||
$start_min = $end_max = "";
|
||||
|
||||
$allday = $summary = $vevent = $rrule = $color = $start = $end = null;
|
||||
$location = $description = "";
|
||||
|
||||
foreach ($eventArray as $yearArray) {
|
||||
foreach ($yearArray as $monthArray) {
|
||||
foreach ($monthArray as $day => $dailyEventsArray) {
|
||||
foreach ($dailyEventsArray as $vevent) {
|
||||
/** @var $vevent vevent */
|
||||
$start = "";
|
||||
$rrule = "NULL";
|
||||
$allday = 0;
|
||||
|
||||
$dtstart = $vevent->getProperty('X-CURRENT-DTSTART');
|
||||
if (is_array($dtstart)) {
|
||||
$start = "'" . $dtstart[1] . "'";
|
||||
if (strpos($dtstart[1], ":") === false) $allday = 1;
|
||||
} else {
|
||||
$dtstart = $vevent->getProperty('dtstart');
|
||||
if (isset($dtstart["day"]) && $dtstart["day"] == $day) { // Mehrtägige Events nur einmal rein
|
||||
if (isset($dtstart["hour"])) $start = "'" . $dtstart["year"] . "-" . $dtstart["month"] . "-" . $dtstart["day"] . " " . $dtstart["hour"] . ":" . $dtstart["minute"] . ":" . $dtstart["secont"] . "'";
|
||||
else {
|
||||
$start = "'" . $dtstart["year"] . "-" . $dtstart["month"] . "-" . $dtstart["day"] . " 00:00:00'";
|
||||
$allday = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dtend = $vevent->getProperty('X-CURRENT-DTEND');
|
||||
if (is_array($dtend)) {
|
||||
$end = "'" . $dtend[1] . "'";
|
||||
if (strpos($dtend[1], ":") === false) $allday = 1;
|
||||
} else {
|
||||
$dtend = $vevent->getProperty('dtend');
|
||||
if (isset($dtend["hour"])) $end = "'" . $dtend["year"] . "-" . $dtend["month"] . "-" . $dtend["day"] . " " . $dtend["hour"] . ":" . $dtend["minute"] . ":" . $dtend["second"] . "'";
|
||||
else {
|
||||
$end = "'" . $dtend["year"] . "-" . $dtend["month"] . "-" . $dtend["day"] . " 00:00:00' - INTERVAL 1 SECOND";
|
||||
$allday = 1;
|
||||
}
|
||||
}
|
||||
$summary = $vevent->getProperty('summary');
|
||||
$description = $vevent->getProperty('description');
|
||||
$location = $vevent->getProperty('location');
|
||||
$rrule_prob = $vevent->getProperty('rrule');
|
||||
if ($rrule_prob != null) {
|
||||
$rrule = $vevent->createRrule();
|
||||
$rrule = "'" . dbesc($rrule) . "'";
|
||||
}
|
||||
$color_ = $vevent->getProperty("X-ANIMEXX-COLOR");
|
||||
$color = (is_array($color_) ? $color_[1] : "NULL");
|
||||
|
||||
if ($start_min == "" || preg_replace("/[^0-9]/", "", $start) < preg_replace("/[^0-9]/", "", $start_min)) $start_min = $start;
|
||||
if ($end_max == "" || preg_replace("/[^0-9]/", "", $end) > preg_replace("/[^0-9]/", "", $start_min)) $end_max = $end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($start_min != "") {
|
||||
|
||||
if ($allday && mb_strlen($end_max) == 12) {
|
||||
$x = explode("-", str_replace("'", "", $end_max));
|
||||
$time = mktime(0, 0, 0, IntVal($x[1]), IntVal($x[2]), IntVal($x[0]));
|
||||
$end_max = date("'Y-m-d H:i:s'", ($time - 1));
|
||||
}
|
||||
|
||||
q("INSERT INTO %s%sjqcalendar (`uid`, `namespace`, `namespace_id`, `ical_uri`, `Subject`, `Location`, `Description`, `StartTime`, `EndTime`, `IsAllDayEvent`, `RecurringRule`, `Color`)
|
||||
VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', %s, %s, %d, '%s', '%s')",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||||
IntVal($calendar->uid), IntVal($calendarobject->namespace), IntVal($calendarobject->namespace_id), dbesc($calendarobject->uri), dbesc($summary),
|
||||
dbesc($location), dbesc(str_replace("\\n", "\n", $description)), $start_min, $end_max, IntVal($allday), dbesc($rrule), dbesc($color)
|
||||
);
|
||||
|
||||
foreach ($vevent->components as $comp) {
|
||||
/** @var $comp calendarComponent */
|
||||
$trigger = $comp->getProperty("TRIGGER");
|
||||
$sql_field = ($trigger["relatedStart"] ? $start : $end);
|
||||
$sql_op = ($trigger["before"] ? "DATE_SUB" : "DATE_ADD");
|
||||
$num = "";
|
||||
$rel_type = "";
|
||||
$rel_value = 0;
|
||||
if (isset($trigger["second"])) {
|
||||
$num = IntVal($trigger["second"]) . " SECOND";
|
||||
$rel_type = "second";
|
||||
$rel_value = IntVal($trigger["second"]);
|
||||
}
|
||||
if (isset($trigger["minute"])) {
|
||||
$num = IntVal($trigger["minute"]) . " MINUTE";
|
||||
$rel_type = "minute";
|
||||
$rel_value = IntVal($trigger["minute"]);
|
||||
}
|
||||
if (isset($trigger["hour"])) {
|
||||
$num = IntVal($trigger["hour"]) . " HOUR";
|
||||
$rel_type = "hour";
|
||||
$rel_value = IntVal($trigger["hour"]);
|
||||
}
|
||||
if (isset($trigger["day"])) {
|
||||
$num = IntVal($trigger["day"]) . " DAY";
|
||||
$rel_type = "day";
|
||||
$rel_value = IntVal($trigger["day"]);
|
||||
}
|
||||
if (isset($trigger["week"])) {
|
||||
$num = IntVal($trigger["week"]) . " WEEK";
|
||||
$rel_type = "week";
|
||||
$rel_value = IntVal($trigger["week"]);
|
||||
}
|
||||
if (isset($trigger["month"])) {
|
||||
$num = IntVal($trigger["month"]) . " MONTH";
|
||||
$rel_type = "month";
|
||||
$rel_value = IntVal($trigger["month"]);
|
||||
}
|
||||
if (isset($trigger["year"])) {
|
||||
$num = IntVal($trigger["year"]) . " YEAR";
|
||||
$rel_type = "year";
|
||||
$rel_value = IntVal($trigger["year"]);
|
||||
}
|
||||
if ($trigger["before"]) $rel_value *= -1;
|
||||
|
||||
if ($rel_type != "") {
|
||||
$not_date = "$sql_op($sql_field, INTERVAL $num)";
|
||||
q("INSERT INTO %s%snotifications (`uid`, `ical_uri`, `rel_type`, `rel_value`, `alert_date`, `notified`) VALUES ('%s', '%s', '%s', '%s', %s, IF(%s < NOW(), 1, 0))",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||||
IntVal($calendar->uid), dbesc($calendarobject->uri), dbesc($rel_type), IntVal($rel_value), $not_date, $not_date);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function renderAllCalDavEntries()
|
||||
{
|
||||
q("DELETE FROM %s%sjqcalendar", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
|
||||
q("DELETE FROM %s%snotifications", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
|
||||
$calendars = q("SELECT * FROM %s%scalendars", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
|
||||
$anz = count($calendars);
|
||||
$i = 0;
|
||||
foreach ($calendars as $calendar) {
|
||||
$cal = new DBClass_friendica_calendars($calendar);
|
||||
$i++;
|
||||
if (($i % 100) == 0) echo "$i / $anz\n";
|
||||
$calobjs = q("SELECT * FROM %s%scalendarobjects WHERE `namespace` = %d AND `namespace_id` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendar["namespace"]), IntVal($calendar["namespace_id"]));
|
||||
foreach ($calobjs as $calobj) {
|
||||
$obj = new DBClass_friendica_calendarobjects($calobj);
|
||||
renderCalDavEntry_data($cal, $obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return bool
|
||||
*/
|
||||
function renderCalDavEntry_uri($uri)
|
||||
{
|
||||
q("DELETE FROM %s%sjqcalendar WHERE `ical_uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
|
||||
q("DELETE FROM %s%snotifications WHERE `ical_uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
|
||||
|
||||
$calobj = q("SELECT * FROM %s%scalendarobjects WHERE `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
|
||||
if (count($calobj) == 0) return false;
|
||||
$cal = new DBClass_friendica_calendarobjects($calobj[0]);
|
||||
$calendars = q("SELECT * FROM %s%scalendars WHERE `namespace`=%d AND `namespace_id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($cal->namespace), IntVal($cal->namespace_id));
|
||||
$calendar = new DBClass_friendica_calendars($calendars[0]);
|
||||
renderCalDavEntry_data($calendar, $cal);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $user_id
|
||||
* @return array|DBClass_friendica_calendars[]
|
||||
*/
|
||||
function dav_getMyCals($user_id)
|
||||
{
|
||||
$d = q("SELECT * FROM %s%scalendars WHERE `uid` = %d ORDER BY `calendarorder` ASC",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($user_id), CALDAV_NAMESPACE_PRIVATE
|
||||
);
|
||||
$cals = array();
|
||||
foreach ($d as $e) $cals[] = new DBClass_friendica_calendars($e);
|
||||
return $cals;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $obj
|
||||
* @return string
|
||||
*/
|
||||
function wdcal_jsonp_encode($obj)
|
||||
{
|
||||
$str = json_encode($obj);
|
||||
if (isset($_REQUEST["callback"])) {
|
||||
$str = $_REQUEST["callback"] . "(" . $str . ")";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $day
|
||||
* @param int $weekstartday
|
||||
* @param int $num_days
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
function wdcal_get_list_range_params($day, $weekstartday, $num_days, $type)
|
||||
{
|
||||
$phpTime = IntVal($day);
|
||||
switch ($type) {
|
||||
case "month":
|
||||
$st = mktime(0, 0, 0, date("m", $phpTime), 1, date("Y", $phpTime));
|
||||
$et = mktime(0, 0, -1, date("m", $phpTime) + 1, 1, date("Y", $phpTime));
|
||||
break;
|
||||
case "week":
|
||||
//suppose first day of a week is monday
|
||||
$monday = date("d", $phpTime) - date('N', $phpTime) + 1;
|
||||
//echo date('N', $phpTime);
|
||||
$st = mktime(0, 0, 0, date("m", $phpTime), $monday, date("Y", $phpTime));
|
||||
$et = mktime(0, 0, -1, date("m", $phpTime), $monday + 7, date("Y", $phpTime));
|
||||
break;
|
||||
case "multi_days":
|
||||
//suppose first day of a week is monday
|
||||
$monday = date("d", $phpTime) - date('N', $phpTime) + $weekstartday;
|
||||
//echo date('N', $phpTime);
|
||||
$st = mktime(0, 0, 0, date("m", $phpTime), $monday, date("Y", $phpTime));
|
||||
$et = mktime(0, 0, -1, date("m", $phpTime), $monday + $num_days, date("Y", $phpTime));
|
||||
break;
|
||||
case "day":
|
||||
$st = mktime(0, 0, 0, date("m", $phpTime), date("d", $phpTime), date("Y", $phpTime));
|
||||
$et = mktime(0, 0, -1, date("m", $phpTime), date("d", $phpTime) + 1, date("Y", $phpTime));
|
||||
break;
|
||||
default:
|
||||
return array(0, 0);
|
||||
}
|
||||
return array($st, $et);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function wdcal_print_feed()
|
||||
{
|
||||
$user_id = dav_compat_get_curr_user_id();
|
||||
$cals = array();
|
||||
if (isset($_REQUEST["cal"])) foreach ($_REQUEST["cal"] as $c) {
|
||||
$x = explode("-", $c);
|
||||
$calendarSource = wdcal_calendar_factory($user_id, $x[0], $x[1]);
|
||||
$calp = $calendarSource->getPermissionsCalendar($user_id);
|
||||
if ($calp["read"]) $cals[] = $calendarSource;
|
||||
}
|
||||
|
||||
$ret = null;
|
||||
/** @var $cals array|AnimexxCalSource[] */
|
||||
|
||||
$method = $_GET["method"];
|
||||
switch ($method) {
|
||||
case "add":
|
||||
$cs = null;
|
||||
foreach ($cals as $c) if ($cs == null) {
|
||||
$x = $c->getPermissionsCalendar($user_id);
|
||||
if ($x["read"]) $cs = $c;
|
||||
}
|
||||
if ($cs == null) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
try {
|
||||
$start = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarStartTime"]));
|
||||
$end = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarEndTime"]));
|
||||
$newuri = $cs->addItem($start, $end, $_REQUEST["CalendarTitle"], $_REQUEST["IsAllDayEvent"]);
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'add success',
|
||||
'Data' => $newuri,
|
||||
);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$ret = array(
|
||||
'IsSuccess' => false,
|
||||
'Msg' => $e->__toString(),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
$weekstartday = (isset($_REQUEST["weekstartday"]) ? IntVal($_REQUEST["weekstartday"]) : 1); // 1 = Monday
|
||||
$num_days = (isset($_REQUEST["num_days"]) ? IntVal($_REQUEST["num_days"]) : 7);
|
||||
$ret = null;
|
||||
|
||||
$date = wdcal_get_list_range_params($_REQUEST["showdate"], $weekstartday, $num_days, $_REQUEST["viewtype"]);
|
||||
$ret = array();
|
||||
$ret['events'] = array();
|
||||
$ret["issort"] = true;
|
||||
$ret["start"] = $date[0];
|
||||
$ret["end"] = $date[1];
|
||||
$ret['error'] = null;
|
||||
|
||||
foreach ($cals as $c) {
|
||||
$events = $c->listItemsByRange($date[0], $date[1]);
|
||||
$ret["events"] = array_merge($ret["events"], $events);
|
||||
}
|
||||
|
||||
$tmpev = array();
|
||||
foreach ($ret["events"] as $e) {
|
||||
if (!isset($tmpev[$e["start"]])) $tmpev[$e["start"]] = array();
|
||||
$tmpev[$e["start"]][] = $e;
|
||||
}
|
||||
ksort($tmpev);
|
||||
$ret["events"] = array();
|
||||
foreach ($tmpev as $e) foreach ($e as $f) $ret["events"][] = $f;
|
||||
|
||||
break;
|
||||
case "update":
|
||||
$found = false;
|
||||
$start = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarStartTime"]));
|
||||
$end = wdcal_mySql2icalTime(wdcal_php2MySqlTime($_REQUEST["CalendarEndTime"]));
|
||||
foreach ($cals as $c) try {
|
||||
$permissions_item = $c->getPermissionsItem($user_id, $_REQUEST["calendarId"], "");
|
||||
if ($permissions_item["write"]) {
|
||||
$c->updateItem($_REQUEST["calendarId"], $start, $end);
|
||||
$found = true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
;
|
||||
|
||||
if ($found) {
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'Succefully',
|
||||
);
|
||||
} else {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
|
||||
try {
|
||||
} catch (Exception $e) {
|
||||
$ret = array(
|
||||
'IsSuccess' => false,
|
||||
'Msg' => $e->__toString(),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
$found = false;
|
||||
foreach ($cals as $c) try {
|
||||
$permissions_item = $c->getPermissionsItem($user_id, $_REQUEST["calendarId"], "");
|
||||
if ($permissions_item["write"]) $c->removeItem($_REQUEST["calendarId"]);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'Succefully',
|
||||
);
|
||||
} else {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
break;
|
||||
}
|
||||
echo wdcal_jsonp_encode($ret);
|
||||
killme();
|
||||
}
|
||||
|
174
dav/common/dav_caldav_backend.inc.php
Normal file
174
dav/common/dav_caldav_backend.inc.php
Normal file
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
class Sabre_CalDAV_Backend_Std extends Sabre_CalDAV_Backend_Common
|
||||
{
|
||||
|
||||
public function getNamespace()
|
||||
{
|
||||
return CALDAV_NAMESPACE_PRIVATE;
|
||||
}
|
||||
|
||||
public function getCalUrlPrefix()
|
||||
{
|
||||
return "private";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar for a principal.
|
||||
*
|
||||
* If the creation was a success, an id must be returned that can be used to reference
|
||||
* this calendar in other methods, such as updateCalendar.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
* @param array $properties
|
||||
* @return void
|
||||
*/
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties)
|
||||
{
|
||||
// TODO: Implement createCalendar() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a calendar and all it's objects
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCalendar($calendarId)
|
||||
{
|
||||
// TODO: Implement deleteCalendar() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
*
|
||||
* Every item contains an array with the following keys:
|
||||
* * id - unique identifier which will be used for subsequent updates
|
||||
* * calendardata - The iCalendar-compatible calendar data
|
||||
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
|
||||
* * lastmodified - a timestamp of the last modification time
|
||||
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
|
||||
* ' "abcdef"')
|
||||
* * calendarid - The calendarid as it was passed to this function.
|
||||
* * size - The size of the calendar objects, in bytes.
|
||||
*
|
||||
* Note that the etag is optional, but it's highly encouraged to return for
|
||||
* speed reasons.
|
||||
*
|
||||
* The calendardata is also optional. If it's not returned
|
||||
* 'getCalendarObject' will be called later, which *is* expected to return
|
||||
* calendardata.
|
||||
*
|
||||
* If neither etag or size are specified, the calendardata will be
|
||||
* used/fetched to determine these numbers. If both are specified the
|
||||
* amount of times this is needed is reduced by a great degree.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObjects($calendarId)
|
||||
{
|
||||
$x = explode("-", $calendarId);
|
||||
$objs = q("SELECT * FROM %s%scalendarobjects WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]));
|
||||
$ret = array();
|
||||
foreach ($objs as $obj) {
|
||||
$ret[] = array(
|
||||
"id" => IntVal($obj["id"]),
|
||||
"calendardata" => $obj["calendardata"],
|
||||
"uri" => $obj["uri"],
|
||||
"lastmodified" => $obj["lastmodified"],
|
||||
"calendarid" => $calendarId,
|
||||
"etag" => $obj["etag"],
|
||||
"size" => IntVal($obj["size"]),
|
||||
);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information from a single calendar object, based on it's object
|
||||
* uri.
|
||||
*
|
||||
* The returned array must have the same keys as getCalendarObjects. The
|
||||
* 'calendardata' object is required here though, while it's not required
|
||||
* for getCalendarObjects.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @throws Sabre_DAV_Exception_FileNotFound
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$x = explode("-", $calendarId);
|
||||
|
||||
$o = q("SELECT * FROM %s%scalendarobjects WHERE `namespace` = %d AND `namespace_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]), dbesc($objectUri));
|
||||
if (count($o) > 0) {
|
||||
$o[0]["calendarid"] = $calendarId;
|
||||
$o[0]["calendardata"] = str_ireplace("Europe/Belgrade", "Europe/Berlin", $o[0]["calendardata"]);
|
||||
return $o[0];
|
||||
} else throw new Sabre_DAV_Exception_FileNotFound($calendarId . " / " . $objectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return null|string|void
|
||||
*/
|
||||
function createCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$x = explode("-", $calendarId);
|
||||
|
||||
q("INSERT INTO %s%scalendarobjects (`namespace`, `namespace_id`, `uri`, `calendardata`, `lastmodified`, `etag`, `size`) VALUES (%d, %d, '%s', '%s', NOW(), '%s', %d)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||||
IntVal($x[0]), IntVal($x[1]), dbesc($objectUri), addslashes($calendarData), md5($calendarData), strlen($calendarData)
|
||||
);
|
||||
|
||||
$this->increaseCalendarCtag($x[0], $x[1]);
|
||||
renderCalDavEntry_uri($objectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return null|string|void
|
||||
*/
|
||||
function updateCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$x = explode("-", $calendarId);
|
||||
|
||||
q("UPDATE %s%scalendarobjects SET `calendardata` = '%s', `lastmodified` = NOW(), `etag` = '%s', `size` = %d WHERE `namespace` = %d AND `namespace_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($calendarData), md5($calendarData), strlen($calendarData), IntVal($x[0]), IntVal($x[1]), dbesc($objectUri));
|
||||
|
||||
$this->increaseCalendarCtag($x[0], $x[1]);
|
||||
renderCalDavEntry_uri($objectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$x = explode("-", $calendarId);
|
||||
|
||||
q("DELETE FROM %s%scalendarobjects WHERE `namespace` = %d AND `namespace_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]), dbesc($objectUri)
|
||||
);
|
||||
|
||||
$this->increaseCalendarCtag($x[0], $x[1]);
|
||||
renderCalDavEntry_uri($objectUri);
|
||||
}
|
||||
}
|
170
dav/common/dav_caldav_backend_common.inc.php
Normal file
170
dav/common/dav_caldav_backend_common.inc.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract {
|
||||
/**
|
||||
* List of CalDAV properties, and how they map to database fieldnames
|
||||
*
|
||||
* Add your own properties by simply adding on to this array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $propertyMap = array(
|
||||
'{DAV:}displayname' => 'displayname',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone',
|
||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
|
||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
|
||||
);
|
||||
|
||||
|
||||
abstract public function getNamespace();
|
||||
abstract public function getCalUrlPrefix();
|
||||
|
||||
/**
|
||||
* @param int $namespace
|
||||
* @param int $namespace_id
|
||||
*/
|
||||
protected function increaseCalendarCtag($namespace, $namespace_id) {
|
||||
$namespace = IntVal($namespace);
|
||||
$namespace_id = IntVal($namespace_id);
|
||||
|
||||
q("UPDATE %s%scalendars SET `ctag` = `ctag` + 1 WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $namespace, $namespace_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of calendars for a principal.
|
||||
*
|
||||
* Every project is an array with the following keys:
|
||||
* * id, a unique id that will be used by other functions to modify the
|
||||
* calendar. This can be the same as the uri or a database key.
|
||||
* * uri, which the basename of the uri with which the calendar is
|
||||
* accessed.
|
||||
* * principaluri. The owner of the calendar. Almost always the same as
|
||||
* principalUri passed to this method.
|
||||
*
|
||||
* Furthermore it can contain webdav properties in clark notation. A very
|
||||
* common one is '{DAV:}displayname'.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarsForUser($principalUri)
|
||||
{
|
||||
list(,$name) = Sabre_DAV_URLUtil::splitPath($principalUri);
|
||||
$user_id = dav_compat_username2id($name);
|
||||
|
||||
$cals = q("SELECT * FROM %s%scalendars WHERE `uid`=%d AND `namespace` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $user_id, $this->getNamespace());
|
||||
$ret = array();
|
||||
foreach ($cals as $cal) {
|
||||
$dat = array(
|
||||
"id" => $cal["namespace"] . "-" . $cal["namespace_id"],
|
||||
"uri" => $this->getCalUrlPrefix() . "-" . $cal["namespace_id"],
|
||||
"principaluri" => $principalUri,
|
||||
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}getctag' => $cal['ctag']?$cal['ctag']:'0',
|
||||
"calendar_class" => "Sabre_CalDAV_Calendar",
|
||||
);
|
||||
foreach ($this->propertyMap as $key=>$field) $dat[$key] = $cal[$field];
|
||||
|
||||
$ret[] = $dat;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
*
|
||||
* The mutations array uses the propertyName in clark-notation as key,
|
||||
* and the array value for the property value. In the case a property
|
||||
* should be deleted, the property value will be null.
|
||||
*
|
||||
* This method must be atomic. If one property cannot be changed, the
|
||||
* entire operation must fail.
|
||||
*
|
||||
* If the operation was successful, true can be returned.
|
||||
* If the operation failed, false can be returned.
|
||||
*
|
||||
* Deletion of a non-existent property is always successful.
|
||||
*
|
||||
* Lastly, it is optional to return detailed information about any
|
||||
* failures. In this case an array should be returned with the following
|
||||
* structure:
|
||||
*
|
||||
* array(
|
||||
* 403 => array(
|
||||
* '{DAV:}displayname' => null,
|
||||
* ),
|
||||
* 424 => array(
|
||||
* '{DAV:}owner' => null,
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* In this example it was forbidden to update {DAV:}displayname.
|
||||
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
|
||||
* (424 Failed Dependency) because the request needs to be atomic.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param array $mutations
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateCalendar($calendarId, array $mutations) {
|
||||
|
||||
$newValues = array();
|
||||
$result = array(
|
||||
200 => array(), // Ok
|
||||
403 => array(), // Forbidden
|
||||
424 => array(), // Failed Dependency
|
||||
);
|
||||
|
||||
$hasError = false;
|
||||
|
||||
foreach($mutations as $propertyName=>$propertyValue) {
|
||||
|
||||
// We don't know about this property.
|
||||
if (!isset($this->propertyMap[$propertyName])) {
|
||||
$hasError = true;
|
||||
$result[403][$propertyName] = null;
|
||||
unset($mutations[$propertyName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldName = $this->propertyMap[$propertyName];
|
||||
$newValues[$fieldName] = $propertyValue;
|
||||
|
||||
}
|
||||
|
||||
// If there were any errors we need to fail the request
|
||||
if ($hasError) {
|
||||
// Properties has the remaining properties
|
||||
foreach($mutations as $propertyName=>$propertyValue) {
|
||||
$result[424][$propertyName] = null;
|
||||
}
|
||||
|
||||
// Removing unused statuscodes for cleanliness
|
||||
foreach($result as $status=>$properties) {
|
||||
if (is_array($properties) && count($properties)===0) unset($result[$status]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
$x = explode("-", $calendarId);
|
||||
|
||||
$this->increaseCalendarCtag($x[0], $x[1]);
|
||||
|
||||
$valuesSql = array();
|
||||
foreach($newValues as $fieldName=>$value) $valuesSql[] = "`" . $fieldName . "` = '" . dbesc($value) . "'";
|
||||
if (count($valuesSql) > 0) {
|
||||
q("UPDATE %s%scalendars SET " . implode(", ", $valuesSql) . " WHERE `namespace` = %d AND `namespace_id` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1])
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
69
dav/common/dav_caldav_root.inc.php
Normal file
69
dav/common/dav_caldav_root.inc.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Users collection
|
||||
*
|
||||
* This object is responsible for generating a collection of users.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage CalDAV
|
||||
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_CalDAV_AnimexxCalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollection {
|
||||
|
||||
/**
|
||||
* CalDAV backend
|
||||
*
|
||||
* @var array|Sabre_CalDAV_Backend_Abstract[]
|
||||
*/
|
||||
protected $caldavBackends;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This constructor needs both an authentication and a caldav backend.
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param array|Sabre_CalDAV_Backend_Abstract[] $caldavBackends
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,$caldavBackends, $principalPrefix = 'principals/users') {
|
||||
|
||||
parent::__construct($principalBackend, $principalPrefix);
|
||||
$this->caldavBackends = $caldavBackends;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nodename
|
||||
*
|
||||
* We're overriding this, because the default will be the 'principalPrefix',
|
||||
* and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
return Sabre_CalDAV_Plugin::CALENDAR_ROOT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a node for a principal.
|
||||
*
|
||||
* The passed array contains principal information, and is guaranteed to
|
||||
* at least contain a uri item. Other properties may or may not be
|
||||
* supplied by the authentication backend.
|
||||
*
|
||||
* @param array $principal
|
||||
* @return \Sabre_CalDAV_AnimexxUserCalendars|\Sabre_DAVACL_IPrincipal
|
||||
*/
|
||||
public function getChildForPrincipal(array $principal) {
|
||||
|
||||
return new Sabre_CalDAV_AnimexxUserCalendars($this->principalBackend, $this->caldavBackends, $principal['uri']);
|
||||
|
||||
}
|
||||
|
||||
}
|
313
dav/common/dav_carddav_backend_std.inc.php
Normal file
313
dav/common/dav_carddav_backend_std.inc.php
Normal file
|
@ -0,0 +1,313 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PDO CardDAV backend
|
||||
*
|
||||
* This CardDAV backend uses PDO to store addressbooks
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage CardDAV
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_CardDAV_Backend_Std extends Sabre_CardDAV_Backend_Abstract
|
||||
{
|
||||
|
||||
/**
|
||||
* Sets up the object
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of addressbooks for a specific user.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @return array
|
||||
*/
|
||||
public function getAddressBooksForUser($principalUri)
|
||||
{
|
||||
$uid = dav_compat_principal2uid($principalUri);
|
||||
|
||||
$addressBooks = array();
|
||||
|
||||
$books = q("SELECT id, uri, displayname, principaluri, description, ctag FROM %s%saddressbooks_phone WHERE principaluri = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($principalUri));
|
||||
if (count($books) == 0) {
|
||||
q("INSERT INTO %s%saddressbooks_phone (uid, principaluri, displayname, uri, description, ctag) VALUES (%d, '%s', '%s', '%s', '%s', 1)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $uid, dbesc($principalUri), 'Other', 'phone', 'Manually added contacts'
|
||||
);
|
||||
$books = q("SELECT id, uri, displayname, principaluri, description, ctag FROM %s%saddressbooks_phone WHERE principaluri = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($principalUri));
|
||||
}
|
||||
foreach ($books as $row) {
|
||||
$addressBooks[] = array(
|
||||
'id' => CARDDAV_NAMESPACE_PHONECONTACTS . "-" . $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'principaluri' => $row['principaluri'],
|
||||
'{DAV:}displayname' => $row['displayname'],
|
||||
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
|
||||
'{http://calendarserver.org/ns/}getctag' => $row['ctag'],
|
||||
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' =>
|
||||
new Sabre_CardDAV_Property_SupportedAddressData(),
|
||||
);
|
||||
}
|
||||
|
||||
return $addressBooks;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates an addressbook's properties
|
||||
*
|
||||
* See Sabre_DAV_IProperties for a description of the mutations array, as
|
||||
* well as the return value.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param array $mutations
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @see Sabre_DAV_IProperties::updateProperties
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateAddressBook($addressBookId, array $mutations)
|
||||
{
|
||||
$x = explode("-", $addressBookId);
|
||||
|
||||
$updates = array();
|
||||
|
||||
foreach ($mutations as $property=> $newValue) {
|
||||
|
||||
switch ($property) {
|
||||
case '{DAV:}displayname' :
|
||||
$updates['displayname'] = $newValue;
|
||||
break;
|
||||
case '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' :
|
||||
$updates['description'] = $newValue;
|
||||
break;
|
||||
default :
|
||||
// If any unsupported values were being updated, we must
|
||||
// let the entire request fail.
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// No values are being updated?
|
||||
if (!$updates) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = 'UPDATE ' . CALDAV_SQL_DB . CALDAV_SQL_PREFIX . 'addressbooks_phone SET ctag = ctag + 1 ';
|
||||
foreach ($updates as $key=> $value) {
|
||||
$query .= ', `' . dbesc($key) . '` = ' . dbesc($key) . ' ';
|
||||
}
|
||||
$query .= ' WHERE id = ' . IntVal($x[1]);
|
||||
q($query);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new address book
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $url Just the 'basename' of the url.
|
||||
* @param array $properties
|
||||
* @throws Sabre_DAV_Exception_BadRequest
|
||||
* @return void
|
||||
*/
|
||||
public function createAddressBook($principalUri, $url, array $properties)
|
||||
{
|
||||
$values = array(
|
||||
'displayname' => null,
|
||||
'description' => null,
|
||||
'principaluri' => $principalUri,
|
||||
'uri' => $url,
|
||||
);
|
||||
|
||||
foreach ($properties as $property=> $newValue) {
|
||||
|
||||
switch ($property) {
|
||||
case '{DAV:}displayname' :
|
||||
$values['displayname'] = $newValue;
|
||||
break;
|
||||
case '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' :
|
||||
$values['description'] = $newValue;
|
||||
break;
|
||||
default :
|
||||
throw new Sabre_DAV_Exception_BadRequest('Unknown property: ' . $property);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
q("INSERT INTO %s%saddressbooks_phone (uri, displayname, description, principaluri, ctag) VALUES ('%s', '%s', '%s', '%s', 1)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($values["uri"]), dbesc($values["displayname"]), dbesc($values["description"]), dbesc($values["principaluri"])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an entire addressbook and all its contents
|
||||
*
|
||||
* @param int $addressBookId
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAddressBook($addressBookId)
|
||||
{
|
||||
$x = explode("-", $addressBookId);
|
||||
q("DELETE FROM %s%scards WHERE namespace = %d AND namespace_id = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]));
|
||||
q("DELETE FROM %s%saddressbooks_phone WHERE id = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cards for a specific addressbook id.
|
||||
*
|
||||
* This method should return the following properties for each card:
|
||||
* * carddata - raw vcard data
|
||||
* * uri - Some unique url
|
||||
* * lastmodified - A unix timestamp
|
||||
*
|
||||
* It's recommended to also return the following properties:
|
||||
* * etag - A unique etag. This must change every time the card changes.
|
||||
* * size - The size of the card in bytes.
|
||||
*
|
||||
* If these last two properties are provided, less time will be spent
|
||||
* calculating them. If they are specified, you can also ommit carddata.
|
||||
* This may speed up certain requests, especially with large cards.
|
||||
*
|
||||
* @param string $addressbookId
|
||||
* @return array
|
||||
*/
|
||||
public function getCards($addressbookId)
|
||||
{
|
||||
$x = explode("-", $addressbookId);
|
||||
|
||||
$r = q('SELECT id, carddata, uri, lastmodified, etag, size, contact FROM %s%scards WHERE namespace = %d AND namespace_id = %d AND manually_deleted = 0',
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1])
|
||||
);
|
||||
if ($r) return $r;
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specfic card.
|
||||
*
|
||||
* The same set of properties must be returned as with getCards. The only
|
||||
* exception is that 'carddata' is absolutely required.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
* @return array
|
||||
*/
|
||||
public function getCard($addressBookId, $cardUri)
|
||||
{
|
||||
$x = explode("-", $addressBookId);
|
||||
$x = q("SELECT id, carddata, uri, lastmodified, etag, size FROM %s%scards WHERE namespace = %d AND namespace_id = %d AND uri = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]), dbesc($cardUri));
|
||||
if (count($x) == 0) throw new Sabre_DAV_Exception_NotFound();
|
||||
return $x[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new 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 is for the
|
||||
* newly created resource, and must be enclosed with double quotes (that
|
||||
* is, the string itself must contain the double 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 string
|
||||
*/
|
||||
public function createCard($addressBookId, $cardUri, $cardData)
|
||||
{
|
||||
$x = explode("-", $addressBookId);
|
||||
|
||||
$etag = md5($cardData);
|
||||
q("INSERT INTO %s%scards (carddata, uri, lastmodified, namespace, namespace_id, etag, size) VALUES ('%s', '%s', %d, %d, '%s', %d)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($cardData), dbesc($cardUri), time(), IntVal($x[0]), IntVal($x[1]), $etag, strlen($cardData)
|
||||
);
|
||||
|
||||
q('UPDATE %s%saddressbooks_phone SET ctag = ctag + 1 WHERE id = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[1]));
|
||||
|
||||
return '"' . $etag . '"';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 string|null
|
||||
*/
|
||||
public function updateCard($addressBookId, $cardUri, $cardData)
|
||||
{
|
||||
$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_phone SET ctag = ctag + 1 WHERE id = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[1]));
|
||||
|
||||
return '"' . $etag . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a card
|
||||
*
|
||||
* @param string $addressBookId
|
||||
* @param string $cardUri
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteCard($addressBookId, $cardUri)
|
||||
{
|
||||
$x = explode("-", $addressBookId);
|
||||
|
||||
q("DELETE FROM %s%scards WHERE namespace = %d AND namespace_id = %d AND uri = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[0]), IntVal($x[1]), dbesc($cardUri));
|
||||
q('UPDATE %s%saddressbooks_phone SET ctag = ctag + 1 WHERE id = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($x[1]));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
64
dav/common/dav_carddav_root.inc.php
Normal file
64
dav/common/dav_carddav_root.inc.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
class Sabre_CardDAV_AddressBookRootFriendica extends Sabre_DAVACL_AbstractPrincipalCollection {
|
||||
|
||||
/**
|
||||
* Principal Backend
|
||||
*
|
||||
* @var Sabre_DAVACL_IPrincipalBackend
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* CardDAV backend
|
||||
*
|
||||
* @var array|Sabre_CardDAV_Backend_Abstract[]
|
||||
*/
|
||||
protected $carddavBackends;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This constructor needs both a principal and a carddav backend.
|
||||
*
|
||||
* By default this class will show a list of addressbook collections for
|
||||
* principals in the 'principals' collection. If your main principals are
|
||||
* actually located in a different path, use the $principalPrefix argument
|
||||
* to override this.
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param array|Sabre_CardDAV_Backend_Abstract[] $carddavBackends
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $carddavBackends, $principalPrefix = 'principals/users') {
|
||||
|
||||
$this->carddavBackends = $carddavBackends;
|
||||
parent::__construct($principalBackend, $principalPrefix);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the node
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return Sabre_CardDAV_Plugin::ADDRESSBOOK_ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a node for a principal.
|
||||
*
|
||||
* The passed array contains principal information, and is guaranteed to
|
||||
* at least contain a uri item. Other properties may or may not be
|
||||
* supplied by the authentication backend.
|
||||
*
|
||||
* @param array $principal
|
||||
* @return Sabre_DAVACL_IPrincipal
|
||||
*/
|
||||
public function getChildForPrincipal(array $principal) {
|
||||
return new Sabre_CardDAV_UserAddressBooksMultiBackend($this->carddavBackends, $principal['uri']);
|
||||
|
||||
}
|
||||
|
||||
}
|
264
dav/common/dav_user_addressbooks.inc.php
Normal file
264
dav/common/dav_user_addressbooks.inc.php
Normal file
|
@ -0,0 +1,264 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The UserCalenders class contains all calendars associated to one user
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage CalDAV
|
||||
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_CardDAV_UserAddressBooksMultiBackend extends Sabre_DAV_Collection implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL {
|
||||
|
||||
/**
|
||||
* Principal uri
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* carddavBackend
|
||||
*
|
||||
* @var array|Sabre_CardDAV_Backend_Abstract[]
|
||||
*/
|
||||
protected $carddavBackends;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|Sabre_CardDAV_Backend_Abstract[] $carddavBackends
|
||||
* @param string $principalUri
|
||||
*/
|
||||
public function __construct($carddavBackends, $principalUri) {
|
||||
|
||||
$this->carddavBackends = $carddavBackends;
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalUri);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name of this object
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function setName($name) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this object
|
||||
*
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function delete() {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastModified() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file under this object.
|
||||
*
|
||||
* This is currently not allowed
|
||||
*
|
||||
* @param string $filename
|
||||
* @param resource $data
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return null|string|void
|
||||
*/
|
||||
public function createFile($filename, $data=null) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Creating new files in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory under this object.
|
||||
*
|
||||
* This is currently not allowed.
|
||||
*
|
||||
* @param string $filename
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function createDirectory($filename) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Creating new collections in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single calendar, by name
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
* @todo needs optimizing
|
||||
* @return \Sabre_CardDAV_AddressBook|\Sabre_DAV_INode
|
||||
*/
|
||||
public function getChild($name) {
|
||||
|
||||
foreach($this->getChildren() as $child) {
|
||||
if ($name==$child->getName())
|
||||
return $child;
|
||||
|
||||
}
|
||||
throw new Sabre_DAV_Exception_NotFound('Addressbook with name \'' . $name . '\' could not be found');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of addressbooks
|
||||
*
|
||||
* @return array|Sabre_DAV_INode[]
|
||||
*/
|
||||
public function getChildren() {
|
||||
|
||||
$objs = array();
|
||||
foreach ($this->carddavBackends as $backend) {
|
||||
$addressbooks = $backend->getAddressbooksForUser($this->principalUri);
|
||||
foreach($addressbooks as $addressbook) {
|
||||
$objs[] = new Sabre_CardDAV_AddressBook($backend, $addressbook);
|
||||
}
|
||||
}
|
||||
return $objs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new addressbook
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $resourceType
|
||||
* @param array $properties
|
||||
* @throws Sabre_DAV_Exception_InvalidResourceType
|
||||
* @return void
|
||||
*/
|
||||
public function createExtendedCollection($name, array $resourceType, array $properties) {
|
||||
|
||||
if (!in_array('{'.Sabre_CardDAV_Plugin::NS_CARDDAV.'}addressbook',$resourceType) || count($resourceType)!==2) {
|
||||
throw new Sabre_DAV_Exception_InvalidResourceType('Unknown resourceType for this collection');
|
||||
}
|
||||
$this->carddavBackends[0]->createAddressBook($this->principalUri, $name, $properties);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner() {
|
||||
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a group principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getGroup() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getACL() {
|
||||
|
||||
return array(
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalUri,
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalUri,
|
||||
'protected' => true,
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ACL
|
||||
*
|
||||
* This method will receive a list of new ACE's.
|
||||
*
|
||||
* @param array $acl
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function setACL(array $acl) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Changing ACL is not yet supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of supported privileges for this node.
|
||||
*
|
||||
* The returned data structure is a list of nested privileges.
|
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
|
||||
* standard structure.
|
||||
*
|
||||
* If null is returned from this method, the default privilege set is used,
|
||||
* which is fine for most common usecases.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getSupportedPrivilegeSet() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
305
dav/common/dav_user_calendars.inc.php
Normal file
305
dav/common/dav_user_calendars.inc.php
Normal file
|
@ -0,0 +1,305 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The UserCalenders class contains all calendars associated to one user
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage CalDAV
|
||||
* @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_CalDAV_AnimexxUserCalendars implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL {
|
||||
|
||||
/**
|
||||
* Principal backend
|
||||
*
|
||||
* @var Sabre_DAVACL_IPrincipalBackend
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* CalDAV backends
|
||||
*
|
||||
* @var array|Sabre_CalDAV_Backend_Abstract[]
|
||||
*/
|
||||
protected $caldavBackends;
|
||||
|
||||
/**
|
||||
* Principal information
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalInfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param array|Sabre_CalDAV_Backend_Abstract $caldavBackends
|
||||
* @param mixed $userUri
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $caldavBackends, $userUri) {
|
||||
|
||||
$this->principalBackend = $principalBackend;
|
||||
$this->caldavBackends = $caldavBackends;
|
||||
$this->principalInfo = $principalBackend->getPrincipalByPath($userUri);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalInfo['uri']);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name of this object
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
public function setName($name) {
|
||||
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this object
|
||||
*
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
public function delete() {
|
||||
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastModified() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file under this object.
|
||||
*
|
||||
* This is currently not allowed
|
||||
*
|
||||
* @param string $filename
|
||||
* @param resource $data
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return null|string|void
|
||||
*/
|
||||
public function createFile($filename, $data=null) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Creating new files in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory under this object.
|
||||
*
|
||||
* This is currently not allowed.
|
||||
*
|
||||
* @param string $filename
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function createDirectory($filename) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Creating new collections in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single calendar, by name
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_FileNotFound
|
||||
* @todo needs optimizing
|
||||
* @return \Sabre_CalDAV_Calendar|\Sabre_DAV_INode
|
||||
*/
|
||||
public function getChild($name) {
|
||||
|
||||
foreach($this->getChildren() as $child) {
|
||||
if ($name==$child->getName())
|
||||
return $child;
|
||||
|
||||
}
|
||||
throw new Sabre_DAV_Exception_FileNotFound('Calendar with name \'' . $name . '\' could not be found');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a calendar exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @todo needs optimizing
|
||||
* @return bool
|
||||
*/
|
||||
public function childExists($name) {
|
||||
|
||||
foreach($this->getChildren() as $child) {
|
||||
if ($name==$child->getName())
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendars
|
||||
*
|
||||
* @return array|\Sabre_DAV_INode[]
|
||||
*/
|
||||
|
||||
public function getChildren() {
|
||||
$objs = array();
|
||||
foreach ($this->caldavBackends as $backend) {
|
||||
$calendars = $backend->getCalendarsForUser($this->principalInfo["uri"]);
|
||||
foreach($calendars as $calendar) {
|
||||
$objs[] = new $calendar["calendar_class"]($this->principalBackend, $backend, $calendar);
|
||||
}
|
||||
}
|
||||
//$objs[] = new Sabre_CalDAV_AnimexxUserZirkelCalendars($this->principalBackend, $this->caldavBackend, $this->username);
|
||||
return $objs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $resourceType
|
||||
* @param array $properties
|
||||
* @throws Sabre_DAV_Exception_InvalidResourceType
|
||||
* @return void
|
||||
*/
|
||||
public function createExtendedCollection($name, array $resourceType, array $properties) {
|
||||
|
||||
if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar',$resourceType) || count($resourceType)!==2) {
|
||||
throw new Sabre_DAV_Exception_InvalidResourceType('Unknown resourceType for this collection');
|
||||
}
|
||||
$this->caldavBackends[0]->createCalendar($this->principalInfo['uri'], $name, $properties);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOwner() {
|
||||
|
||||
return $this->principalInfo['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a group principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getGroup() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
* Each ACE has the following properties:
|
||||
* * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
|
||||
* currently the only supported privileges
|
||||
* * 'principal', a url to the principal who owns the node
|
||||
* * 'protected' (optional), indicating that this ACE is not allowed to
|
||||
* be updated.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getACL() {
|
||||
return array(
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'],
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalInfo['uri'],
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ACL
|
||||
*
|
||||
* This method will receive a list of new ACE's.
|
||||
*
|
||||
* @param array $acl
|
||||
* @throws Sabre_DAV_Exception_MethodNotAllowed
|
||||
* @return void
|
||||
*/
|
||||
public function setACL(array $acl) {
|
||||
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Changing ACL is not yet supported');
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of supported privileges for this node.
|
||||
*
|
||||
* The returned data structure is a list of nested privileges.
|
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
|
||||
* standard structure.
|
||||
*
|
||||
* If null is returned from this method, the default privilege set is used,
|
||||
* which is fine for most common usecases.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function getSupportedPrivilegeSet()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
# Generated automatically - do not change!
|
||||
|
||||
class DBClass_friendica_calendarobjects extends DBClass_animexx {
|
||||
/** @var $PRIMARY_KEY array */
|
||||
public $PRIMARY_KEY = array("id");
|
||||
|
||||
protected $SRC_TABLE = 'calendarobjects';
|
||||
/** @var $calendardata string|null */
|
||||
/** @var $uri string */
|
||||
/** @var $lastmodified string|null */
|
||||
/** @var $etag string */
|
||||
|
||||
public $calendardata, $uri, $lastmodified, $etag;
|
||||
|
||||
/** @var $id int */
|
||||
/** @var $namespace int */
|
||||
/** @var $namespace_id int */
|
||||
/** @var $size int */
|
||||
|
||||
public $id, $namespace, $namespace_id, $size;
|
||||
|
||||
|
||||
protected $_string_fields = array('calendardata', 'uri', 'lastmodified', 'etag');
|
||||
protected $_int_fields = array('id', 'namespace', 'namespace_id', 'size');
|
||||
protected $_null_fields = array('calendardata', 'lastmodified');
|
||||
}
|
29
dav/common/dbclasses/dbclass.friendica.calendars.class.php
Normal file
29
dav/common/dbclasses/dbclass.friendica.calendars.class.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
# Generated automatically - do not change!
|
||||
|
||||
class DBClass_friendica_calendars extends DBClass_animexx {
|
||||
/** @var $PRIMARY_KEY array */
|
||||
public $PRIMARY_KEY = array("namespace", "namespace_id");
|
||||
|
||||
protected $SRC_TABLE = 'calendars';
|
||||
/** @var $calendarcolor string */
|
||||
/** @var $displayname string */
|
||||
/** @var $timezone string */
|
||||
/** @var $description string */
|
||||
|
||||
public $calendarcolor, $displayname, $timezone, $description;
|
||||
|
||||
/** @var $namespace int */
|
||||
/** @var $namespace_id int */
|
||||
/** @var $uid int */
|
||||
/** @var $calendarorder int */
|
||||
/** @var $ctag int */
|
||||
|
||||
public $namespace, $namespace_id, $uid, $calendarorder, $ctag;
|
||||
|
||||
|
||||
protected $_string_fields = array('calendarcolor', 'displayname', 'timezone', 'description');
|
||||
protected $_int_fields = array('namespace', 'namespace_id', 'uid', 'calendarorder', 'ctag');
|
||||
protected $_null_fields = array();
|
||||
}
|
35
dav/common/dbclasses/dbclass.friendica.jqcalendar.class.php
Normal file
35
dav/common/dbclasses/dbclass.friendica.jqcalendar.class.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
# Generated automatically - do not change!
|
||||
|
||||
class DBClass_friendica_jqcalendar extends DBClass_animexx {
|
||||
/** @var $PRIMARY_KEY array */
|
||||
public $PRIMARY_KEY = array("id");
|
||||
|
||||
protected $SRC_TABLE = 'jqcalendar';
|
||||
/** @var $ical_uri string */
|
||||
/** @var $ical_recurr_uri string */
|
||||
/** @var $Subject string|null */
|
||||
/** @var $Location string|null */
|
||||
/** @var $Description string|null */
|
||||
/** @var $StartTime string|null */
|
||||
/** @var $EndTime string|null */
|
||||
/** @var $Color string|null */
|
||||
/** @var $RecurringRule string|null */
|
||||
|
||||
public $ical_uri, $ical_recurr_uri, $Subject, $Location, $Description, $StartTime, $EndTime, $Color, $RecurringRule;
|
||||
|
||||
/** @var $id int */
|
||||
/** @var $uid int */
|
||||
/** @var $namespace int */
|
||||
/** @var $namespace_id int */
|
||||
/** @var $permission_edit int */
|
||||
/** @var $IsAllDayEvent int */
|
||||
|
||||
public $id, $uid, $namespace, $namespace_id, $permission_edit, $IsAllDayEvent;
|
||||
|
||||
|
||||
protected $_string_fields = array('ical_uri', 'ical_recurr_uri', 'Subject', 'Location', 'Description', 'StartTime', 'EndTime', 'Color', 'RecurringRule');
|
||||
protected $_int_fields = array('id', 'uid', 'namespace', 'namespace_id', 'permission_edit', 'IsAllDayEvent');
|
||||
protected $_null_fields = array('Subject', 'Location', 'Description', 'StartTime', 'EndTime', 'Color', 'RecurringRule');
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
# Generated automatically - do not change!
|
||||
|
||||
class DBClass_friendica_notifications extends DBClass_animexx {
|
||||
/** @var $PRIMARY_KEY array */
|
||||
public $PRIMARY_KEY = array("id");
|
||||
|
||||
protected $SRC_TABLE = 'notifications';
|
||||
/** @var $ical_uri string */
|
||||
/** @var $ical_recurr_uri string */
|
||||
/** @var $alert_date string */
|
||||
/** @var $rel_type string */
|
||||
|
||||
public $ical_uri, $ical_recurr_uri, $alert_date, $rel_type;
|
||||
|
||||
/** @var $id int */
|
||||
/** @var $uid int */
|
||||
/** @var $namespace int */
|
||||
/** @var $namespace_id int */
|
||||
/** @var $rel_value int */
|
||||
/** @var $notified int */
|
||||
|
||||
public $id, $uid, $namespace, $namespace_id, $rel_value, $notified;
|
||||
|
||||
/** @var $REL_TYPE_VALUES array */
|
||||
public static $REL_TYPE_VALUES = array('second', 'minute', 'hour', 'day', 'week', 'month', 'year');
|
||||
public static $REL_TYPE_SECOND = 'second';
|
||||
public static $REL_TYPE_MINUTE = 'minute';
|
||||
public static $REL_TYPE_HOUR = 'hour';
|
||||
public static $REL_TYPE_DAY = 'day';
|
||||
public static $REL_TYPE_WEEK = 'week';
|
||||
public static $REL_TYPE_MONTH = 'month';
|
||||
public static $REL_TYPE_YEAR = 'year';
|
||||
|
||||
|
||||
protected $_string_fields = array('ical_uri', 'ical_recurr_uri', 'alert_date', 'rel_type');
|
||||
protected $_int_fields = array('id', 'uid', 'namespace', 'namespace_id', 'rel_value', 'notified');
|
||||
protected $_null_fields = array();
|
||||
}
|
50
dav/common/dbclasses/dbclass_animexx.class.php
Normal file
50
dav/common/dbclasses/dbclass_animexx.class.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
class DBClass_animexx
|
||||
{
|
||||
protected $_string_fields = array();
|
||||
protected $_int_fields = array();
|
||||
protected $_float_fields = array();
|
||||
protected $_null_fields = array();
|
||||
|
||||
public $PRIMARY_KEY = array();
|
||||
protected $SRC_TABLE = "";
|
||||
|
||||
/**
|
||||
* @param $dbarray_or_id
|
||||
* @throws Exception
|
||||
*/
|
||||
function __construct($dbarray_or_id)
|
||||
{
|
||||
if (is_numeric($dbarray_or_id) && count($this->PRIMARY_KEY) == 1) {
|
||||
$dbarray_or_id = q("SELECT * FROM %s%s%s WHERE %s=%d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->SRC_TABLE, $this->PRIMARY_KEY[0], IntVal($dbarray_or_id)
|
||||
);
|
||||
if (count($dbarray_or_id) == 0) throw new Exception("Not found");
|
||||
$dbarray_or_id = $dbarray_or_id[0];
|
||||
}
|
||||
if (is_array($dbarray_or_id)) {
|
||||
foreach ($this->_string_fields as $field) {
|
||||
$this->$field = $dbarray_or_id[$field];
|
||||
}
|
||||
foreach ($this->_int_fields as $field) {
|
||||
$this->$field = IntVal($dbarray_or_id[$field]);
|
||||
}
|
||||
foreach ($this->_float_fields as $field) {
|
||||
$this->$field = FloatVal($dbarray_or_id[$field]);
|
||||
}
|
||||
} else throw new Exception("Not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function toArray()
|
||||
{
|
||||
$arr = array();
|
||||
foreach ($this->_string_fields as $field) $arr[$field] = $this->$field;
|
||||
foreach ($this->_int_fields as $field) $arr[$field] = $this->$field;
|
||||
foreach ($this->_float_fields as $field) $arr[$field] = $this->$field;
|
||||
return $arr;
|
||||
}
|
||||
}
|
63
dav/common/virtual_cal_source_backend.inc.php
Normal file
63
dav/common/virtual_cal_source_backend.inc.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
abstract class VirtualCalSourceBackend {
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $uid
|
||||
* @param int $namespace
|
||||
*/
|
||||
static public function invalidateCache($uid = 0, $namespace = 0) {
|
||||
q("DELETE FROM %s%scache_synchronized WHERE `uid` = %d AND `namespace` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($uid), IntVal($namespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @param int $uid
|
||||
* @param int $namespace_id
|
||||
*/
|
||||
static abstract function createCache($uid = 0, $namespace_id = 0);
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $uid
|
||||
* @param int $namespace
|
||||
* @return array
|
||||
*/
|
||||
static public function getCachedItems($uid = 0, $namespace = 0) {
|
||||
$uid = IntVal($uid);
|
||||
$namespace = IntVal($namespace);
|
||||
$r = q("SELECT COUNT(*) n FROM %s%scache_synchronized WHERE `uid` = %d AND `namespace` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($uid), $namespace);
|
||||
|
||||
if ($r[0]["n"] == 0) self::createCache();
|
||||
|
||||
$r = q("SELECT * FROM %s%scal_virtual_object_cache WHERE `uid` = %d AND `namespace` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $uid, $namespace);
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @param int $uid
|
||||
* @param int $namespace_id
|
||||
* @param string $date_from
|
||||
* @param string $date_to
|
||||
* @return array
|
||||
*/
|
||||
abstract static public function getItemsByTime($uid = 0, $namespace_id = 0, $date_from = "", $date_to = "");
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @param int $uid
|
||||
* @param string $uri
|
||||
* @return array
|
||||
*/
|
||||
abstract static public function getItemsByUri($uid = 0, $uri);
|
||||
|
||||
}
|
25
dav/common/wdcal.js
Normal file
25
dav/common/wdcal.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
function wdcal_edit_init(dateFormat) {
|
||||
"use strict";
|
||||
|
||||
$("#cal_color").colorPicker();
|
||||
|
||||
$("#cal_start_time").timePicker({ step: 15 });
|
||||
$("#cal_end_time").timePicker();
|
||||
|
||||
$("#cal_start_date").datepicker({
|
||||
"dateFormat": dateFormat
|
||||
});
|
||||
$("#cal_end_date").datepicker({
|
||||
"dateFormat": dateFormat
|
||||
});
|
||||
|
||||
$("#notification").on("click change", function() {
|
||||
if ($(this).prop("checked")) $("#notification_detail").show();
|
||||
else ($("#notification_detail")).hide();
|
||||
}).change();
|
||||
|
||||
$("#cal_allday").on("click change", function() {
|
||||
if ($(this).prop("checked")) $("#cal_end_time, #cal_start_time").hide();
|
||||
else $("#cal_end_time, #cal_start_time").show();
|
||||
}).change();
|
||||
}
|
2845
dav/common/wdcal/js/jquery.calendar.js
Normal file
2845
dav/common/wdcal/js/jquery.calendar.js
Normal file
File diff suppressed because it is too large
Load diff
210
dav/common/wdcal/js/main.js
Normal file
210
dav/common/wdcal/js/main.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
$(function () {
|
||||
"use strict";
|
||||
|
||||
$.fn.animexxCalendar = function (option) {
|
||||
//(wdcal_view, std_theme, data_feed_url, readonly, height_diff) {
|
||||
|
||||
var url_cal_add = "?";
|
||||
$(this).find(".calselect input[type=checkbox]").each(function() {
|
||||
if ($(this).prop("checked")) url_cal_add += "cal[]=" + $(this).val() + "&";
|
||||
});
|
||||
|
||||
var def = {
|
||||
calendars:[],
|
||||
calendars_show:[],
|
||||
view:"week",
|
||||
theme:0,
|
||||
onWeekOrMonthToDay:wtd,
|
||||
onBeforeRequestData:cal_beforerequest,
|
||||
onAfterRequestData:cal_afterrequest,
|
||||
onRequestDataError:cal_onerror,
|
||||
autoload:true,
|
||||
data_feed_url:"",
|
||||
url:option.data_feed_url + url_cal_add + "method=list",
|
||||
quickAddUrl:option.data_feed_url + url_cal_add + "method=add",
|
||||
quickUpdateUrl:option.data_feed_url + url_cal_add + "method=update",
|
||||
quickDeleteUrl:option.data_feed_url + url_cal_add + "method=remove"
|
||||
};
|
||||
|
||||
option = $.extend(def, option);
|
||||
|
||||
var $animexxcal = $(this),
|
||||
$gridcontainer = $animexxcal.find(".gridcontainer"),
|
||||
$dv = $animexxcal.find(".calhead"),
|
||||
$caltoolbar = $animexxcal.find(".ctoolbar"),
|
||||
$txtdatetimeshow = $animexxcal.find(".txtdatetimeshow"),
|
||||
$loadingpanel = $animexxcal.find(".loadingpanel"),
|
||||
$loaderrpanel = $animexxcal.find(".loaderror");
|
||||
|
||||
var _MH = document.documentElement.clientHeight;
|
||||
var dvH = $dv.height() + 2;
|
||||
|
||||
option.height = _MH - dvH - option.height_diff;
|
||||
if (option.height < 300) option.height = 300;
|
||||
option.eventItems = [];
|
||||
|
||||
$animexxcal.find(".hdtxtshow").datepicker({
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
onSelect: function(dateText, inst) {
|
||||
var r = new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay);
|
||||
var p = $gridcontainer.gotoDate(r).BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$animexxcal.find(".txtdatetimeshow").text(p.datestrshow);
|
||||
}
|
||||
}
|
||||
});
|
||||
$animexxcal.find(".txtdatetimeshow").css("cursor", "pointer").bind("click", function() {
|
||||
$animexxcal.find(".hdtxtshow").datepicker("show");
|
||||
});
|
||||
|
||||
var p = $gridcontainer.bcalendar(option).BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
|
||||
$caltoolbar.noSelect();
|
||||
|
||||
function cal_beforerequest(type) {
|
||||
var t = "Lade Daten...";
|
||||
switch (type) {
|
||||
case 1:
|
||||
t = "Lade Daten...";
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
t = "Wird bearbeitete ...";
|
||||
break;
|
||||
}
|
||||
$loaderrpanel.hide();
|
||||
$loadingpanel.html(t).show();
|
||||
}
|
||||
|
||||
function cal_afterrequest(type) {
|
||||
var p = $gridcontainer.BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
$loadingpanel.hide();
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
$loadingpanel.html("Erfolg!");
|
||||
$gridcontainer.reload();
|
||||
window.setTimeout(function () {
|
||||
$loadingpanel.hide();
|
||||
}, 2000);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cal_onerror(type, data) {
|
||||
$loaderrpanel.show();
|
||||
}
|
||||
|
||||
function wtd(p) {
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
$caltoolbar.find("div.fcurrent").removeClass("fcurrent");
|
||||
$animexxcal.find(".showdaybtn").addClass("fcurrent");
|
||||
}
|
||||
|
||||
//to show day view
|
||||
$animexxcal.find(".showdaybtn").on("click", function (e) {
|
||||
//document.location.href="#day";
|
||||
$caltoolbar.find("div.fcurrent").removeClass("fcurrent");
|
||||
$(this).addClass("fcurrent");
|
||||
var p = $gridcontainer.switchView("day").BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
//to show week view
|
||||
$animexxcal.find(".showweekbtn").on("click", function (e) {
|
||||
//document.location.href="#week";
|
||||
$caltoolbar.find("div.fcurrent").removeClass("fcurrent");
|
||||
$(this).addClass("fcurrent");
|
||||
var p = $gridcontainer.switchView("week").BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
//to show month view
|
||||
$animexxcal.find(".showmonthbtn").on("click", function (e) {
|
||||
//document.location.href="#month";
|
||||
$caltoolbar.find("div.fcurrent").removeClass("fcurrent");
|
||||
$(this).addClass("fcurrent");
|
||||
var p = $gridcontainer.switchView("month").BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$animexxcal.find(".showreflashbtn").on("click", function (e) {
|
||||
$gridcontainer.reload();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
//go to today
|
||||
$animexxcal.find(".showtodaybtn").on("click", function (e) {
|
||||
var p = $gridcontainer.gotoDate().BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
});
|
||||
//previous date range
|
||||
$animexxcal.find(".sfprevbtn").on("click", function (e) {
|
||||
var p = $gridcontainer.previousRange().BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
//next date range
|
||||
$animexxcal.find(".sfnextbtn").on("click", function (e) {
|
||||
var p = $gridcontainer.nextRange().BcalGetOp();
|
||||
if (p && p.datestrshow) {
|
||||
$txtdatetimeshow.text(p.datestrshow);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$animexxcal.find(".calselect input[type=checkbox]").on("click change", function() {
|
||||
var url_cal_add = option.data_feed_url + "?";
|
||||
$animexxcal.find(".calselect input[type=checkbox]").each(function() {
|
||||
if ($(this).prop("checked")) url_cal_add += "cal[]=" + $(this).val() + "&";
|
||||
});
|
||||
/*
|
||||
url:option.data_feed_url + url_cal_add + "method=list",
|
||||
quickAddUrl:option.data_feed_url + url_cal_add + "method=add",
|
||||
quickUpdateUrl:option.data_feed_url + url_cal_add + "method=update",
|
||||
quickDeleteUrl:option.data_feed_url + url_cal_add + "method=remove"
|
||||
|
||||
*/
|
||||
var url = url_cal_add + "method=list";
|
||||
var p = $gridcontainer.BcalGetOp();
|
||||
if (p.url != url) {
|
||||
$gridcontainer.BcalSetOp({
|
||||
"url": url_cal_add + "method=list",
|
||||
"quickAddUrl": url_cal_add + "method=add",
|
||||
"quickUpdateUrl": url_cal_add + "method=update",
|
||||
"quickDeleteUrl": url_cal_add + "method=remove"
|
||||
});
|
||||
$gridcontainer.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
57
dav/common/wdcal/js/wdCalendar_lang_DE.js
Normal file
57
dav/common/wdcal/js/wdCalendar_lang_DE.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
var i18n = $.extend({}, i18n || {}, {
|
||||
xgcalendar: {
|
||||
dateformat: {
|
||||
"fulldaykey": "ddMMyyyy",
|
||||
"fulldayshow": "d L yyyy",
|
||||
"separator": ".",
|
||||
"year_index": 2,
|
||||
"month_index": 1,
|
||||
"day_index": 0,
|
||||
"day": "d",
|
||||
"sun": "So",
|
||||
"mon": "Mo",
|
||||
"tue": "Di",
|
||||
"wed": "Mi",
|
||||
"thu": "Do",
|
||||
"fri": "Fr",
|
||||
"sat": "Sa",
|
||||
"jan": "Jan",
|
||||
"feb": "Feb",
|
||||
"mar": "Mär",
|
||||
"apr": "Apr",
|
||||
"may": "Mai",
|
||||
"jun": "Jun",
|
||||
"jul": "Jul",
|
||||
"aug": "Aug",
|
||||
"sep": "Sep",
|
||||
"oct": "Okt",
|
||||
"nov": "Nov",
|
||||
"dec": "Dez"
|
||||
},
|
||||
"no_implemented": "Nicht eingebaut",
|
||||
"to_date_view": "Zum aktuellen Datum gehen",
|
||||
"i_undefined": "Undefined",
|
||||
"allday_event": "Ganztages-Termin",
|
||||
"repeat_event": "Wiederholter Termin",
|
||||
"time": "Zeit",
|
||||
"event": "Termin",
|
||||
"location": "Ort",
|
||||
"participant": "Teilnehmer",
|
||||
"get_data_exception": "Exception when getting data",
|
||||
"new_event": "Neuer Termin",
|
||||
"confirm_delete_event": "Diesen Termin wirklich löschen? ",
|
||||
"confrim_delete_event_or_all": "Nur diesen einen Termin löschen, oder alle Wiederholungen? \r\n[OK] für diesen einen, [Abbrechen] für alle.",
|
||||
"data_format_error": "Data format error! ",
|
||||
"invalid_title": "Der Titel des Termins darf nicht leer sein und kein ($<>) enthalten.",
|
||||
"view_no_ready": "View is not ready",
|
||||
"example": "e.g., Treffen in Raum 23",
|
||||
"content": "Was",
|
||||
"create_event": "Termin anlegen",
|
||||
"update_detail": "Details bearbeiten",
|
||||
"click_to_detail": "Details anzeigen",
|
||||
"i_delete": "Löschen",
|
||||
"day_plural": "Tage",
|
||||
"others": "Weitere: ",
|
||||
"item": ""
|
||||
}
|
||||
});
|
57
dav/common/wdcal/js/wdCalendar_lang_EN.js
Normal file
57
dav/common/wdcal/js/wdCalendar_lang_EN.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
var i18n = $.extend({}, i18n || {}, {
|
||||
xgcalendar: {
|
||||
dateformat: {
|
||||
"fulldaykey": "ddMMyyyy",
|
||||
"fulldayshow": "d L yyyy",
|
||||
"separator": ".",
|
||||
"year_index": 2,
|
||||
"month_index": 1,
|
||||
"day_index": 0,
|
||||
"day": "d",
|
||||
"sun": "Su",
|
||||
"mon": "Mo",
|
||||
"tue": "Tu",
|
||||
"wed": "Mi",
|
||||
"thu": "Th",
|
||||
"fri": "Fr",
|
||||
"sat": "Sa",
|
||||
"jan": "Jan",
|
||||
"feb": "Feb",
|
||||
"mar": "Mar",
|
||||
"apr": "Apr",
|
||||
"may": "May",
|
||||
"jun": "Jun",
|
||||
"jul": "Jul",
|
||||
"aug": "Aug",
|
||||
"sep": "Sep",
|
||||
"oct": "Oct",
|
||||
"nov": "Nov",
|
||||
"dec": "Dec"
|
||||
},
|
||||
"no_implemented": "Not implemented",
|
||||
"to_date_view": "Go to today",
|
||||
"i_undefined": "Undefined",
|
||||
"allday_event": "All-day event",
|
||||
"repeat_event": "Recurring event",
|
||||
"time": "Time",
|
||||
"event": "Event",
|
||||
"location": "Loaction",
|
||||
"participant": "Attendees",
|
||||
"get_data_exception": "Exception when getting data",
|
||||
"new_event": "New event",
|
||||
"confirm_delete_event": "Do you really want to delete this event?",
|
||||
"confrim_delete_event_or_all": "Do you want to delete this event alone, or all recurrences? \r\n[OK] for this single item, [Abort] for all.",
|
||||
"data_format_error": "Data format error!",
|
||||
"invalid_title": "The title of an event must not be empty and must not contain ($<>).",
|
||||
"view_no_ready": "View is not ready",
|
||||
"example": "e.g., Meeting in room 23",
|
||||
"content": "Title",
|
||||
"create_event": "Create event",
|
||||
"update_detail": "Edit",
|
||||
"click_to_detail": "Show details",
|
||||
"i_delete": "Delete",
|
||||
"day_plural": "days",
|
||||
"others": "More: ",
|
||||
"item": ""
|
||||
}
|
||||
});
|
137
dav/common/wdcal_cal_source.inc.php
Normal file
137
dav/common/wdcal_cal_source.inc.php
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
|
||||
abstract class AnimexxCalSource
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int $namespace_id
|
||||
*/
|
||||
protected $namespace_id;
|
||||
|
||||
/**
|
||||
* @var DBClass_friendica_calendars $calendarDb
|
||||
*/
|
||||
protected $calendarDb;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $user_id;
|
||||
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @param int $namespace_id
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
*/
|
||||
function __construct($user_id = 0, $namespace_id = 0)
|
||||
{
|
||||
$this->namespace_id = IntVal($namespace_id);
|
||||
$this->user_id = IntVal($user_id);
|
||||
|
||||
$x = q("SELECT * FROM %s%scalendars WHERE `namespace` = %d AND `namespace_id` = %d AND `uid` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->getNamespace(), $this->namespace_id, $this->user_id
|
||||
);
|
||||
|
||||
if (count($x) != 1) throw new Sabre_DAV_Exception_NotFound("Not found");
|
||||
|
||||
try {
|
||||
$this->calendarDb = new DBClass_friendica_calendars($x[0]);
|
||||
} catch (Exception $e) {
|
||||
throw new Sabre_DAV_Exception_NotFound("Not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return int
|
||||
*/
|
||||
public static abstract function getNamespace();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $user
|
||||
* @return array
|
||||
*/
|
||||
public abstract function getPermissionsCalendar($user);
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $user
|
||||
* @param string $item_uri
|
||||
* @param string $recurrence_uri
|
||||
* @param array|null $item_arr
|
||||
* @return array
|
||||
*/
|
||||
public abstract function getPermissionsItem($user, $item_uri, $recurrence_uri, $item_arr = null);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
public abstract function updateItem($uri, $start, $end, $subject = "", $allday = false, $description = "", $location = "", $color = null,
|
||||
$timezone = "", $notification = true, $notification_type = null, $notification_value = null);
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @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
|
||||
*/
|
||||
public abstract function addItem($start, $end, $subject, $allday = false, $description = "", $location = "", $color = null,
|
||||
$timezone = "", $notification = true, $notification_type = null, $notification_value = null);
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
*/
|
||||
public abstract function removeItem($uri);
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param string $sd
|
||||
* @param string $ed
|
||||
* @return array
|
||||
*/
|
||||
public abstract function listItemsByRange($sd, $ed);
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param string $uri
|
||||
* @return array
|
||||
*/
|
||||
public abstract function getItemByUri($uri);
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return null|string
|
||||
*/
|
||||
public function getItemDetailRedirect($uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
331
dav/common/wdcal_cal_source_private.inc.php
Normal file
331
dav/common/wdcal_cal_source_private.inc.php
Normal file
|
@ -0,0 +1,331 @@
|
|||
<?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/";
|
||||
}
|
||||
}
|
277
dav/common/wdcal_configuration.php
Normal file
277
dav/common/wdcal_configuration.php
Normal file
|
@ -0,0 +1,277 @@
|
|||
<?php
|
||||
|
||||
abstract class wdcal_local
|
||||
{
|
||||
|
||||
const LOCAL_US = 0;
|
||||
const LOCAL_DE = 1;
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return array|wdcal_local[]
|
||||
*/
|
||||
static function getInstanceClasses() {
|
||||
return array(
|
||||
self::LOCAL_US => "wdcal_local_us",
|
||||
self::LOCAL_DE => "wdcal_local_de",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $config
|
||||
* @return null|wdcal_local
|
||||
*/
|
||||
static function getInstance($config = 0) {
|
||||
$classes = self::getInstanceClasses();
|
||||
if (isset($classes[$config])) return new $classes[$config];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $uid
|
||||
* @return wdcal_local
|
||||
*/
|
||||
static function getInstanceByUser($uid = 0) {
|
||||
$dateformat = get_pconfig($uid, "dav", "dateformat");
|
||||
$format = self::getInstance($dateformat);
|
||||
if ($format == null) $format = self::getInstance(self::LOCAL_US);
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
abstract static function getName();
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @return int
|
||||
*/
|
||||
abstract static function getID();
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return int
|
||||
*/
|
||||
function date_local2timestamp($str) {
|
||||
$x = $this->date_parseLocal($str);
|
||||
return mktime($x["hour"], $x["minute"], $x["second"], $x["month"], $x["day"], $x["year"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param string $str
|
||||
* @return array
|
||||
*/
|
||||
abstract function date_parseLocal($str);
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
abstract function date_timestamp2local($ts);
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return int
|
||||
*/
|
||||
abstract function getFirstDayOfWeek();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return string
|
||||
*/
|
||||
abstract function dateformat_js_dm1();
|
||||
/**
|
||||
* @abstract
|
||||
* @return string
|
||||
*/
|
||||
abstract function dateformat_js_dm2();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return string
|
||||
*/
|
||||
abstract function dateformat_js_dm3();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return string
|
||||
*/
|
||||
abstract function dateformat_datepicker_js();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
abstract function dateformat_datepicker_php($ts = 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class wdcal_local_us extends wdcal_local {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static function getName() {
|
||||
return t("U.S. Time Format (mm/dd/YYYY)");
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return int
|
||||
*/
|
||||
static function getID() {
|
||||
return wdcal_local::LOCAL_US;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return array
|
||||
*/
|
||||
function date_parseLocal($str) {
|
||||
return date_parse_from_format("m/d/Y H:i", $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function date_timestamp2local($ts)
|
||||
{
|
||||
return date("m/d/Y H:i", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function getFirstDayOfWeek() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm1() {
|
||||
return "W, M/d";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm2() {
|
||||
return "d. L";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm3() {
|
||||
return "d L yyyy";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_datepicker_js() {
|
||||
return "mm/dd/yy";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_datepicker_php($ts = 0) {
|
||||
return date("m/d/Y", $ts);
|
||||
}
|
||||
}
|
||||
|
||||
class wdcal_local_de extends wdcal_local {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static function getName() {
|
||||
return t("German Time Format (dd.mm.YYYY)");
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return int
|
||||
*/
|
||||
static function getID() {
|
||||
return wdcal_local::LOCAL_DE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return array
|
||||
*/
|
||||
function date_parseLocal($str)
|
||||
{
|
||||
return date_parse_from_format("d.m.Y H:i", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function date_timestamp2local($ts)
|
||||
{
|
||||
return date("d.m.Y H:i", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function getFirstDayOfWeek() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm1() {
|
||||
return "W, d.M";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm2() {
|
||||
return "d. L";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_js_dm3() {
|
||||
return "d L yyyy";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_datepicker_js() {
|
||||
return "dd.mm.yy";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function dateformat_datepicker_php($ts = 0) {
|
||||
return date("d.m.Y", $ts);
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue