mirror of
https://git.friendi.ca/friendica/friendica-addons.git
synced 2025-07-07 00:48:55 +00:00
Heavily refactored, including multiple calendars per user and recurring events. Not in an installable state yet, though
This commit is contained in:
parent
4a5e30ec84
commit
fefee23e90
78 changed files with 8026 additions and 1205 deletions
|
@ -1,6 +1,11 @@
|
|||
<?php
|
||||
|
||||
|
||||
define("DAV_ACL_READ", "{DAV:}read");
|
||||
define("DAV_ACL_WRITE", "{DAV:}write");
|
||||
define("DAV_DISPLAYNAME", "{DAV:}displayname");
|
||||
|
||||
|
||||
class vcard_source_data_email
|
||||
{
|
||||
public $email, $type;
|
||||
|
@ -83,7 +88,7 @@ class vcard_source_data
|
|||
/** @var array|vcard_source_data_email[] $email */
|
||||
public $emails;
|
||||
|
||||
/** @var array|vcard_source_data_addresses[] $addresses */
|
||||
/** @var array|vcard_source_data_address[] $addresses */
|
||||
public $addresses;
|
||||
|
||||
/** @var vcard_source_data_photo */
|
||||
|
@ -136,41 +141,6 @@ function vcard_source_compile($vcardsource)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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)
|
||||
|
@ -216,457 +186,196 @@ 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);
|
||||
$str = str_replace("\n\n", "\n", $str);
|
||||
$str = str_replace("\n\n", "\n", $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param DBClass_friendica_calendars $calendar
|
||||
* @param DBClass_friendica_calendarobjects $calendarobject
|
||||
* @return Sabre_CalDAV_AnimexxCalendarRootNode
|
||||
*/
|
||||
function renderCalDavEntry_data(&$calendar, &$calendarobject)
|
||||
function dav_createRootCalendarNode()
|
||||
{
|
||||
$caldavBackend_std = Sabre_CalDAV_Backend_Private::getInstance();
|
||||
$caldavBackend_community = Sabre_CalDAV_Backend_Friendica::getInstance();
|
||||
|
||||
return new Sabre_CalDAV_AnimexxCalendarRootNode(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), array(
|
||||
$caldavBackend_std,
|
||||
$caldavBackend_community,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Sabre_CardDAV_AddressBookRootFriendica
|
||||
*/
|
||||
function dav_createRootContactsNode()
|
||||
{
|
||||
$carddavBackend_std = Sabre_CardDAV_Backend_Std::getInstance();
|
||||
$carddavBackend_community = Sabre_CardDAV_Backend_FriendicaCommunity::getInstance();
|
||||
|
||||
return new Sabre_CardDAV_AddressBookRootFriendica(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), array(
|
||||
$carddavBackend_std,
|
||||
$carddavBackend_community,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $force_authentication
|
||||
* @param bool $needs_caldav
|
||||
* @param bool $needs_carddav
|
||||
* @return Sabre_DAV_Server
|
||||
*/
|
||||
function dav_create_server($force_authentication = false, $needs_caldav = true, $needs_carddav = true)
|
||||
{
|
||||
$arr = array(
|
||||
new Sabre_DAV_SimpleCollection('principals', array(
|
||||
new Sabre_CalDAV_Principal_Collection(Sabre_DAVACL_PrincipalBackend_Std::getInstance(), "principals/users"),
|
||||
)),
|
||||
);
|
||||
if ($needs_caldav) $arr[] = dav_createRootCalendarNode();
|
||||
if ($needs_carddav) $arr[] = dav_createRootContactsNode();
|
||||
|
||||
|
||||
$tree = new Sabre_DAV_SimpleCollection('root', $arr);
|
||||
|
||||
// The object tree needs in turn to be passed to the server class
|
||||
$server = new Sabre_DAV_Server($tree);
|
||||
|
||||
$server->setBaseUri(CALDAV_URL_PREFIX);
|
||||
|
||||
$authPlugin = new Sabre_DAV_Auth_Plugin(Sabre_DAV_Auth_Backend_Std::getInstance(), 'SabreDAV');
|
||||
$server->addPlugin($authPlugin);
|
||||
|
||||
$aclPlugin = new Sabre_DAVACL_Plugin_Friendica();
|
||||
$aclPlugin->defaultUsernamePath = "principals/users";
|
||||
$server->addPlugin($aclPlugin);
|
||||
|
||||
if ($needs_caldav) {
|
||||
$caldavPlugin = new Sabre_CalDAV_Plugin();
|
||||
$server->addPlugin($caldavPlugin);
|
||||
}
|
||||
if ($needs_carddav) {
|
||||
$carddavPlugin = new Sabre_CardDAV_Plugin();
|
||||
$server->addPlugin($carddavPlugin);
|
||||
}
|
||||
|
||||
if ($force_authentication) $server->broadcastEvent('beforeMethod', array("GET", "/")); // Make it authenticate
|
||||
|
||||
return $server;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param string $with_privilege
|
||||
* @return array|Sabre_CalDAV_Calendar[]
|
||||
*/
|
||||
function dav_get_current_user_calendars(&$server, $with_privilege = "")
|
||||
{
|
||||
if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
|
||||
|
||||
$a = get_app();
|
||||
$calendar_path = "/calendars/" . strtolower($a->user["nickname"]) . "/";
|
||||
|
||||
/** @var Sabre_CalDAV_AnimexxUserCalendars $tree */
|
||||
$tree = $server->tree->getNodeForPath($calendar_path);
|
||||
/** @var array|Sabre_CalDAV_Calendar[] $calendars */
|
||||
$children = $tree->getChildren();
|
||||
|
||||
$calendars = array();
|
||||
/** @var Sabre_DAVACL_Plugin $aclplugin */
|
||||
$aclplugin = $server->getPlugin("acl");
|
||||
foreach ($children as $child) if (is_a($child, "Sabre_CalDAV_Calendar")) {
|
||||
if ($with_privilege != "") {
|
||||
$caluri = $calendar_path . $child->getName();
|
||||
if ($aclplugin->checkPrivileges($caluri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) $calendars[] = $child;
|
||||
} else {
|
||||
$calendars[] = $child;
|
||||
}
|
||||
}
|
||||
return $calendars;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param Sabre_CalDAV_Calendar $calendar
|
||||
* @param string $calendarobject_uri
|
||||
* @param string $with_privilege
|
||||
* @return null|Sabre_VObject_Component_VEvent
|
||||
*/
|
||||
function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
|
||||
{
|
||||
$obj = $calendar->getChild($calendarobject_uri);
|
||||
|
||||
if ($with_privilege == "") $with_privilege = DAV_ACL_READ;
|
||||
|
||||
$a = get_app();
|
||||
$uri = "/calendars/" . strtolower($a->user["nickname"]) . "/" . $calendar->getName() . "/" . $calendarobject_uri;
|
||||
|
||||
/** @var Sabre_DAVACL_Plugin $aclplugin */
|
||||
$aclplugin = $server->getPlugin("acl");
|
||||
if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) return null;
|
||||
|
||||
$data = $obj->get();
|
||||
$vObject = Sabre_VObject_Reader::read($data);
|
||||
|
||||
return $vObject;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param int $id
|
||||
* @param string $with_privilege
|
||||
* @return null|Sabre_CalDAV_Calendar
|
||||
*/
|
||||
function dav_get_current_user_calendar_by_id(&$server, $id, $with_privilege = "")
|
||||
{
|
||||
$calendars = dav_get_current_user_calendars($server, $with_privilege);
|
||||
|
||||
$calendar = null;
|
||||
foreach ($calendars as $cal) {
|
||||
$prop = $cal->getProperties(array("id"));
|
||||
if (isset($prop["id"]) && $prop["id"] == $id) $calendar = $cal;
|
||||
}
|
||||
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return Sabre_VObject_Component_VEvent $vObject
|
||||
*/
|
||||
function dav_create_empty_vevent($uid = "")
|
||||
{
|
||||
$a = get_app();
|
||||
if ($uid == "") $uid = uniqid();
|
||||
return Sabre_VObject_Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Friendica//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . $a->get_hostname() .
|
||||
"\r\nDTSTAMP:" . date("Ymd") . "T" . date("His") . "Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Sabre_VObject_Component_VEvent $vObject
|
||||
* @return Sabre_VObject_Component_VEvent|null
|
||||
*/
|
||||
function dav_get_eventComponent(&$vObject)
|
||||
{
|
||||
$component = null;
|
||||
$componentType = "";
|
||||
foreach ($vObject->getComponents() as $component) {
|
||||
if ($component->name !== 'VTIMEZONE') {
|
||||
$componentType = $component->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($componentType != "VEVENT") return null;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $component;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param string $recurr_uri
|
||||
* @param int $uid
|
||||
* @param string $timezone
|
||||
* @param string $goaway_url
|
||||
* @return string
|
||||
*/
|
||||
function wdcal_postEditPage($uri, $recurr_uri = "", $uid = 0, $timezone = "", $goaway_url = "")
|
||||
{
|
||||
$uid = IntVal($uid);
|
||||
$localization = wdcal_local::getInstanceByUser($uid);
|
||||
|
||||
if (isset($_REQUEST["allday"])) {
|
||||
$start = $localization->date_parseLocal($_REQUEST["start_date"] . " 00:00");
|
||||
$end = $localization->date_parseLocal($_REQUEST["end_date"] . " 20:00");
|
||||
$isallday = true;
|
||||
} else {
|
||||
$start = $localization->date_parseLocal($_REQUEST["start_date"] . " " . $_REQUEST["start_time"]);
|
||||
$end = $localization->date_parseLocal($_REQUEST["end_date"] . " " . $_REQUEST["end_time"]);
|
||||
$isallday = false;
|
||||
}
|
||||
|
||||
if ($uri == "new") {
|
||||
$cals = dav_getMyCals($uid);
|
||||
foreach ($cals as $c) {
|
||||
$cs = wdcal_calendar_factory($uid, $c->namespace, $c->namespace_id);
|
||||
$p = $cs->getPermissionsCalendar($uid);
|
||||
|
||||
if ($p["write"]) try {
|
||||
$cs->addItem($start, $end, dav_compat_getRequestVar("subject"), $isallday, dav_compat_parse_text_serverside("wdcal_desc"),
|
||||
dav_compat_getRequestVar("location"), dav_compat_getRequestVar("color"), $timezone,
|
||||
isset($_REQUEST["notification"]), $_REQUEST["notification_type"], $_REQUEST["notification_value"]);
|
||||
} catch (Exception $e) {
|
||||
notification(t("Error") . ": " . $e);
|
||||
}
|
||||
dav_compat_redirect($goaway_url);
|
||||
}
|
||||
|
||||
} else {
|
||||
$cals = dav_getMyCals($uid);
|
||||
foreach ($cals as $c) {
|
||||
$cs = wdcal_calendar_factory($uid, $c->namespace, $c->namespace_id);
|
||||
$p = $cs->getPermissionsItem($uid, $uri, $recurr_uri);
|
||||
if ($p["write"]) try {
|
||||
$cs->updateItem($uri, $start, $end,
|
||||
dav_compat_getRequestVar("subject"), $isallday, dav_compat_parse_text_serverside("wdcal_desc"),
|
||||
dav_compat_getRequestVar("location"), dav_compat_getRequestVar("color"), $timezone,
|
||||
isset($_REQUEST["notification"]), $_REQUEST["notification_type"], $_REQUEST["notification_value"]);
|
||||
} catch (Exception $e) {
|
||||
notification(t("Error") . ": " . $e);
|
||||
}
|
||||
dav_compat_redirect($goaway_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function wdcal_print_feed($base_path = "")
|
||||
{
|
||||
$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], $base_path);
|
||||
$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();
|
||||
}
|
||||
|
||||
|
|
185
dav/common/calendar_rendering.fnk.php
Normal file
185
dav/common/calendar_rendering.fnk.php
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_VObject_Component_VAlarm $alarm
|
||||
* @param Sabre_VObject_Component_VEvent|Sabre_VObject_Component_VTodo $parent
|
||||
* @return DateTime|null
|
||||
* @throws Sabre_DAV_Exception
|
||||
*/
|
||||
function renderCalDavEntry_calcalarm(&$alarm, &$parent)
|
||||
{
|
||||
$trigger = $alarm->__get("TRIGGER");
|
||||
if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
|
||||
$triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger);
|
||||
|
||||
$related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
|
||||
|
||||
if ($related === 'START') {
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $parent->__get("DTSTART");
|
||||
$effectiveTrigger = $dtstart->getDateTime();
|
||||
$effectiveTrigger->add($triggerDuration);
|
||||
} else {
|
||||
if ($parent->name === 'VTODO') {
|
||||
$endProp = 'DUE';
|
||||
} else {
|
||||
$endProp = 'DTEND';
|
||||
}
|
||||
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $parent->__get("DTSTART");
|
||||
if (isset($parent->$endProp)) {
|
||||
$effectiveTrigger = clone $parent->$endProp->getDateTime();
|
||||
$effectiveTrigger->add($triggerDuration);
|
||||
} elseif ($parent->__get("DURATION") != "") {
|
||||
$effectiveTrigger = clone $dtstart->getDateTime();
|
||||
$duration = Sabre_VObject_DateTimeParser::parseDuration($parent->__get("DURATION"));
|
||||
$effectiveTrigger->add($duration);
|
||||
$effectiveTrigger->add($triggerDuration);
|
||||
} else {
|
||||
$effectiveTrigger = clone $dtstart->getDateTime();
|
||||
$effectiveTrigger->add($triggerDuration);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ??? @TODO
|
||||
$effectiveTrigger = $trigger->getDateTime();
|
||||
}
|
||||
return $effectiveTrigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $calendar
|
||||
* @param array $calendarobject
|
||||
* @throws Sabre_DAV_Exception_BadRequest
|
||||
* @return void
|
||||
*/
|
||||
function renderCalDavEntry_data(&$calendar, &$calendarobject)
|
||||
{
|
||||
/** @var Sabre_VObject_Component_VCalendar $vObject */
|
||||
$vObject = Sabre_VObject_Reader::read($calendarobject["calendardata"]);
|
||||
$componentType = null;
|
||||
/** @var Sabre_VObject_Component_VEvent $component */
|
||||
$component = null;
|
||||
foreach ($vObject->getComponents() as $component) {
|
||||
if ($component->name !== 'VTIMEZONE') {
|
||||
$componentType = $component->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$componentType) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
|
||||
}
|
||||
|
||||
|
||||
if ($componentType !== 'VEVENT') return;
|
||||
|
||||
$event = array(
|
||||
"description" => ($component->__get("DESCRIPTION") ? $component->__get("DESCRIPTION")->value : null),
|
||||
"summary" => ($component->__get("SUMMARY") ? $component->__get("SUMMARY")->value : null),
|
||||
"location" => ($component->__get("LOCATION") ? $component->__get("LOCATION")->value : null),
|
||||
"color" => ($component->__get("X-ANIMEXX-COLOR") ? $component->__get("X-ANIMEXX-COLOR")->value : null),
|
||||
);
|
||||
|
||||
$recurring = ($component->__get("RRULE") ? 1 : 0);
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $component->__get("DTSTART");
|
||||
$allday = ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE ? 1 : 0);
|
||||
|
||||
/** @var array|Sabre_VObject_Component_VAlarm[] $alarms */
|
||||
$alarms = array();
|
||||
foreach ($component->getComponents() as $a_component) if ($a_component->name == "VALARM") {
|
||||
/** var Sabre_VObject_Component_VAlarm $component */
|
||||
$alarms[] = $a_component;
|
||||
}
|
||||
|
||||
$it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
|
||||
$last_end = 0;
|
||||
$max_ts = mktime(0, 0, 0, 1, 1, CALDAV_MAX_YEAR * 1);
|
||||
$first = true;
|
||||
|
||||
while ($it->valid() && $last_end < $max_ts && ($recurring || $first)) {
|
||||
$first = false;
|
||||
$last_end = $it->getDtEnd()->getTimestamp();
|
||||
$start = $it->getDtStart()->getTimestamp();
|
||||
|
||||
q("INSERT INTO %s%sjqcalendar (`calendar_id`, `calendarobject_id`, `Summary`, `StartTime`, `EndTime`, `IsEditable`, `IsAllDayEvent`, `IsRecurring`, `Color`) VALUES
|
||||
(%d, %d, '%s', '%s', '%s', %d, %d, %d, '%s')", CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||||
IntVal($calendar["id"]), IntVal($calendarobject["id"]), dbesc($event["summary"]), date("Y-m-d H:i:s", $start), date("Y-m-d H:i:s", $last_end),
|
||||
1, $allday, $recurring, dbesc(substr($event["color"], 1))
|
||||
);
|
||||
|
||||
foreach ($alarms as $alarm) {
|
||||
$alarm = renderCalDavEntry_calcalarm($alarm, $component);
|
||||
$notified = ($alarm->getTimestamp() < time() ? 1 : 0);
|
||||
q("INSERT INTO %s%snotifications (`calendar_id`, `calendarobject_id`, `alert_date`, `notified`) VALUES (%d, %d, '%s', %d)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendar["id"]), IntVal($calendarobject["id"]), $alarm->format("Y-m-d H:i:s"), $notified
|
||||
);
|
||||
}
|
||||
|
||||
$it->next();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
$i++;
|
||||
if (($i % 100) == 0) echo "$i / $anz\n";
|
||||
$calobjs = q("SELECT * FROM %s%scalendarobjects WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendar["id"]));
|
||||
foreach ($calobjs as $calobj) renderCalDavEntry_data($calendar, $calobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return bool
|
||||
*/
|
||||
function renderCalDavEntry_uri($uri)
|
||||
{
|
||||
$calobj = q("SELECT * FROM %s%scalendarobjects WHERE `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($uri));
|
||||
if (count($calobj) == 0) return false;
|
||||
|
||||
q("DELETE FROM %s%sjqcalendar WHERE `calendar_id` = %d AND `calendarobject_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calobj[0]["calendar_id"]), IntVal($calobj[0]["id"]));
|
||||
q("DELETE FROM %s%snotifications WHERE `calendar_id` = %d AND `calendarobject_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calobj[0]["calendar_id"]), IntVal($calobj[0]["id"]));
|
||||
|
||||
$calendars = q("SELECT * FROM %s%scalendars WHERE `id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calobj[0]["calendar_id"]));
|
||||
|
||||
renderCalDavEntry_data($calendars[0], $calobj[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $calobj_id
|
||||
* @return bool
|
||||
*/
|
||||
function renderCalDavEntry_calobj_id($calobj_id)
|
||||
{
|
||||
$calobj_id = IntVal($calobj_id);
|
||||
q("DELETE FROM %s%sjqcalendar WHERE `calendarobject_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calobj_id);
|
||||
q("DELETE FROM %s%snotifications WHERE `calendarobject_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calobj_id);
|
||||
|
||||
$calobj = q("SELECT * FROM %s%scalendarobjects WHERE `id` = '%d'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calobj_id);
|
||||
if (count($calobj) == 0) return false;
|
||||
|
||||
$calendars = q("SELECT * FROM %s%scalendars WHERE `id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calobj[0]["calendar_id"]));
|
||||
|
||||
renderCalDavEntry_data($calendars[0], $calobj[0]);
|
||||
return true;
|
||||
}
|
|
@ -1,76 +1,171 @@
|
|||
<?php
|
||||
|
||||
abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract {
|
||||
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',
|
||||
protected $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',
|
||||
'{http://apple.com/ns/ical/}calendar-order' => 'calendarorder',
|
||||
'{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor',
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return int
|
||||
*/
|
||||
abstract public function getNamespace();
|
||||
abstract public function getCalUrlPrefix();
|
||||
|
||||
|
||||
/**
|
||||
* @param int $namespace
|
||||
* @param int $namespace_id
|
||||
* @param int $calendarId
|
||||
* @param string $sd
|
||||
* @param string $ed
|
||||
* @param string $base_path
|
||||
* @return array
|
||||
*/
|
||||
protected function increaseCalendarCtag($namespace, $namespace_id) {
|
||||
$namespace = IntVal($namespace);
|
||||
$namespace_id = IntVal($namespace_id);
|
||||
abstract public function listItemsByRange($calendarId, $sd, $ed, $base_path);
|
||||
|
||||
q("UPDATE %s%scalendars SET `ctag` = `ctag` + 1 WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $namespace, $namespace_id);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static private $calendarCache = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static private $calendarObjectCache = array();
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $calendarId
|
||||
* @return array
|
||||
*/
|
||||
static public function loadCalendarById($calendarId)
|
||||
{
|
||||
if (!isset(self::$calendarCache[$calendarId])) {
|
||||
$c = q("SELECT * FROM %s%scalendars WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
self::$calendarCache[$calendarId] = $c[0];
|
||||
}
|
||||
return self::$calendarCache[$calendarId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $obj_id
|
||||
* @return array
|
||||
*/
|
||||
static public function loadCalendarobjectById($obj_id)
|
||||
{
|
||||
if (!isset(self::$calendarObjectCache[$obj_id])) {
|
||||
$o = q("SELECT * FROM %s%scalendarobjects WHERE `id` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($obj_id)
|
||||
);
|
||||
self::$calendarObjectCache[$obj_id] = $o[0];
|
||||
}
|
||||
return self::$calendarObjectCache[$obj_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
|
||||
* @static
|
||||
* @param Sabre_VObject_Component_VEvent $component
|
||||
* @return int
|
||||
*/
|
||||
public function getCalendarsForUser($principalUri)
|
||||
public static function getDtEndTimeStamp(&$component)
|
||||
{
|
||||
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;
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $component->__get("DTSTART");
|
||||
if ($component->__get("DTEND")) {
|
||||
/** @var Sabre_VObject_Property_DateTime $dtend */
|
||||
$dtend = $component->__get("DTEND");
|
||||
return $dtend->getDateTime()->getTimeStamp();
|
||||
} elseif ($component->__get("DURATION")) {
|
||||
$endDate = clone $dtstart->getDateTime();
|
||||
$endDate->add(Sabre_VObject_DateTimeParser::parse($component->__get("DURATION")->value));
|
||||
return $endDate->getTimeStamp();
|
||||
} elseif ($dtstart->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
|
||||
$endDate = clone $dtstart->getDateTime();
|
||||
$endDate->modify('+1 day');
|
||||
return $endDate->getTimeStamp();
|
||||
} else {
|
||||
return $dtstart->getDateTime()->getTimeStamp() + 3600;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses some information from calendar objects, used for optimized
|
||||
* calendar-queries.
|
||||
*
|
||||
* Returns an array with the following keys:
|
||||
* * etag
|
||||
* * size
|
||||
* * componentType
|
||||
* * firstOccurence
|
||||
* * lastOccurence
|
||||
*
|
||||
* @param string $calendarData
|
||||
* @throws Sabre_DAV_Exception_BadRequest
|
||||
* @return array
|
||||
*/
|
||||
protected function getDenormalizedData($calendarData)
|
||||
{
|
||||
/** @var Sabre_VObject_Component_VEvent $vObject */
|
||||
$vObject = Sabre_VObject_Reader::read($calendarData);
|
||||
$componentType = null;
|
||||
$component = null;
|
||||
$firstOccurence = null;
|
||||
$lastOccurence = null;
|
||||
foreach ($vObject->getComponents() as $component) {
|
||||
if ($component->name !== 'VTIMEZONE') {
|
||||
$componentType = $component->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$componentType) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
|
||||
}
|
||||
if ($componentType === 'VEVENT') {
|
||||
/** @var Sabre_VObject_Component_VEvent $component */
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $component->__get("DTSTART");
|
||||
$firstOccurence = $dtstart->getDateTime()->getTimeStamp();
|
||||
// Finding the last occurence is a bit harder
|
||||
if (!$component->__get("RRULE")) {
|
||||
$lastOccurence = self::getDtEndTimeStamp($component);
|
||||
} else {
|
||||
$it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
|
||||
$maxDate = new DateTime(CALDAV_MAX_YEAR . "-01-01");
|
||||
if ($it->isInfinite()) {
|
||||
$lastOccurence = $maxDate->getTimeStamp();
|
||||
} else {
|
||||
$end = $it->getDtEnd();
|
||||
while ($it->valid() && $end < $maxDate) {
|
||||
$end = $it->getDtEnd();
|
||||
$it->next();
|
||||
|
||||
}
|
||||
$lastOccurence = $end->getTimeStamp();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'etag' => md5($calendarData),
|
||||
'size' => strlen($calendarData),
|
||||
'componentType' => $componentType,
|
||||
'firstOccurence' => $firstOccurence,
|
||||
'lastOccurence' => $lastOccurence,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,10 +204,11 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
|
|||
* @param array $mutations
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateCalendar($calendarId, array $mutations) {
|
||||
public function updateCalendar($calendarId, array $mutations)
|
||||
{
|
||||
|
||||
$newValues = array();
|
||||
$result = array(
|
||||
$result = array(
|
||||
200 => array(), // Ok
|
||||
403 => array(), // Forbidden
|
||||
424 => array(), // Failed Dependency
|
||||
|
@ -120,17 +216,17 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
|
|||
|
||||
$hasError = false;
|
||||
|
||||
foreach($mutations as $propertyName=>$propertyValue) {
|
||||
foreach ($mutations as $propertyName=> $propertyValue) {
|
||||
|
||||
// We don't know about this property.
|
||||
if (!isset($this->propertyMap[$propertyName])) {
|
||||
$hasError = true;
|
||||
$hasError = true;
|
||||
$result[403][$propertyName] = null;
|
||||
unset($mutations[$propertyName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldName = $this->propertyMap[$propertyName];
|
||||
$fieldName = $this->propertyMap[$propertyName];
|
||||
$newValues[$fieldName] = $propertyValue;
|
||||
|
||||
}
|
||||
|
@ -138,33 +234,46 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
|
|||
// If there were any errors we need to fail the request
|
||||
if ($hasError) {
|
||||
// Properties has the remaining properties
|
||||
foreach($mutations as $propertyName=>$propertyValue) {
|
||||
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]);
|
||||
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]);
|
||||
$this->increaseCalendarCtag($calendarId);
|
||||
|
||||
$valuesSql = array();
|
||||
foreach($newValues as $fieldName=>$value) $valuesSql[] = "`" . $fieldName . "` = '" . dbesc($value) . "'";
|
||||
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])
|
||||
);
|
||||
q("UPDATE %s%scalendars SET " . implode(", ", $valuesSql) . " WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $calendarId
|
||||
*/
|
||||
protected function increaseCalendarCtag($calendarId)
|
||||
{
|
||||
q("UPDATE %s%scalendars SET `ctag` = `ctag` + 1 WHERE `id` = '%d'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
self::$calendarObjectCache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $calendar_id
|
||||
* @param int $calendarobject_id
|
||||
* @return string
|
||||
*/
|
||||
abstract function getItemDetailRedirect($calendar_id, $calendarobject_id);
|
||||
|
||||
}
|
495
dav/common/dav_caldav_backend_private.inc.php
Normal file
495
dav/common/dav_caldav_backend_private.inc.php
Normal file
|
@ -0,0 +1,495 @@
|
|||
<?php
|
||||
|
||||
class Sabre_CalDAV_Backend_Private extends Sabre_CalDAV_Backend_Common
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var null|Sabre_CalDAV_Backend_Private
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return Sabre_CalDAV_Backend_Private
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance == null) {
|
||||
self::$instance = new Sabre_CalDAV_Backend_Private();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return CALDAV_NAMESPACE_PRIVATE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @obsolete
|
||||
* @param array $calendar
|
||||
* @param int $user
|
||||
* @return array
|
||||
*/
|
||||
public function getPermissionsCalendar($calendar, $user)
|
||||
{
|
||||
if ($calendar["namespace"] == CALDAV_NAMESPACE_PRIVATE && $user == $calendar["namespace_id"]) return array("read"=> true, "write"=> true);
|
||||
return array("read"=> false, "write"=> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @obsolete
|
||||
* @param array $calendar
|
||||
* @param int $user
|
||||
* @param string $calendarobject_id
|
||||
* @param null|array $item_arr
|
||||
* @return array
|
||||
*/
|
||||
public function getPermissionsItem($calendar, $user, $calendarobject_id, $item_arr = null)
|
||||
{
|
||||
return $this->getPermissionsCalendar($calendar, $user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
* @param array $calendar
|
||||
* @param string $base_path
|
||||
* @return array
|
||||
*/
|
||||
private function jqcal2wdcal($row, $calendar, $base_path)
|
||||
{
|
||||
$not = q("SELECT COUNT(*) num FROM %s%snotifications WHERE `calendar_id` = %d AND `calendarobject_id` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($row["calendar_id"]), IntVal($row["calendarobject_id"])
|
||||
);
|
||||
$editable = $this->getPermissionsItem($calendar["namespace_id"], $row["calendarobject_id"], $row);
|
||||
|
||||
$end = wdcal_mySql2PhpTime($row["EndTime"]);
|
||||
if ($row["IsAllDayEvent"]) $end -= 1;
|
||||
|
||||
return array(
|
||||
"jq_id" => $row["id"],
|
||||
"ev_id" => $row["calendarobject_id"],
|
||||
"summary" => escape_tags($row["Summary"]),
|
||||
"start" => wdcal_mySql2PhpTime($row["StartTime"]),
|
||||
"end" => $end,
|
||||
"is_allday" => $row["IsAllDayEvent"],
|
||||
"is_moredays" => 0,
|
||||
"is_recurring" => $row["IsRecurring"],
|
||||
"color" => (is_null($row["Color"]) || $row["Color"] == "" ? $calendar["calendarcolor"] : $row["Color"]),
|
||||
"is_editable" => ($editable ? 1 : 0),
|
||||
"is_editable_quick" => ($editable && !$row["IsRecurring"] ? 1 : 0),
|
||||
"location" => "Loc.",
|
||||
"attendees" => '',
|
||||
"has_notification" => ($not[0]["num"] > 0 ? 1 : 0),
|
||||
"url_detail" => $base_path . $row["calendarobject_id"] . "/",
|
||||
"url_edit" => $base_path . $row["calendarobject_id"] . "/edit/",
|
||||
"special_type" => "",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $calendarId
|
||||
* @param string $sd
|
||||
* @param string $ed
|
||||
* @param string $base_path
|
||||
* @return array
|
||||
*/
|
||||
public function listItemsByRange($calendarId, $sd, $ed, $base_path)
|
||||
{
|
||||
$calendar = Sabre_CalDAV_Backend_Common::loadCalendarById($calendarId);
|
||||
$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 `calendar_id` = %d AND `starttime` between '%s' and '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX,
|
||||
IntVal($calendarId), dbesc($von), dbesc($bis));
|
||||
|
||||
$events = array();
|
||||
foreach ($evs as $row) $events[] = $this->jqcal2wdcal($row, $calendar, $base_path . $row["calendar_id"] . "/");
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $calendar_id
|
||||
* @param int $calendarobject_id
|
||||
* @return string
|
||||
*/
|
||||
public function getItemDetailRedirect($calendar_id, $calendarobject_id)
|
||||
{
|
||||
return "/dav/wdcal/$calendar_id/$calendarobject_id/edit/";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$n = dav_compat_principal2namespace($principalUri);
|
||||
if ($n["namespace"] != $this->getNamespace()) return array();
|
||||
|
||||
$cals = q("SELECT * FROM %s%scalendars WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $this->getNamespace(), IntVal($n["namespace_id"]));
|
||||
$ret = array();
|
||||
foreach ($cals as $cal) {
|
||||
if (in_array($cal["uri"], $GLOBALS["CALDAV_PRIVATE_SYSTEM_CALENDARS"])) continue;
|
||||
|
||||
$dat = array(
|
||||
"id" => $cal["id"],
|
||||
"uri" => $cal["uri"],
|
||||
"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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws Sabre_DAV_Exception
|
||||
* @return string|void
|
||||
*/
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties)
|
||||
{
|
||||
|
||||
$uid = dav_compat_principal2uid($principalUri);
|
||||
|
||||
$r = q("SELECT * FROM %s%scalendars WHERE `namespace` = %d AND `namespace_id` = %d AND `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, CALDAV_NAMESPACE_PRIVATE, $uid, dbesc($calendarUri));
|
||||
if (count($r) > 0) throw new Sabre_DAV_Exception("A calendar with this URI already exists");
|
||||
|
||||
$keys = array("`namespace`", "`namespace_id`", "`ctag`", "`uri`");
|
||||
$vals = array(CALDAV_NAMESPACE_PRIVATE, IntVal($uid), 1, "'" . dbesc($calendarUri) . "'");
|
||||
|
||||
// Default value
|
||||
$sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
|
||||
$has_vevent = $has_vtodo = 1;
|
||||
if (isset($properties[$sccs])) {
|
||||
if (!($properties[$sccs] instanceof Sabre_CalDAV_Property_SupportedCalendarComponentSet)) {
|
||||
throw new Sabre_DAV_Exception('The ' . $sccs . ' property must be of type: Sabre_CalDAV_Property_SupportedCalendarComponentSet');
|
||||
}
|
||||
$v = $properties[$sccs]->getValue();
|
||||
$has_vevent = $has_vtodo = 0;
|
||||
foreach ($v as $w) {
|
||||
if (mb_strtolower($w) == "vevent") $has_vevent = 1;
|
||||
if (mb_strtolower($w) == "vtodo") $has_vtodo = 1;
|
||||
}
|
||||
}
|
||||
$keys[] = "`has_vevent`";
|
||||
$keys[] = "`has_vtodo`";
|
||||
$vals[] = $has_vevent;
|
||||
$vals[] = $has_vtodo;
|
||||
|
||||
foreach ($this->propertyMap as $xmlName=> $dbName) {
|
||||
if (isset($properties[$xmlName])) {
|
||||
$keys[] = "`$dbName`";
|
||||
$vals[] = "'" . dbesc($properties[$xmlName]) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
$sql = sprintf("INSERT INTO %s%scalendars (" . implode(', ', $keys) . ") VALUES (" . implode(', ', $vals) . ")", CALDAV_SQL_DB, CALDAV_SQL_PREFIX);
|
||||
|
||||
q($sql);
|
||||
|
||||
$x = q("SELECT id FROM %s%scalendars WHERE `namespace` = %d AND `namespace_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, CALDAV_NAMESPACE_PRIVATE, $uid, $calendarUri
|
||||
);
|
||||
return $x[0]["id"];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 string $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;
|
||||
|
||||
}
|
||||
|
||||
$sql = "`ctag` = `ctag` + 1";
|
||||
foreach ($newValues as $key=> $val) $sql .= ", `" . $key . "` = '" . dbesc($val) . "'";
|
||||
|
||||
$sql = sprintf("UPDATE %s%scalendars SET $sql WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
|
||||
q($sql);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a calendar and all it's objects
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCalendar($calendarId)
|
||||
{
|
||||
q("DELETE FROM %s%scalendarobjects WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
q("DELETE FROM %s%scalendars WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 mixed $calendarId
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObjects($calendarId)
|
||||
{
|
||||
$objs = q("SELECT * FROM %s%scalendarobjects WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
$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_NotFound
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$o = q("SELECT * FROM %s%scalendarobjects WHERE `calendar_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId), 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_NotFound($calendarId . " / " . $objectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* It is possible return an etag from this function, which will be used in
|
||||
* the response to this PUT request. Note that the ETag must be surrounded
|
||||
* by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return string|null
|
||||
*/
|
||||
function createCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
|
||||
$calendarData = icalendar_sanitize_string($calendarData);
|
||||
|
||||
$extraData = $this->getDenormalizedData($calendarData);
|
||||
|
||||
q("INSERT INTO %s%scalendarobjects (`calendar_id`, `uri`, `calendardata`, `lastmodified`, `componentType`, `firstOccurence`, `lastOccurence`, `etag`, `size`)
|
||||
VALUES (%d, '%s', '%s', NOW(), '%s', '%s', '%s', '%s', %d)",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId), dbesc($objectUri), addslashes($calendarData), dbesc($extraData['componentType']),
|
||||
dbesc(wdcal_php2MySqlTime($extraData['firstOccurence'])), dbesc(wdcal_php2MySqlTime($extraData['lastOccurence'])), dbesc($extraData["etag"]), IntVal($extraData["size"])
|
||||
);
|
||||
|
||||
$this->increaseCalendarCtag($calendarId);
|
||||
renderCalDavEntry_uri($objectUri);
|
||||
|
||||
return '"' . $extraData['etag'] . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* It is possible return an etag from this function, which will be used in
|
||||
* the response to this PUT request. Note that the ETag must be surrounded
|
||||
* by double-quotes.
|
||||
*
|
||||
* However, you should only really return this ETag if you don't mangle the
|
||||
* calendar-data. If the result of a subsequent GET to this object is not
|
||||
* the exact same as this request body, you should omit the ETag.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @return string|null
|
||||
*/
|
||||
function updateCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$calendarData = icalendar_sanitize_string($calendarData);
|
||||
|
||||
$extraData = $this->getDenormalizedData($calendarData);
|
||||
|
||||
q("UPDATE %s%scalendarobjects SET `calendardata` = '%s', `lastmodified` = NOW(), `etag` = '%s', `size` = %d, `componentType` = '%s', `firstOccurence` = '%s', `lastOccurence` = '%s'
|
||||
WHERE `calendar_id` = %d AND `uri` = '%s'",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($calendarData), dbesc($extraData["etag"]), IntVal($extraData["size"]), dbesc($extraData["componentType"]),
|
||||
dbesc(wdcal_php2MySqlTime($extraData["firstOccurence"])), dbesc(wdcal_php2MySqlTime($extraData["lastOccurence"])), IntVal($calendarId), dbesc($objectUri));
|
||||
|
||||
$this->increaseCalendarCtag($calendarId);
|
||||
renderCalDavEntry_uri($objectUri);
|
||||
|
||||
return '"' . $extraData['etag'] . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$r = q("SELECT `id` FROM %s%scalendarobjects WHERE `calendar_id` = %d AND `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId), dbesc($objectUri));
|
||||
if (count($r) == 0) throw new Sabre_DAV_Exception_NotFound();
|
||||
|
||||
q("DELETE FROM %s%scalendarobjects WHERE `calendar_id` = %d AND `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId), dbesc($objectUri));
|
||||
|
||||
$this->increaseCalendarCtag($calendarId);
|
||||
renderCalDavEntry_calobj_id($r[0]["id"]);
|
||||
}
|
||||
}
|
186
dav/common/dav_caldav_backend_virtual.inc.php
Normal file
186
dav/common/dav_caldav_backend_virtual.inc.php
Normal file
|
@ -0,0 +1,186 @@
|
|||
<?php
|
||||
|
||||
abstract class Sabre_CalDAV_Backend_Virtual extends Sabre_CalDAV_Backend_Common
|
||||
{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @param int $calendarId
|
||||
* @param string $uri
|
||||
* @return array
|
||||
*/
|
||||
/*
|
||||
abstract public function getItemsByUri($calendarId, $uri);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $uid
|
||||
* @param int $namespace
|
||||
*/
|
||||
static public function invalidateCache($uid = 0, $namespace = 0) {
|
||||
q("DELETE FROM %s%scal_virtual_object_sync WHERE `uid` = %d AND `namespace` = %d",
|
||||
CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($uid), IntVal($namespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @param int $calendarId
|
||||
*/
|
||||
static abstract protected function createCache_internal($calendarId);
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @param int $calendarId
|
||||
*/
|
||||
static protected function createCache($calendarId) {
|
||||
$calendarId = IntVal($calendarId);
|
||||
q("DELETE FROM %s%scal_virtual_object_cache WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calendarId);
|
||||
static::createCache_internal($calendarId);
|
||||
q("REPLACE INTO %s%scal_virtual_object_sync (`calendar_id`, `date`) VALUES (%d, NOW())", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calendarId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $calendarId
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObjects($calendarId)
|
||||
{
|
||||
$calendarId = IntVal($calendarId);
|
||||
$r = q("SELECT COUNT(*) n FROM %s%scal_virtual_object_sync WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calendarId);
|
||||
|
||||
if ($r[0]["n"] == 0) static::createCache($calendarId);
|
||||
|
||||
$r = q("SELECT * FROM %s%scal_virtual_object_cache WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $calendarId);
|
||||
|
||||
$ret = array();
|
||||
foreach ($r as $obj) {
|
||||
$ret[] = array(
|
||||
"id" => IntVal($obj["data_uri"]),
|
||||
"calendardata" => $obj["calendardata"],
|
||||
"uri" => $obj["data_uri"],
|
||||
"lastmodified" => $obj["date"],
|
||||
"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_NotFound
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$calendarId = IntVal($calendarId);
|
||||
$r = q("SELECT COUNT(*) n FROM %s%scal_virtual_object_sync WHERE `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($calendarId));
|
||||
|
||||
if ($r[0]["n"] == 0) static::createCache($calendarId);
|
||||
|
||||
$r = q("SELECT * FROM %s%scal_virtual_object_cache WHERE `data_uri` = '%s' AND `calendar_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($objectUri), IntVal($calendarId));
|
||||
if (count($r) == 0) throw new Sabre_DAV_Exception_NotFound();
|
||||
|
||||
$obj = $r[0];
|
||||
$ret = array(
|
||||
"id" => IntVal($obj["data_uri"]),
|
||||
"calendardata" => $obj["calendardata"],
|
||||
"uri" => $obj["data_uri"],
|
||||
"lastmodified" => $obj["date"],
|
||||
"calendarid" => $calendarId,
|
||||
"etag" => $obj["etag"],
|
||||
"size" => IntVal($obj["size"]),
|
||||
);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties)
|
||||
{
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a calendar and all it's objects
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCalendar($calendarId)
|
||||
{
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return null|string|void
|
||||
*/
|
||||
function createCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return null|string|void
|
||||
*/
|
||||
function updateCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @throws Sabre_DAV_Exception_Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
throw new Sabre_DAV_Exception_Forbidden();
|
||||
}
|
||||
|
||||
|
||||
}
|
44
dav/common/dav_caldav_calendar_virtual.inc.php
Normal file
44
dav/common/dav_caldav_calendar_virtual.inc.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
class Sabre_CalDAV_Calendar_Virtual extends Sabre_CalDAV_Calendar {
|
||||
|
||||
/**
|
||||
* 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->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -14,6 +14,23 @@
|
|||
class Sabre_CardDAV_Backend_Std extends Sabre_CardDAV_Backend_Abstract
|
||||
{
|
||||
|
||||
/**
|
||||
* @var null|Sabre_CardDAV_Backend_Std
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return Sabre_CardDAV_Backend_Std
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if (self::$instance == null) {
|
||||
self::$instance = new Sabre_CardDAV_Backend_Std();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets up the object
|
||||
*/
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
<?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 {
|
||||
|
||||
/**
|
||||
|
@ -21,7 +13,7 @@ class Sabre_CalDAV_AnimexxUserCalendars implements Sabre_DAV_IExtendedCollection
|
|||
/**
|
||||
* CalDAV backends
|
||||
*
|
||||
* @var array|Sabre_CalDAV_Backend_Abstract[]
|
||||
* @var array|Sabre_CalDAV_Backend_Common[]
|
||||
*/
|
||||
protected $caldavBackends;
|
||||
|
||||
|
@ -36,7 +28,7 @@ class Sabre_CalDAV_AnimexxUserCalendars implements Sabre_DAV_IExtendedCollection
|
|||
* Constructor
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param array|Sabre_CalDAV_Backend_Abstract $caldavBackends
|
||||
* @param array|Sabre_CalDAV_Backend_Common[] $caldavBackends
|
||||
* @param mixed $userUri
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $caldavBackends, $userUri) {
|
||||
|
@ -130,7 +122,7 @@ class Sabre_CalDAV_AnimexxUserCalendars implements Sabre_DAV_IExtendedCollection
|
|||
* Returns a single calendar, by name
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_FileNotFound
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
* @todo needs optimizing
|
||||
* @return \Sabre_CalDAV_Calendar|\Sabre_DAV_INode
|
||||
*/
|
||||
|
@ -141,7 +133,7 @@ class Sabre_CalDAV_AnimexxUserCalendars implements Sabre_DAV_IExtendedCollection
|
|||
return $child;
|
||||
|
||||
}
|
||||
throw new Sabre_DAV_Exception_FileNotFound('Calendar with name \'' . $name . '\' could not be found');
|
||||
throw new Sabre_DAV_Exception_NotFound('Calendar with name \'' . $name . '\' could not be found');
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,16 +16,19 @@ function wdcal_edit_getStartEnd() {
|
|||
|
||||
function wdcal_edit_checktime_startChanged() {
|
||||
"use strict";
|
||||
|
||||
var time = wdcal_edit_getStartEnd();
|
||||
if (time.start.getTime() >= time.end.getTime()) {
|
||||
var newend = new Date(time.start.getTime() + 3600000);
|
||||
$("#cal_end_date").datepicker("setDate", newend);
|
||||
$.timePicker("#cal_end_time").setTime(newend);
|
||||
}
|
||||
wdcal_edit_recur_recalc();
|
||||
}
|
||||
|
||||
function wdcal_edit_checktime_endChanged() {
|
||||
"use strict";
|
||||
|
||||
var time = wdcal_edit_getStartEnd();
|
||||
if (time.start.getTime() >= time.end.getTime()) {
|
||||
var newstart = new Date(time.end.getTime() - 3600000);
|
||||
|
@ -34,7 +37,27 @@ function wdcal_edit_checktime_endChanged() {
|
|||
}
|
||||
}
|
||||
|
||||
function wdcal_edit_init(dateFormat) {
|
||||
function wdcal_edit_recur_recalc() {
|
||||
"use strict";
|
||||
|
||||
var start = $("#cal_start_date").datepicker("getDate");
|
||||
$(".rec_month_name").text($.datepicker._defaults.monthNames[start.getMonth()]);
|
||||
$("#rec_yearly_day option[value=bymonthday], #rec_monthly_day option[value=bymonthday]").text($("#rec_yearly_day option[value=bymonthday]").data("orig").replace("#num#", start.getDate()));
|
||||
var month = new Date(start.getFullYear(), start.getMonth() + 1, 0);
|
||||
var monthlast = month.getDate() - start.getDate() + 1;
|
||||
$("#rec_yearly_day option[value=bymonthday_neg], #rec_monthly_day option[value=bymonthday_neg]").text($("#rec_yearly_day option[value=bymonthday_neg]").data("orig").replace("#num#", monthlast));
|
||||
var wk = Math.ceil(start.getDate() / 7);
|
||||
var wkname = $.datepicker._defaults.dayNames[start.getDay()];
|
||||
$("#rec_yearly_day option[value=byday], #rec_monthly_day option[value=byday]").text(
|
||||
$("#rec_yearly_day option[value=byday]").data("orig").replace("#num#", wk).replace("#wkday#", wkname)
|
||||
);
|
||||
var wk_inv = Math.ceil(monthlast / 7);
|
||||
$("#rec_yearly_day option[value=byday_neg], #rec_monthly_day option[value=byday_neg]").text(
|
||||
$("#rec_yearly_day option[value=byday_neg]").data("orig").replace("#num#", wk_inv).replace("#wkday#", wkname)
|
||||
);
|
||||
}
|
||||
|
||||
function wdcal_edit_init(dateFormat, base_path) {
|
||||
"use strict";
|
||||
|
||||
$("#cal_color").colorPicker();
|
||||
|
@ -49,6 +72,8 @@ function wdcal_edit_init(dateFormat) {
|
|||
"dateFormat": dateFormat
|
||||
}).on("change", wdcal_edit_checktime_endChanged);
|
||||
|
||||
$("#rec_until_date").datepicker({ "dateFormat": dateFormat });
|
||||
|
||||
$("#notification").on("click change", function() {
|
||||
if ($(this).prop("checked")) $("#notification_detail").show();
|
||||
else ($("#notification_detail")).hide();
|
||||
|
@ -58,4 +83,111 @@ function wdcal_edit_init(dateFormat) {
|
|||
if ($(this).prop("checked")) $("#cal_end_time, #cal_start_time").hide();
|
||||
else $("#cal_end_time, #cal_start_time").show();
|
||||
}).change();
|
||||
|
||||
$("#rec_frequency").on("click change", function() {
|
||||
var val = $("#rec_frequency").val();
|
||||
if (val == "") $("#rec_details").hide();
|
||||
else $("#rec_details").show();
|
||||
|
||||
if (val == "daily") $(".rec_daily").show();
|
||||
else $(".rec_daily").hide();
|
||||
|
||||
if (val == "weekly") $(".rec_weekly").show();
|
||||
else $(".rec_weekly").hide();
|
||||
|
||||
if (val == "monthly") $(".rec_monthly").show();
|
||||
else $(".rec_monthly").hide();
|
||||
|
||||
if (val == "yearly") $(".rec_yearly").show();
|
||||
else $(".rec_yearly").hide();
|
||||
}).change();
|
||||
|
||||
$("#rec_until_type").on("click change", function() {
|
||||
var val = $("#rec_until_type").val();
|
||||
|
||||
if (val == "count") $("#rec_until_count").show();
|
||||
else $("#rec_until_count").hide();
|
||||
|
||||
if (val == "date") $("#rec_until_date").show();
|
||||
else $("#rec_until_date").hide();
|
||||
}).change();
|
||||
|
||||
$("#rec_yearly_day option, #rec_monthly_day option").each(function() {
|
||||
$(this).data("orig", $(this).text());
|
||||
});
|
||||
|
||||
wdcal_edit_recur_recalc();
|
||||
|
||||
$(document).on("click", ".exception_remover", function(ev) {
|
||||
ev.preventDefault();
|
||||
var $this = $(this),
|
||||
$par = $this.parents(".rec_exceptions");
|
||||
$this.parents(".except").remove();
|
||||
if ($par.find(".rec_exceptions_holder").children().length == 0) {
|
||||
$par.find(".rec_exceptions_holder").hide();
|
||||
$par.find(".rec_exceptions_none").show();
|
||||
}
|
||||
});
|
||||
|
||||
$(".exception_adder").click(function(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
var exceptions = [];
|
||||
$(".rec_exceptions .except input").each(function() {
|
||||
exceptions.push($(this).val());
|
||||
});
|
||||
var rec_weekly_byday = [];
|
||||
$(".rec_weekly_byday:checked").each(function() {
|
||||
rec_weekly_byday.push($(this).val());
|
||||
});
|
||||
var rec_daily_byday = [];
|
||||
$(".rec_daily_byday:checked").each(function() {
|
||||
rec_daily_byday.push($(this).val());
|
||||
});
|
||||
var opts = {
|
||||
"start_date": $("input[name=start_date]").val(),
|
||||
"start_time": $("input[name=start_time]").val(),
|
||||
"end_date": $("input[name=end_date]").val(),
|
||||
"end_time": $("input[name=end_time]").val(),
|
||||
"rec_frequency": $("#rec_frequency").val(),
|
||||
"rec_interval": $("#rec_interval").val(),
|
||||
"rec_until_type": $("#rec_until_type").val(),
|
||||
"rec_until_count": $("#rec_until_count").val(),
|
||||
"rec_until_date": $("#rec_until_date").val(),
|
||||
"rec_weekly_byday": rec_weekly_byday,
|
||||
"rec_daily_byday": rec_daily_byday,
|
||||
"rec_weekly_wkst": $("input[name=rec_weekly_wkst]:checked").val(),
|
||||
"rec_monthly_day": $("#rec_monthly_day").val(),
|
||||
"rec_yearly_day": $("#rec_yearly_day").val(),
|
||||
"rec_exceptions": exceptions
|
||||
};
|
||||
if ($("#cal_allday").prop("checked")) opts["allday"] = 1;
|
||||
var $dial = $("<div id='exception_setter_dialog'>Loading...</div>");
|
||||
$dial.appendTo("body");
|
||||
$dial.dialog({
|
||||
"width": 400,
|
||||
"height": 300,
|
||||
"title": "Exceptions"
|
||||
});
|
||||
$dial.load(base_path + "getExceptionDates/", opts, function() {
|
||||
$dial.find(".exception_selector_link").click(function(ev2) {
|
||||
ev2.preventDefault();
|
||||
var ts = $(this).data("timestamp");
|
||||
var str = $(this).html();
|
||||
var $part = $("<div data-timestamp='" + ts + "' class='except'><input type='hidden' class='rec_exception' name='rec_exceptions[]' value='" + ts + "'><a href='#' class='exception_remover'>[remove]</a> " + str + "</div>");
|
||||
var found = false;
|
||||
$(".rec_exceptions_holder .except").each(function() {
|
||||
if (!found && ts < $(this).data("timestamp")) {
|
||||
found = true;
|
||||
$part.insertBefore(this);
|
||||
}
|
||||
});
|
||||
if (!found) $(".rec_exceptions_holder").append($part);
|
||||
$(".rec_exceptions .rec_exceptions_holder").show();
|
||||
$(".rec_exceptions .rec_exceptions_none").hide();
|
||||
|
||||
$dial.dialog("destroy").remove();
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
|
@ -5,8 +5,10 @@
|
|||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var __WDAY = new Array(i18n.xgcalendar.dateformat.sun, i18n.xgcalendar.dateformat.mon, i18n.xgcalendar.dateformat.tue, i18n.xgcalendar.dateformat.wed, i18n.xgcalendar.dateformat.thu, i18n.xgcalendar.dateformat.fri, i18n.xgcalendar.dateformat.sat);
|
||||
var __MonthName = new Array(i18n.xgcalendar.dateformat.jan, i18n.xgcalendar.dateformat.feb, i18n.xgcalendar.dateformat.mar, i18n.xgcalendar.dateformat.apr, i18n.xgcalendar.dateformat.may, i18n.xgcalendar.dateformat.jun, i18n.xgcalendar.dateformat.jul, i18n.xgcalendar.dateformat.aug, i18n.xgcalendar.dateformat.sep, i18n.xgcalendar.dateformat.oct, i18n.xgcalendar.dateformat.nov, i18n.xgcalendar.dateformat.dec);
|
||||
var __WDAY = $.datepicker._defaults.dayNamesShort;
|
||||
//new Array(i18n.xgcalendar.dateformat.sun, i18n.xgcalendar.dateformat.mon, i18n.xgcalendar.dateformat.tue, i18n.xgcalendar.dateformat.wed, i18n.xgcalendar.dateformat.thu, i18n.xgcalendar.dateformat.fri, i18n.xgcalendar.dateformat.sat);
|
||||
var __MonthName = $.datepicker._defaults.monthNamesShort;
|
||||
//new Array(i18n.xgcalendar.dateformat.jan, i18n.xgcalendar.dateformat.feb, i18n.xgcalendar.dateformat.mar, i18n.xgcalendar.dateformat.apr, i18n.xgcalendar.dateformat.may, i18n.xgcalendar.dateformat.jun, i18n.xgcalendar.dateformat.jul, i18n.xgcalendar.dateformat.aug, i18n.xgcalendar.dateformat.sep, i18n.xgcalendar.dateformat.oct, i18n.xgcalendar.dateformat.nov, i18n.xgcalendar.dateformat.dec);
|
||||
|
||||
|
||||
function dateFormat(format) {
|
||||
|
@ -769,8 +771,8 @@
|
|||
for (i = 0; i < l; i++) {
|
||||
var $col = $container.find(".tgCol" + i);
|
||||
for (var j = 0; j < events[i].length; j++) {
|
||||
if (events[i][j].event["color"] && events[i][j].event["color"].match(/^#[0-9a-f]{6}$/i)) {
|
||||
c = events[i][j].event["color"];
|
||||
if (events[i][j].event["color"] && events[i][j].event["color"].match(/^[0-9a-f]{6}$/i)) {
|
||||
c = "#" + events[i][j].event["color"];
|
||||
}
|
||||
else {
|
||||
c = option.std_color;
|
||||
|
@ -787,7 +789,7 @@
|
|||
function getTitle(event) {
|
||||
var timeshow, eventshow;
|
||||
var showtime = event["is_allday"] != 1;
|
||||
eventshow = event["subject"];
|
||||
eventshow = event["summary"];
|
||||
var startformat = getymformat(event["start"], null, showtime, true);
|
||||
var endformat = getymformat(event["end"], event["start"], showtime, true);
|
||||
timeshow = dateFormat.call(event["start"], startformat) + " - " + dateFormat.call(event["end"], endformat);
|
||||
|
@ -819,7 +821,7 @@
|
|||
var p = { bdcolor:theme[0], bgcolor2:theme[0], bgcolor1:theme[2], width:"70%", icon:"", title:"", data:"" };
|
||||
p.starttime = pZero(e.st.hour) + ":" + pZero(e.st.minute);
|
||||
p.endtime = pZero(e.et.hour) + ":" + pZero(e.et.minute);
|
||||
p.content = e.event["subject"];
|
||||
p.content = e.event["summary"];
|
||||
p.title = getTitle(e.event);
|
||||
var icons = [];
|
||||
if (e.event["has_notification"] == 1) icons.push("<I class=\"cic cic-tmr\"> </I>");
|
||||
|
@ -1146,12 +1148,12 @@
|
|||
var p = { color:theme[2], title:"", extendClass:"", extendHTML:"", data:"" };
|
||||
|
||||
p.title = getTitle(e.event);
|
||||
p.id = "bbit_cal_event_" + e.event["uri"];
|
||||
p.id = "bbit_cal_event_" + e.event["jq_id"];
|
||||
if (option.enableDrag && e.event["is_editable_quick"] == 1) {
|
||||
p.eclass = "drag";
|
||||
}
|
||||
else {
|
||||
p.eclass = "cal_" + e.event["uri"];
|
||||
p.eclass = "cal_" + e.event["jq_id"];
|
||||
}
|
||||
p.eclass += " " + (e.event["is_editable"] ? "editable" : "not_editable");
|
||||
var sp = "<span style=\"cursor: pointer\">{content}</span>";
|
||||
|
@ -1175,10 +1177,10 @@
|
|||
}
|
||||
var cen;
|
||||
if (!e.allday && !sf) {
|
||||
cen = pZero(e.st.hour) + ":" + pZero(e.st.minute) + " " + e.event["subject"];
|
||||
cen = pZero(e.st.hour) + ":" + pZero(e.st.minute) + " " + e.event["summary"];
|
||||
}
|
||||
else {
|
||||
cen = e.event["subject"];
|
||||
cen = e.event["summary"];
|
||||
}
|
||||
var content = [];
|
||||
if (cen.indexOf("Geburtstag:") == 0) {
|
||||
|
@ -1294,7 +1296,7 @@
|
|||
}
|
||||
if (option.eventItems[i]["start"] >= es) {
|
||||
for (var j = 0; j < jl; j++) {
|
||||
if (option.eventItems[i]["uri"] == events[j]["uri"] && option.eventItems[i]["start"] < start) {
|
||||
if (option.eventItems[i]["jq_id"] == events[j]["jq_id"] && option.eventItems[i]["start"] < start) {
|
||||
events.splice(j, 1); //for duplicated event
|
||||
jl--;
|
||||
break;
|
||||
|
@ -1477,7 +1479,7 @@
|
|||
$("#bbit-cs-buddle").css("visibility", "hidden");
|
||||
var calid = $("#bbit-cs-id").val();
|
||||
var param = [
|
||||
{ "name":"calendarId", value:calid },
|
||||
{ "name":"jq_id", value:calid },
|
||||
{ "name":"type", value:type}
|
||||
];
|
||||
var de = rebyKey(calid, true);
|
||||
|
@ -1609,8 +1611,8 @@
|
|||
var location = "";
|
||||
if (data["location"] != "") location = data["location"] + ", ";
|
||||
$("#bbit-cs-buddle-timeshow").html(location + ss.join(""));
|
||||
$bud.find(".bbit-cs-what").html(data["subject"]).attr("href", data["url_detail"]);
|
||||
$("#bbit-cs-id").val(data["uri"]);
|
||||
$bud.find(".bbit-cs-what").html(data["summary"]).attr("href", data["url_detail"]);
|
||||
$("#bbit-cs-id").val(data["jq_id"]);
|
||||
$bud.data("cdata", data);
|
||||
$bud.css({ "visibility":"visible", left:pos.left, top:pos.top });
|
||||
|
||||
|
@ -1684,11 +1686,11 @@
|
|||
return false;
|
||||
}
|
||||
option.isloading = true;
|
||||
var id = data["uri"];
|
||||
var id = data["jq_id"];
|
||||
var os = data["start"];
|
||||
var od = data["end"];
|
||||
var param = [
|
||||
{ "name":"calendarId", value:id },
|
||||
{ "name":"jq_id", value:id },
|
||||
{ "name":"CalendarStartTime", value:Math.floor(start.getTime() / 1000) },
|
||||
{ "name":"CalendarEndTime", value:Math.floor(end.getTime() / 1000) }
|
||||
];
|
||||
|
@ -1744,7 +1746,7 @@
|
|||
temparr.push('<table class="cb-table"><tbody><tr><th class="cb-key">');
|
||||
temparr.push(i18n.xgcalendar.time, ':</th><td class=cb-value><div id="bbit-cal-buddle-timeshow"></div></td></tr><tr><th class="cb-key">');
|
||||
temparr.push(i18n.xgcalendar.content, ':</th><td class="cb-value"><div class="textbox-fill-wrapper"><div class="textbox-fill-mid"><input id="bbit-cal-what" class="textbox-fill-input"/></div></div><div class="cb-example">');
|
||||
temparr.push(i18n.xgcalendar.example, '</div></td></tr></tbody></table><input id="bbit-cal-start" type="hidden"/><input id="bbit-cal-end" type="hidden"/><input id="bbit-cal-allday" type="hidden"/><input id="bbit-cal-quickAddBTN" value="');
|
||||
temparr.push(i18n.xgcalendar.example, '</div></td></tr></tbody></table><input id="bbit-cal-start" type="hidden"/><input id="bbit-cal-end" type="hidden"/><input id="bbit-cal-allday" type="hidden"/><input value="');
|
||||
temparr.push(i18n.xgcalendar.create_event, '" type="submit"/> <a href="" class="lk bbit-cal-editLink">');
|
||||
temparr.push(i18n.xgcalendar.update_detail, ' <StrONG>>></StrONG></SPAN></div></div></div><tr><td><div id="bl1" class="bubble-corner"><div class="bubble-sprite bubble-bl"></div></div><td><div class="bubble-bottom"></div><td><div id="br1" class="bubble-corner"><div class="bubble-sprite bubble-br"></div></div></tr></tbody></table><div id="bubbleClose1" class="bubble-closebutton"></div><div id="prong2" class="prong"><div class=bubble-sprite></div></div></div>');
|
||||
temparr.push('</form>');
|
||||
|
@ -1789,7 +1791,6 @@
|
|||
param[param.length] = option.extParam[pi];
|
||||
}
|
||||
}
|
||||
|
||||
if (option.quickAddHandler && $.isFunction(option.quickAddHandler)) {
|
||||
option.quickAddHandler.call(this, param);
|
||||
$("#bbit-cal-buddle").css("visibility", "hidden");
|
||||
|
@ -1804,8 +1805,9 @@
|
|||
ed = new Date(dateend),
|
||||
diff = DateDiff("d", sd, ed);
|
||||
var newdata = {
|
||||
"uri":"",
|
||||
"subject":what,
|
||||
"jq_id":"",
|
||||
"ev_id":"",
|
||||
"summary":what,
|
||||
"start":sd,
|
||||
"end":ed,
|
||||
"is_allday":(allday == "1" ? 1 : 0),
|
||||
|
@ -1886,7 +1888,7 @@
|
|||
var sl = option.eventItems.length;
|
||||
var i = -1;
|
||||
for (var j = 0; j < sl; j++) {
|
||||
if (option.eventItems[j]["uri"] == key) {
|
||||
if (option.eventItems[j]["jq_id"] == key) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
|
@ -2352,7 +2354,7 @@
|
|||
d.target.hide();
|
||||
ny = gP(gh.sh, gh.sm);
|
||||
d.top = ny;
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["subject"], false, false, data["color"]);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["summary"], false, false, data["color"]);
|
||||
cpwrap = $("<div class='ca-evpi drag-chip-wrapper' style='top:" + ny + "px'/>").html(tempdata);
|
||||
evid = ".tgOver" + d.target.parent().data("col");
|
||||
$gridcontainer.find(evid).append(cpwrap);
|
||||
|
@ -2389,7 +2391,7 @@
|
|||
//log.info("ny=" + ny);
|
||||
gh = gW(ny, ny + d.h);
|
||||
//log.info("sh=" + gh.sh + ",sm=" + gh.sm);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["subject"], false, false, data["color"]);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["summary"], false, false, data["color"]);
|
||||
d.cpwrap.css("top", ny + "px").html(tempdata);
|
||||
}
|
||||
d.ny = ny;
|
||||
|
@ -2415,7 +2417,7 @@
|
|||
d.target.hide();
|
||||
ny = gP(gh.sh, gh.sm);
|
||||
d.top = ny;
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["subject"], "100%", true, data["color"]);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["summary"], "100%", true, data["color"]);
|
||||
cpwrap = $("<div class='ca-evpi drag-chip-wrapper' style='top:" + ny + "px'/>").html(tempdata);
|
||||
evid = ".tgOver" + d.target.parent().data("col");
|
||||
$gridcontainer.find(evid).append(cpwrap);
|
||||
|
@ -2427,7 +2429,7 @@
|
|||
nh = pnh > 1 ? nh - pnh + Math.ceil(option.hour_height / 2) : nh - pnh;
|
||||
if (d.nh != nh) {
|
||||
gh = gW(d.top, d.top + nh);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["subject"], "100%", true, data["color"]);
|
||||
tempdata = buildtempdayevent(gh.sh, gh.sm, gh.eh, gh.em, gh.h, data["summary"], "100%", true, data["color"]);
|
||||
d.cpwrap.html(tempdata);
|
||||
}
|
||||
d.nh = nh;
|
||||
|
|
|
@ -7,26 +7,7 @@ var i18n = $.extend({}, i18n || {}, {
|
|||
"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"
|
||||
"day": "d"
|
||||
},
|
||||
"no_implemented": "Nicht eingebaut",
|
||||
"to_date_view": "Zum aktuellen Datum gehen",
|
||||
|
|
|
@ -7,26 +7,7 @@ var i18n = $.extend({}, i18n || {}, {
|
|||
"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"
|
||||
"day": "d"
|
||||
},
|
||||
"no_implemented": "Not implemented",
|
||||
"to_date_view": "Go to today",
|
||||
|
|
238
dav/common/wdcal_backend.inc.php
Normal file
238
dav/common/wdcal_backend.inc.php
Normal file
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param string $right
|
||||
* @return null|Sabre_CalDAV_Calendar
|
||||
*/
|
||||
function wdcal_print_feed_getCal(&$server, $right)
|
||||
{
|
||||
$cals = dav_get_current_user_calendars($server, $right);
|
||||
$calfound = null;
|
||||
for ($i = 0; $i < count($cals) && $calfound === null; $i++) {
|
||||
$prop = $cals[$i]->getProperties(array("id"));
|
||||
if (isset($prop["id"]) && (!isset($_REQUEST["cal"]) || in_array($prop["id"], $_REQUEST["cal"]))) $calfound = $cals[$i];
|
||||
}
|
||||
return $calfound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function wdcal_print_feed($base_path = "")
|
||||
{
|
||||
$server = dav_create_server(true, true, false);
|
||||
|
||||
$ret = null;
|
||||
|
||||
$method = $_GET["method"];
|
||||
switch ($method) {
|
||||
case "add":
|
||||
$cs = wdcal_print_feed_getCal($server, DAV_ACL_WRITE);
|
||||
if ($cs == null) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
try {
|
||||
$item = dav_create_empty_vevent();
|
||||
$component = dav_get_eventComponent($item);
|
||||
$component->add("SUMMARY", icalendar_sanitize_string(dav_compat_parse_text_serverside("CalendarTitle")));
|
||||
|
||||
if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE;
|
||||
else $type = Sabre_VObject_Property_DateTime::LOCALTZ;
|
||||
|
||||
$datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
|
||||
$datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type);
|
||||
$datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
|
||||
$datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type);
|
||||
|
||||
$component->add($datetime_start);
|
||||
$component->add($datetime_end);
|
||||
|
||||
$uid = $component->__get("UID");
|
||||
$data = $item->serialize();
|
||||
|
||||
$cs->createFile($uid . ".ics", $data);
|
||||
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'add success',
|
||||
'Data' => $uid . ".ics",
|
||||
);
|
||||
|
||||
} 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;
|
||||
|
||||
$cals = dav_get_current_user_calendars($server, DAV_ACL_READ);
|
||||
foreach ($cals as $cal) {
|
||||
$prop = $cal->getProperties(array("id"));
|
||||
if (isset($prop["id"]) && (!isset($_REQUEST["cal"]) || in_array($prop["id"], $_REQUEST["cal"]))) {
|
||||
$backend = wdcal_calendar_factory_by_id($prop["id"]);
|
||||
$events = $backend->listItemsByRange($prop["id"], $date[0], $date[1], $base_path);
|
||||
$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":
|
||||
$r = q("SELECT `calendarobject_id`, `calendar_id` FROM %s%sjqcalendar WHERE `id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($_REQUEST["jq_id"]));
|
||||
if (count($r) != 1) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
try {
|
||||
$cs = dav_get_current_user_calendar_by_id($server, $r[0]["calendar_id"], DAV_ACL_READ);
|
||||
$obj_uri = Sabre_CalDAV_Backend_Common::loadCalendarobjectById($r[0]["calendarobject_id"]);
|
||||
|
||||
$vObject = dav_get_current_user_calendarobject($server, $cs, $obj_uri["uri"], DAV_ACL_WRITE);
|
||||
$component = dav_get_eventComponent($vObject);
|
||||
|
||||
if (!$component) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
|
||||
if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE;
|
||||
else $type = Sabre_VObject_Property_DateTime::LOCALTZ;
|
||||
|
||||
$datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
|
||||
$datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type);
|
||||
$datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
|
||||
$datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type);
|
||||
|
||||
$component->__unset("DTSTART");
|
||||
$component->__unset("DTEND");
|
||||
$component->add($datetime_start);
|
||||
$component->add($datetime_end);
|
||||
|
||||
$data = $vObject->serialize();
|
||||
/** @var Sabre_CalDAV_CalendarObject $child */
|
||||
$child = $cs->getChild($obj_uri["uri"]);
|
||||
$child->put($data);
|
||||
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'Succefully',
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
$r = q("SELECT `calendarobject_id`, `calendar_id` FROM %s%sjqcalendar WHERE `id`=%d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($_REQUEST["jq_id"]));
|
||||
if (count($r) != 1) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
try {
|
||||
$cs = dav_get_current_user_calendar_by_id($server, $r[0]["calendar_id"], DAV_ACL_WRITE);
|
||||
$obj_uri = Sabre_CalDAV_Backend_Common::loadCalendarobjectById($r[0]["calendarobject_id"]);
|
||||
$child = $cs->getChild($obj_uri["uri"]);
|
||||
$child->delete();
|
||||
|
||||
$ret = array(
|
||||
'IsSuccess' => true,
|
||||
'Msg' => 'Succefully',
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
echo wdcal_jsonp_encode(array('IsSuccess' => false,
|
||||
'Msg' => t('No access')));
|
||||
killme();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
echo wdcal_jsonp_encode($ret);
|
||||
killme();
|
||||
}
|
||||
|
|
@ -40,6 +40,13 @@ abstract class wdcal_local
|
|||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @abstract
|
||||
* @return string
|
||||
*/
|
||||
abstract static function getLanguageCode();
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @static
|
||||
|
@ -77,6 +84,13 @@ abstract class wdcal_local
|
|||
*/
|
||||
abstract function date_timestamp2local($ts);
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
abstract function date_timestamp2localDate($ts);
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return int
|
||||
|
@ -119,6 +133,14 @@ abstract class wdcal_local
|
|||
|
||||
class wdcal_local_us extends wdcal_local {
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
static function getLanguageCode() {
|
||||
return "en";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -152,6 +174,14 @@ class wdcal_local_us extends wdcal_local {
|
|||
return date("m/d/Y H:i", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function date_timestamp2localDate($ts) {
|
||||
return date("l, F jS Y", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
@ -198,6 +228,14 @@ class wdcal_local_us extends wdcal_local {
|
|||
|
||||
class wdcal_local_de extends wdcal_local {
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
static function getLanguageCode() {
|
||||
return "de";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -231,6 +269,14 @@ class wdcal_local_de extends wdcal_local {
|
|||
return date("d.m.Y H:i", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $ts
|
||||
* @return string
|
||||
*/
|
||||
function date_timestamp2localDate($ts) {
|
||||
return date("l, j. F Y", $ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
|
510
dav/common/wdcal_edit.inc.php
Normal file
510
dav/common/wdcal_edit.inc.php
Normal file
|
@ -0,0 +1,510 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @param wdcal_local $localization
|
||||
* @param string $baseurl
|
||||
* @param int $uid
|
||||
* @param int $calendar_id
|
||||
* @param int $uri
|
||||
* @param string $recurr_uri
|
||||
* @return string
|
||||
*/
|
||||
function wdcal_getEditPage_str(&$localization, $baseurl, $uid, $calendar_id, $uri, $recurr_uri = "")
|
||||
{
|
||||
$server = dav_create_server(true, true, false);
|
||||
|
||||
if ($uri > 0) {
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE);
|
||||
if (!$calendar) {
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_READ);
|
||||
$calendars = array();
|
||||
} else {
|
||||
$calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE);
|
||||
}
|
||||
|
||||
if ($calendar == null) return "Calendar not found";
|
||||
|
||||
$obj_uri = Sabre_CalDAV_Backend_Common::loadCalendarobjectById($uri);
|
||||
|
||||
$vObject = dav_get_current_user_calendarobject($server, $calendar, $obj_uri["uri"], DAV_ACL_WRITE);
|
||||
$component = dav_get_eventComponent($vObject);
|
||||
|
||||
if ($component == null) return t('Could not open component for editing');
|
||||
|
||||
/** @var Sabre_VObject_Property_DateTime $dtstart */
|
||||
$dtstart = $component->__get("DTSTART");
|
||||
$event = array(
|
||||
"id" => IntVal($uri),
|
||||
"Summary" => ($component->__get("SUMMARY") ? $component->__get("SUMMARY")->value : null),
|
||||
"StartTime" => $dtstart->getDateTime()->getTimeStamp(),
|
||||
"EndTime" => Sabre_CalDAV_Backend_Common::getDtEndTimeStamp($component),
|
||||
"IsAllDayEvent" => (strlen($dtstart->value) == 8),
|
||||
"Description" => ($component->__get("DESCRIPTION") ? $component->__get("DESCRIPTION")->value : null),
|
||||
"Location" => ($component->__get("LOCATION") ? $component->__get("LOCATION")->value : null),
|
||||
"Color" => ($component->__get("X-ANIMEXX-COLOR") ? $component->__get("X-ANIMEXX-COLOR")->value : null),
|
||||
);
|
||||
|
||||
$exdates = $component->select("EXDATE");
|
||||
$recurrentce_exdates = array();
|
||||
/** @var Sabre_VObject_Property_MultiDateTime $x */
|
||||
foreach ($exdates as $x) {
|
||||
/** @var DateTime $y */
|
||||
$z = $x->getDateTimes();
|
||||
foreach ($z as $y) $recurrentce_exdates[] = $y->getTimeStamp();
|
||||
}
|
||||
|
||||
if ($component->select("RRULE")) $recurrence = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
|
||||
else $recurrence = null;
|
||||
|
||||
} elseif (isset($_REQUEST["start"]) && $_REQUEST["start"] > 0) {
|
||||
$calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE);
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE);
|
||||
|
||||
$event = array(
|
||||
"id" => 0,
|
||||
"Summary" => $_REQUEST["title"],
|
||||
"StartTime" => InTVal($_REQUEST["start"]),
|
||||
"EndTime" => IntVal($_REQUEST["end"]),
|
||||
"IsAllDayEvent" => $_REQUEST["isallday"],
|
||||
"Description" => "",
|
||||
"Location" => "",
|
||||
"Color" => "#5858ff",
|
||||
);
|
||||
if ($_REQUEST["isallday"]) {
|
||||
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 24));
|
||||
} else {
|
||||
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 1));
|
||||
}
|
||||
$recurrence = null;
|
||||
$recurrentce_exdates = array();
|
||||
} else {
|
||||
$calendars = dav_get_current_user_calendars($server, DAV_ACL_WRITE);
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $calendar_id, DAV_ACL_WRITE);
|
||||
|
||||
$event = array(
|
||||
"id" => 0,
|
||||
"Summary" => "",
|
||||
"StartTime" => time(),
|
||||
"EndTime" => time() + 3600,
|
||||
"IsAllDayEvent" => "0",
|
||||
"Description" => "",
|
||||
"Location" => "",
|
||||
"Color" => "#5858ff",
|
||||
);
|
||||
$notifications = array(array("rel" => "start", "type" => "duration", "period" => "hour", "period_val" => 1));
|
||||
$recurrence = null;
|
||||
$recurrentce_exdates = array();
|
||||
}
|
||||
|
||||
$postto = $baseurl . "/dav/wdcal/" . ($uri == 0 ? "new/" : $calendar_id . "/" . $uri . "/edit/");
|
||||
|
||||
$out = "<a href='" . $baseurl . "/dav/wdcal/'>" . t("Go back to the calendar") . "</a><br><br>";
|
||||
$out .= "<form method='POST' action='$postto'>
|
||||
<input type='hidden' name='form_security_token' value='" . get_form_security_token('caledit') . "'>\n";
|
||||
|
||||
$out .= "<h2>" .t("Event data") . "</h2>";
|
||||
|
||||
$out .= "<label for='calendar'>" . t("Calendar") . ":</label><select name='calendar' size='1'>";
|
||||
foreach ($calendars as $cal) {
|
||||
$prop = $cal->getProperties(array("id", DAV_DISPLAYNAME));
|
||||
$out .= "<option value='" . $prop["id"] . "' ";
|
||||
if ($prop["id"] == $calendar_id) $out .= "selected";
|
||||
$out .= ">" . escape_tags($prop[DAV_DISPLAYNAME]) . "</option>\n";
|
||||
}
|
||||
$out .= "</select><br>\n";
|
||||
|
||||
$out .= "<label class='block' for='cal_summary'>" . t("Subject") . ":</label>
|
||||
<input name='color' id='cal_color' value='" . (strlen($event["Color"]) != 7 ? "#5858ff" : escape_tags($event["Color"])) . "'>
|
||||
<input name='summary' id='cal_summary' value='" . escape_tags($event["Summary"]) . "'><br>\n";
|
||||
$out .= "<label class='block' for='cal_allday'>Is All-Day event:</label><input type='checkbox' name='allday' id='cal_allday' " . ($event["IsAllDayEvent"] ? "checked" : "") . "><br>\n";
|
||||
|
||||
$out .= "<label class='block' for='cal_startdate'>" . t("Starts") . ":</label>";
|
||||
$out .= "<input name='start_date' value='" . $localization->dateformat_datepicker_php($event["StartTime"]) . "' id='cal_start_date'>";
|
||||
$out .= "<input name='start_time' value='" . date("H:i", $event["StartTime"]) . "' id='cal_start_time'>";
|
||||
$out .= "<br>\n";
|
||||
|
||||
$out .= "<label class='block' for='cal_enddate'>" . t("Ends") . ":</label>";
|
||||
$out .= "<input name='end_date' value='" . $localization->dateformat_datepicker_php($event["EndTime"]) . "' id='cal_end_date'>";
|
||||
$out .= "<input name='end_time' value='" . date("H:i", $event["EndTime"]) . "' id='cal_end_time'>";
|
||||
$out .= "<br>\n";
|
||||
|
||||
$out .= "<label class='block' for='cal_location'>" . t("Location") . ":</label><input name='location' id='cal_location' value='" . escape_tags($event["Location"]) . "'><br>\n";
|
||||
|
||||
$out .= "<label class='block' for='event-desc-textarea'>" . t("Description") . ":</label> <textarea id='event-desc-textarea' name='wdcal_desc' style='vertical-align: top; width: 400px; height: 100px;'>" . escape_tags($event["Description"]) . "</textarea>";
|
||||
$out .= "<br style='clear: both;'>";
|
||||
|
||||
$out .= "<h2>" .t("Recurrence") . "</h2>";
|
||||
|
||||
$out .= "<label class='block' for='rec_frequency'>" . t("Frequency") . ":</label> <select id='rec_frequency' name='rec_frequency' size='1'>";
|
||||
$out .= "<option value=''>" . t("None") . "</option>\n";
|
||||
$out .= "<option value='daily' "; if ($recurrence && $recurrence->frequency == "daily") $out .= "selected"; $out .= ">" . t("Daily") . "</option>\n";
|
||||
$out .= "<option value='weekly' "; if ($recurrence && $recurrence->frequency == "weekly") $out .= "selected"; $out .= ">" . t("Weekly") . "</option>\n";
|
||||
$out .= "<option value='monthly' "; if ($recurrence && $recurrence->frequency == "monthly") $out .= "selected"; $out .= ">" . t("Monthly") . "</option>\n";
|
||||
$out .= "<option value='yearly' "; if ($recurrence && $recurrence->frequency == "yearly") $out .= "selected"; $out .= ">" . t("Yearly") . "</option>\n";
|
||||
$out .="</select><br>\n";
|
||||
$out .= "<div id='rec_details'>";
|
||||
|
||||
$select = "<select id='rec_interval' name='rec_interval' size='1'>";
|
||||
for ($i = 1; $i < 50; $i++) {
|
||||
$select .= "<option value='$i' ";
|
||||
if ($recurrence && $i == $recurrence->interval) $select .= "selected";
|
||||
$select .= ">$i</option>\n";
|
||||
}
|
||||
$select .= "</select>";
|
||||
$time = "<span class='rec_daily'>" . t("days") . "</span>";
|
||||
$time .= "<span class='rec_weekly'>" . t("weeks") . "</span>";
|
||||
$time .= "<span class='rec_monthly'>" . t("months") . "</span>";
|
||||
$time .= "<span class='rec_yearly'>" . t("years") . "</span>";
|
||||
$out .= "<label class='block' for='rev_interval'>" . t("Interval") . ":</label> " . str_replace(array("%select%", "%time%"), array($select, $time), t("All %select% %time%")) . "<br>";
|
||||
|
||||
|
||||
$out .= "<div class='rec_daily'>";
|
||||
$out .= "<label class='block'>" . t("Days") . ":</label>";
|
||||
if ($recurrence && $recurrence->byDay) {
|
||||
$byday = $recurrence->byDay;
|
||||
} else {
|
||||
$byday = array("MO", "TU", "WE", "TH", "FR", "SA", "SU");
|
||||
}
|
||||
if ($localization->getFirstDayOfWeek() == 0) {
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='SU' "; if (in_array("SU", $byday)) $out .= "checked"; $out .= ">" . t("Sunday") . "</label> ";
|
||||
}
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='MO' "; if (in_array("MO", $byday)) $out .= "checked"; $out .= ">" . t("Monday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='TU' "; if (in_array("TU", $byday)) $out .= "checked"; $out .= ">" . t("Tuesday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='WE' "; if (in_array("WE", $byday)) $out .= "checked"; $out .= ">" . t("Wednesday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='TH' "; if (in_array("TH", $byday)) $out .= "checked"; $out .= ">" . t("Thursday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='FR' "; if (in_array("FR", $byday)) $out .= "checked"; $out .= ">" . t("Friday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='SA' "; if (in_array("SA", $byday)) $out .= "checked"; $out .= ">" . t("Saturday") . "</label> ";
|
||||
if ($localization->getFirstDayOfWeek() != 0) {
|
||||
$out .= "<label class='plain'><input class='rec_daily_byday' type='checkbox' name='rec_daily_byday[]' value='SU' "; if (in_array("SU", $byday)) $out .= "checked"; $out .= ">" . t("Sunday") . "</label> ";
|
||||
}
|
||||
$out .= "</div>";
|
||||
|
||||
|
||||
$out .= "<div class='rec_weekly'>";
|
||||
$out .= "<label class='block'>" . t("Days") . ":</label>";
|
||||
if ($recurrence && $recurrence->byDay) {
|
||||
$byday = $recurrence->byDay;
|
||||
} else {
|
||||
$byday = array("MO", "TU", "WE", "TH", "FR", "SA", "SU");
|
||||
}
|
||||
if ($localization->getFirstDayOfWeek() == 0) {
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='SU' "; if (in_array("SU", $byday)) $out .= "checked"; $out .= ">" . t("Sunday") . "</label> ";
|
||||
}
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='MO' "; if (in_array("MO", $byday)) $out .= "checked"; $out .= ">" . t("Monday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='TU' "; if (in_array("TU", $byday)) $out .= "checked"; $out .= ">" . t("Tuesday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='WE' "; if (in_array("WE", $byday)) $out .= "checked"; $out .= ">" . t("Wednesday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='TH' "; if (in_array("TH", $byday)) $out .= "checked"; $out .= ">" . t("Thursday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='FR' "; if (in_array("FR", $byday)) $out .= "checked"; $out .= ">" . t("Friday") . "</label> ";
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='SA' "; if (in_array("SA", $byday)) $out .= "checked"; $out .= ">" . t("Saturday") . "</label> ";
|
||||
if ($localization->getFirstDayOfWeek() != 0) {
|
||||
$out .= "<label class='plain'><input class='rec_weekly_byday' type='checkbox' name='rec_weekly_byday[]' value='SU' "; if (in_array("SU", $byday)) $out .= "checked"; $out .= ">" . t("Sunday") . "</label> ";
|
||||
}
|
||||
$out .= "<br>";
|
||||
|
||||
$out .= "<label class='block'>" . t("First day of week:") . "</label>";
|
||||
if ($recurrence && $recurrence->weekStart != "") $wkst = $recurrence->weekStart;
|
||||
else {
|
||||
if ($localization->getFirstDayOfWeek() == 0) $wkst = "SU";
|
||||
else $wkst = "MO";
|
||||
}
|
||||
$out .= "<label class='plain'><input type='radio' name='rec_weekly_wkst' value='SU' "; if ($wkst == "SU") $out .= "checked"; $out .= ">" . t("Sunday") . "</label> ";
|
||||
$out .= "<label class='plain'><input type='radio' name='rec_weekly_wkst' value='MO' "; if ($wkst == "MO") $out .= "checked"; $out .= ">" . t("Monday") . "</label><br>\n";
|
||||
|
||||
$out .= "</div>";
|
||||
|
||||
$monthly_rule = "bymonthday"; // @TODO
|
||||
$out .= "<div class='rec_monthly'>";
|
||||
$out .= "<label class='block' name='rec_monthly_day'>" . t("Day of month") . ":</label>";
|
||||
$out .= "<select id='rec_monthly_day' name='rec_monthly_day' size='1'>";
|
||||
$out .= "<option value='bymonthday' "; if ($monthly_rule == "bymonthday") $out .= "selected"; $out .= ">" . t("#num#th of each month") . "</option>\n";
|
||||
$out .= "<option value='bymonthday_neg' "; if ($monthly_rule == "bymonthday_neg") $out .= "selected"; $out .= ">" . t("#num#th-last of each month") . "</option>\n";
|
||||
$out .= "<option value='byday' "; if ($monthly_rule == "byday") $out .= "selected"; $out .= ">" . t("#num#th #wkday# of each month") . "</option>\n";
|
||||
$out .= "<option value='byday_neg' "; if ($monthly_rule == "byday_neg") $out .= "selected"; $out .= ">" . t("#num#th-last #wkday# of each month") . "</option>\n";
|
||||
$out .= "</select>";
|
||||
$out .= "</div>\n";
|
||||
|
||||
|
||||
$out .= "<div class='rec_yearly'>";
|
||||
$out .= "<label class='block' name='rec_yearly_day'>" . t("Month") . ":</label> <span class='rec_month_name'>#month#</span><br>\n";
|
||||
$out .= "<label class='block' name='rec_yearly_day'>" . t("Day of month") . ":</label>";
|
||||
$out .= "<select id='rec_yearly_day' name='rec_yearly_day' size='1'>";
|
||||
$out .= "<option value='bymonthday' "; if ($monthly_rule == "bymonthday") $out .= "selected"; $out .= ">" . t("#num#th of each month") . "</option>\n";
|
||||
$out .= "<option value='bymonthday_neg' "; if ($monthly_rule == "bymonthday_neg") $out .= "selected"; $out .= ">" . t("#num#th-last of each month") . "</option>\n";
|
||||
$out .= "<option value='byday' "; if ($monthly_rule == "byday") $out .= "selected"; $out .= ">" . t("#num#th #wkday# of each month") . "</option>\n";
|
||||
$out .= "<option value='byday_neg' "; if ($monthly_rule == "byday_neg") $out .= "selected"; $out .= ">" . t("#num#th-last #wkday# of each month") . "</option>\n";
|
||||
$out .= "</select>";
|
||||
$out .= "</div>\n";
|
||||
|
||||
|
||||
if ($recurrence) {
|
||||
$until = $recurrence->until;
|
||||
$count = $recurrence->count;
|
||||
if (is_a($until, "DateTime")) {
|
||||
/** @var DateTime $until */
|
||||
$rule_type = "date";
|
||||
$rule_until_date = $until->getTimestamp();
|
||||
$rule_until_count = 1;
|
||||
} elseif ($count > 0) {
|
||||
$rule_type = "count";
|
||||
$rule_until_date = time();
|
||||
$rule_until_count = $count;
|
||||
} else {
|
||||
$rule_type = "infinite";
|
||||
$rule_until_date = time();
|
||||
$rule_until_count = 1;
|
||||
}
|
||||
} else {
|
||||
$rule_type = "infinite";
|
||||
$rule_until_date = time();
|
||||
$rule_until_count = 1;
|
||||
}
|
||||
$out .= "<label class='block' for='rec_until_type'>" . t("Repeat until") . ":</label> ";
|
||||
$out .= "<select name='rec_until_type' id='rec_until_type' size='1'>";
|
||||
$out .= "<option value='infinite' "; if ($rule_type == "infinite") $out .= "selected"; $out .= ">" . t("Infinite") . "</option>\n";
|
||||
$out .= "<option value='date' "; if ($rule_type == "date") $out .= "selected"; $out .= ">" . t("Until the following date") . ":</option>\n";
|
||||
$out .= "<option value='count' "; if ($rule_type == "count") $out .= "selected"; $out .= ">" . t("Number of times") . ":</option>\n";
|
||||
$out .= "</select>";
|
||||
|
||||
$out .= "<input name='rec_until_date' value='" . $localization->dateformat_datepicker_php($rule_until_date) . "' id='rec_until_date'>";
|
||||
$out .= "<input name='rec_until_count' value='$rule_until_count' id='rec_until_count'><br>";
|
||||
|
||||
$out .= "<label class='block'>" . t("Exceptions") . ":</label><div class='rec_exceptions'>";
|
||||
$out .= "<div class='rec_exceptions_none' ";
|
||||
if (count($recurrentce_exdates) > 0) $out .= "style='display: none;'";
|
||||
$out .= ">" . t("none") . "</div>";
|
||||
$out .= "<div class='rec_exceptions_holder' ";
|
||||
if (count($recurrentce_exdates) == 0) $out .= "style='display: none;'";
|
||||
$out .= ">";
|
||||
|
||||
foreach ($recurrentce_exdates as $exdate) {
|
||||
$out .= "<div data-timestamp='$exdate' class='except'><input type='hidden' class='rec_exception' name='rec_exceptions[]' value='$exdate'>";
|
||||
$out .= "<a href='#' class='exception_remover'>[remove]</a> ";
|
||||
$out .= $localization->date_timestamp2localDate($exdate);
|
||||
$out .= "</div>\n";
|
||||
}
|
||||
$out .= "</div><div><a href='#' class='exception_adder'>[add]</a></div>";
|
||||
$out .= "</div>\n";
|
||||
$out .= "<br>\n";
|
||||
|
||||
$out .= "</div><br>";
|
||||
|
||||
$out .= "<h2>" .t("Notification") . "</h2>";
|
||||
|
||||
/*
|
||||
$out .= '<input type="checkbox" name="notification" id="notification" ';
|
||||
if ($notification) $out .= "checked";
|
||||
$out .= '> ';
|
||||
$out .= '<span id="notification_detail" style="display: none;">
|
||||
<input name="notification_value" value="' . $notification_value . '" size="3">
|
||||
<select name="notification_type" size="1">
|
||||
<option value="minute" ';
|
||||
if ($notification_type == "minute") $out .= "selected";
|
||||
$out .= '> ' . t('Minutes') . '</option>
|
||||
<option value="hour" ';
|
||||
if ($notification_type == "hour") $out .= "selected";
|
||||
$out .= '> ' . t('Hours') . '</option>
|
||||
<option value="day" ';
|
||||
if ($notification_type == "day") echo "selected";
|
||||
$out .= '> ' . t('Days') . '</option>
|
||||
</select> ' . t('before') . '
|
||||
</span><br><br>';
|
||||
*/
|
||||
|
||||
$out .= "<script>\$(function() {
|
||||
wdcal_edit_init('" . $localization->dateformat_datepicker_js() . "', '${baseurl}/dav/');
|
||||
});</script>";
|
||||
|
||||
$out .= "<input type='submit' name='save' value='Save'></form>";
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Sabre_VObject_Component_VEvent $component
|
||||
* @param wdcal_local $localization
|
||||
*/
|
||||
function wdcal_set_component_date(&$component, &$localization) {
|
||||
if (isset($_REQUEST["allday"])) {
|
||||
$ts_start = $localization->date_local2timestamp($_REQUEST["start_date"] . " 00:00");
|
||||
$ts_end = $localization->date_local2timestamp($_REQUEST["end_date"] . " 00:00");
|
||||
$type = Sabre_VObject_Property_DateTime::DATE;
|
||||
} else {
|
||||
$ts_start = $localization->date_local2timestamp($_REQUEST["start_date"] . " " . $_REQUEST["start_time"]);
|
||||
$ts_end = $localization->date_local2timestamp($_REQUEST["end_date"] . " " . $_REQUEST["end_time"]);
|
||||
$type = Sabre_VObject_Property_DateTime::LOCALTZ;
|
||||
}
|
||||
$datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
|
||||
$datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_start)), $type);
|
||||
$datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
|
||||
$datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_end)), $type);
|
||||
|
||||
$component->__unset("DTSTART");
|
||||
$component->__unset("DTEND");
|
||||
$component->add($datetime_start);
|
||||
$component->add($datetime_end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Sabre_VObject_Component_VEvent $component
|
||||
* @param wdcal_local $localization
|
||||
*/
|
||||
function wdcal_set_component_recurrence(&$component, &$localization) {
|
||||
$component->__unset("RRULE");
|
||||
$component->__unset("EXRULE");
|
||||
$component->__unset("EXDATE");
|
||||
$component->__unset("RDATE");
|
||||
|
||||
$part_until = "";
|
||||
switch ($_REQUEST["rec_until_type"]) {
|
||||
case "date":
|
||||
$date = $localization->date_local2timestamp($_REQUEST["rec_until_date"]);
|
||||
$part_until = ";UNTIL=" . date("Ymd", $date);
|
||||
$datetime_until = new Sabre_VObject_Property_DateTime("UNTIL");
|
||||
$datetime_until->setDateTime(new DateTime(date("Y-m-d H:i:s", $date)), Sabre_VObject_Property_DateTime::DATE);
|
||||
break;
|
||||
case "count":
|
||||
$part_until = ";COUNT=" . IntVal($_REQUEST["rec_until_count"]);
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($_REQUEST["rec_frequency"]) {
|
||||
case "daily":
|
||||
$part_freq = "FREQ=DAILY";
|
||||
if (isset($_REQUEST["rec_daily_byday"])) {
|
||||
$days = array();
|
||||
foreach ($_REQUEST["rec_daily_byday"] as $x) if (in_array($x, array("MO", "TU", "WE", "TH", "FR", "SA", "SU"))) $days[] = $x;
|
||||
if (count($days) > 0) $part_freq .= ";BYDAY=" . implode(",", $days);
|
||||
}
|
||||
break;
|
||||
case "weekly":
|
||||
$part_freq = "FREQ=WEEKLY";
|
||||
if (isset($_REQUEST["rec_weekly_wkst"]) && in_array($_REQUEST["rec_weekly_wkst"], array("MO", "SU"))) $part_freq .= ";WKST=" . $_REQUEST["rec_weekly_wkst"];
|
||||
if (isset($_REQUEST["rec_weekly_byday"])) {
|
||||
$days = array();
|
||||
foreach ($_REQUEST["rec_weekly_byday"] as $x) if (in_array($x, array("MO", "TU", "WE", "TH", "FR", "SA", "SU"))) $days[] = $x;
|
||||
if (count($days) > 0) $part_freq .= ";BYDAY=" . implode(",", $days);
|
||||
}
|
||||
break;
|
||||
case "monthly":
|
||||
$part_freq = "FREQ=MONTHLY";
|
||||
break;
|
||||
case "FREQ=yearly":
|
||||
$part_freq = "FREQ=YEARLY";
|
||||
break;
|
||||
default:
|
||||
$part_freq = "";
|
||||
}
|
||||
|
||||
if ($part_freq == "") return;
|
||||
|
||||
if (isset($_REQUEST["rec_interval"])) $part_freq .= ";INTERVAL=" . InTVal($_REQUEST["rec_interval"]);
|
||||
|
||||
if (isset($_REQUEST["rec_exceptions"])) {
|
||||
$arr = array();
|
||||
foreach ($_REQUEST["rec_exceptions"] as $except) {
|
||||
$arr[] = new DateTime(date("Y-m-d H:i:s", $except));
|
||||
}
|
||||
/** @var Sabre_VObject_Property_MultiDateTime $prop */
|
||||
$prop = Sabre_VObject_Property::create("EXDATE");
|
||||
$prop->setDateTimes($arr);
|
||||
$component->add($prop);
|
||||
}
|
||||
|
||||
$rrule = $part_freq . $part_until;
|
||||
$component->add(new Sabre_VObject_Property("RRULE", $rrule));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param string $recurr_uri
|
||||
* @param int $uid
|
||||
* @param string $timezone
|
||||
* @param string $goaway_url
|
||||
* @return array
|
||||
*/
|
||||
function wdcal_postEditPage($uri, $recurr_uri = "", $uid = 0, $timezone = "", $goaway_url = "")
|
||||
{
|
||||
$uid = IntVal($uid);
|
||||
$localization = wdcal_local::getInstanceByUser($uid);
|
||||
|
||||
$server = dav_create_server(true, true, false);
|
||||
|
||||
if ($uri > 0) {
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $_REQUEST["calendar"], DAV_ACL_READ);
|
||||
$obj_uri = Sabre_CalDAV_Backend_Common::loadCalendarobjectById($uri);
|
||||
$obj_uri = $obj_uri["uri"];
|
||||
|
||||
$vObject = dav_get_current_user_calendarobject($server, $calendar, $obj_uri, DAV_ACL_WRITE);
|
||||
$component = dav_get_eventComponent($vObject);
|
||||
|
||||
if ($component == null) return array("ok" => false, "msg" => t('Could not open component for editing'));
|
||||
} else {
|
||||
$calendar = dav_get_current_user_calendar_by_id($server, $_REQUEST["calendar"], DAV_ACL_WRITE);
|
||||
$vObject = dav_create_empty_vevent();
|
||||
$component = dav_get_eventComponent($vObject);
|
||||
$obj_uri = $component->__get("UID");
|
||||
}
|
||||
|
||||
wdcal_set_component_date($component, $localization);
|
||||
wdcal_set_component_recurrence($component, $localization);
|
||||
|
||||
$component->__unset("LOCATION");
|
||||
$component->__unset("SUMMARY");
|
||||
$component->__unset("DESCRIPTION");
|
||||
$component->__unset("X-ANIMEXXCOLOR");
|
||||
$component->add("SUMMARY", icalendar_sanitize_string(dav_compat_parse_text_serverside("summary")));
|
||||
$component->add("LOCATION", icalendar_sanitize_string(dav_compat_parse_text_serverside("location")));
|
||||
$component->add("DESCRIPTION", icalendar_sanitize_string(dav_compat_parse_text_serverside("wdcal_desc")));
|
||||
$component->add("X-ANIMEXX-COLOR", $_REQUEST["color"]);
|
||||
|
||||
$data = $vObject->serialize();
|
||||
|
||||
if ($uri == 0) {
|
||||
$calendar->createFile($obj_uri . ".ics", $data);
|
||||
} else {
|
||||
$obj = $calendar->getChild($obj_uri);
|
||||
$obj->put($data);
|
||||
}
|
||||
return array("ok" => false, "msg" => t("Saved"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function wdcal_getEditPage_exception_selector() {
|
||||
header("Content-type: application/json");
|
||||
|
||||
$a = get_app();
|
||||
$localization = wdcal_local::getInstanceByUser($a->user["uid"]);
|
||||
|
||||
$vObject = wdcal_create_empty_vevent();
|
||||
|
||||
foreach($vObject->getComponents() as $component) {
|
||||
if ($component->name!=='VTIMEZONE') break;
|
||||
}
|
||||
/** @var Sabre_VObject_Component_VEvent $component */
|
||||
wdcal_set_component_date($component, $localization);
|
||||
wdcal_set_component_recurrence($component, $localization);
|
||||
|
||||
|
||||
$it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
|
||||
$max_ts = mktime(0, 0, 0, 1, 1, CALDAV_MAX_YEAR + 1);
|
||||
$last_start = 0;
|
||||
|
||||
$o = "<ul>";
|
||||
|
||||
$i = 0;
|
||||
while($it->valid() && $last_start < $max_ts && $i++ < 1000) {
|
||||
$last_start = $it->getDtStart()->getTimestamp();
|
||||
$o .= "<li><a href='#' class='exception_selector_link' data-timestamp='$last_start'>" . $localization->date_timestamp2localDate($last_start) . "</a></li>\n";
|
||||
$it->next();
|
||||
}
|
||||
$o .= "</ul>\n";
|
||||
|
||||
return $o;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue