diff --git a/htdocs/dav/dav.class.php b/htdocs/dav/dav.class.php
new file mode 100644
index 00000000000..c0220d77a66
--- /dev/null
+++ b/htdocs/dav/dav.class.php
@@ -0,0 +1,294 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/dav/dav.class.php
+ * \ingroup dav
+ * \brief Server DAV
+ */
+
+
+/**
+ * Define Common function to access calendar items
+ * And format it in vCalendar
+ * */
+
+class CdavLib
+{
+
+ private $db;
+
+ private $user;
+
+ private $langs;
+
+ function __construct($user, $db, $langs)
+ {
+ $this->user = $user;
+ $this->db = $db;
+ $this->langs = $langs;
+ }
+
+ /**
+ * Base sql request for calendar events
+ *
+ * @param int calendar user id
+ * @param int actioncomm object id
+ * @return string
+ */
+ public function getSqlCalEvents($calid, $oid=false, $ouri=false)
+ {
+ // TODO : replace GROUP_CONCAT by
+ $sql = 'SELECT
+ a.tms AS lastupd,
+ a.*,
+ sp.firstname,
+ sp.lastname,
+ sp.address,
+ sp.zip,
+ sp.town,
+ co.label country_label,
+ sp.phone,
+ sp.phone_perso,
+ sp.phone_mobile,
+ s.nom AS soc_nom,
+ s.address soc_address,
+ s.zip soc_zip,
+ s.town soc_town,
+ cos.label soc_country_label,
+ s.phone soc_phone,
+ ac.sourceuid,
+ (SELECT GROUP_CONCAT(u.login) FROM '.MAIN_DB_PREFIX.'actioncomm_resources ar
+ LEFT OUTER JOIN '.MAIN_DB_PREFIX.'user AS u ON (u.rowid=fk_element)
+ WHERE ar.element_type=\'user\' AND fk_actioncomm=a.id) AS other_users
+ FROM '.MAIN_DB_PREFIX.'actioncomm AS a';
+ if (! $this->user->rights->societe->client->voir )//FIXME si 'voir' on voit plus de chose ?
+ {
+ $sql.=' LEFT OUTER JOIN '.MAIN_DB_PREFIX.'societe_commerciaux AS sc ON (a.fk_soc = sc.fk_soc AND sc.fk_user='.$this->user->id.')
+ LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON (s.rowid = sc.fk_soc)
+ LEFT JOIN '.MAIN_DB_PREFIX.'socpeople AS sp ON (sp.fk_soc = sc.fk_soc AND sp.rowid = a.fk_contact)
+ LEFT JOIN '.MAIN_DB_PREFIX.'actioncomm_cdav AS ac ON (a.id = ac.fk_object)';
+ }
+ else
+ {
+ $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON (s.rowid = a.fk_soc)
+ LEFT JOIN '.MAIN_DB_PREFIX.'socpeople AS sp ON (sp.rowid = a.fk_contact)
+ LEFT JOIN '.MAIN_DB_PREFIX.'actioncomm_cdav AS ac ON (a.id = ac.fk_object)';
+ }
+
+ $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON co.rowid = sp.fk_pays
+ LEFT JOIN '.MAIN_DB_PREFIX.'c_country as cos ON cos.rowid = s.fk_pays
+ WHERE a.id IN (SELECT ar.fk_actioncomm FROM '.MAIN_DB_PREFIX.'actioncomm_resources ar WHERE ar.element_type=\'user\' AND ar.fk_element='.intval($calid).')
+ AND a.code IN (SELECT cac.code FROM '.MAIN_DB_PREFIX.'c_actioncomm cac WHERE cac.type<>\'systemauto\')
+ AND a.entity IN ('.getEntity('societe', 1).')';
+ if($oid!==false) {
+ if($ouri===false)
+ {
+ $sql.=' AND a.id = '.intval($oid);
+ }
+ else
+ {
+ $sql.=' AND (a.id = '.intval($oid).' OR ac.uuidext = \''.$this->db->escape($ouri).'\')';
+ }
+ }
+
+ return $sql;
+
+ }
+
+ /**
+ * Convert calendar row to VCalendar string
+ *
+ * @param row object
+ * @return string
+ */
+ public function toVCalendar($calid, $obj)
+ {
+
+ $categ = [];
+ /*if($obj->soc_client)
+ {
+ $nick[] = $obj->soc_code_client;
+ $categ[] = $this->langs->transnoentitiesnoconv('Customer');
+ }*/
+
+ $location=$obj->location;
+
+ // contact address
+ if(empty($location) && !empty($obj->address))
+ {
+ $location = trim(str_replace(array("\r","\t","\n"),' ', $obj->address));
+ $location = trim($location.', '.$obj->zip);
+ $location = trim($location.' '.$obj->town);
+ $location = trim($location.', '.$obj->country_label);
+ }
+
+ // contact address
+ if(empty($location) && !empty($obj->soc_address))
+ {
+ $location = trim(str_replace(array("\r","\t","\n"),' ', $obj->soc_address));
+ $location = trim($location.', '.$obj->soc_zip);
+ $location = trim($location.' '.$obj->soc_town);
+ $location = trim($location.', '.$obj->soc_country_label);
+ }
+
+ $address=explode("\n",$obj->address,2);
+ foreach($address as $kAddr => $vAddr)
+ {
+ $address[$kAddr] = trim(str_replace(array("\r","\t"),' ', str_replace("\n",' | ', trim($vAddr))));
+ }
+ $address[]='';
+ $address[]='';
+
+ if($obj->percent==-1 && trim($obj->datep)!='')
+ $type='VEVENT';
+ else
+ $type='VTODO';
+
+ $timezone = date_default_timezone_get();
+
+ $caldata ="BEGIN:VCALENDAR\n";
+ $caldata.="VERSION:2.0\n";
+ $caldata.="METHOD:PUBLISH\n";
+ $caldata.="PRODID:-//Dolibarr CDav//FR\n";
+ $caldata.="BEGIN:".$type."\n";
+ $caldata.="CREATED:".gmdate('Ymd\THis', strtotime($obj->datec))."Z\n";
+ $caldata.="LAST-MODIFIED:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n";
+ $caldata.="DTSTAMP:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n";
+ if($obj->sourceuid=='')
+ $caldata.="UID:".$obj->id.'-ev-'.$calid.'-cal-'.CDAV_URI_KEY."\n";
+ else
+ $caldata.="UID:".$obj->sourceuid."\n";
+ $caldata.="SUMMARY:".$obj->label."\n";
+ $caldata.="LOCATION:".$location."\n";
+ $caldata.="PRIORITY:".$obj->priority."\n";
+ if($obj->fulldayevent)
+ {
+ $caldata.="DTSTART;VALUE=DATE:".date('Ymd', strtotime($obj->datep))."\n";
+ if($type=='VEVENT')
+ {
+ if(trim($obj->datep2)!='')
+ $caldata.="DTEND;VALUE=DATE:".date('Ymd', strtotime($obj->datep2)+1)."\n";
+ else
+ $caldata.="DTEND;VALUE=DATE:".date('Ymd', strtotime($obj->datep)+(25*3600))."\n";
+ }
+ elseif(trim($obj->datep2)!='')
+ $caldata.="DUE;VALUE=DATE:".date('Ymd', strtotime($obj->datep2)+1)."\n";
+ }
+ else
+ {
+ $caldata.="DTSTART;TZID=".$timezone.":".strtr($obj->datep,array(" "=>"T", ":"=>"", "-"=>""))."\n";
+ if($type=='VEVENT')
+ {
+ if(trim($obj->datep2)!='')
+ $caldata.="DTEND;TZID=".$timezone.":".strtr($obj->datep2,array(" "=>"T", ":"=>"", "-"=>""))."\n";
+ else
+ $caldata.="DTEND;TZID=".$timezone.":".strtr($obj->datep,array(" "=>"T", ":"=>"", "-"=>""))."\n";
+ }
+ elseif(trim($obj->datep2)!='')
+ $caldata.="DUE;TZID=".$timezone.":".strtr($obj->datep2,array(" "=>"T", ":"=>"", "-"=>""))."\n";
+ }
+ $caldata.="CLASS:PUBLIC\n";
+ if($obj->transparency==1)
+ $caldata.="TRANSP:TRANSPARENT\n";
+ else
+ $caldata.="TRANSP:OPAQUE\n";
+
+ if($type=='VEVENT')
+ $caldata.="STATUS:CONFIRMED\n";
+ elseif($obj->percent==0)
+ $caldata.="STATUS:NEEDS-ACTION\n";
+ elseif($obj->percent==100)
+ $caldata.="STATUS:COMPLETED\n";
+ else
+ {
+ $caldata.="STATUS:IN-PROCESS\n";
+ $caldata.="PERCENT-COMPLETE:".$obj->percent."\n";
+ }
+
+ $caldata.="DESCRIPTION:";
+ $caldata.=strtr($obj->note, array("\n"=>"\\n", "\r"=>""));
+ if(!empty($obj->soc_nom))
+ $caldata.="\\n*DOLIBARR-SOC: ".$obj->soc_nom;
+ if(!empty($obj->soc_phone))
+ $caldata.="\\n*DOLIBARR-SOC-TEL: ".$obj->soc_phone;
+ if(!empty($obj->firstname) || !empty($obj->lastname))
+ $caldata.="\\n*DOLIBARR-CTC: ".trim($obj->firstname.' '.$obj->lastname);
+ if(!empty($obj->phone) || !empty($obj->phone_perso) || !empty($obj->phone_mobile))
+ $caldata.="\\n*DOLIBARR-CTC-TEL: ".trim($obj->phone.' '.$obj->phone_perso.' '.$obj->phone_mobile);
+ if(strpos($obj->other_users,',')) // several
+ $caldata.="\\n*DOLIBARR-USR: ".$obj->other_users;
+ $caldata.="\n";
+
+ $caldata.="END:".$type."\n";
+ $caldata.="END:VCALENDAR\n";
+
+ return $caldata;
+ }
+
+ public function getFullCalendarObjects($calendarId, $bCalendarData)
+ {
+
+ $calid = ($calendarId*1);
+ $calevents = [] ;
+
+ if(! $this->user->rights->agenda->myactions->read)
+ return $calevents;
+
+ if($calid!=$this->user->id && (!isset($this->user->rights->agenda->allactions->read) || !$this->user->rights->agenda->allactions->read))
+ return $calevents;
+
+ $sql = $this->getSqlCalEvents($calid);
+
+ $result = $this->db->query($sql);
+
+ if ($result)
+ {
+ while ($obj = $this->db->fetch_object($result))
+ {
+ $calendardata = $this->toVCalendar($calid, $obj);
+
+ if($bCalendarData)
+ {
+ $calevents[] = [
+ 'calendardata' => $calendardata,
+ 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY,
+ 'lastmodified' => strtotime($obj->lastupd),
+ 'etag' => '"'.md5($calendardata).'"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($calendardata),
+ 'component' => strpos($calendardata, 'BEGIN:VEVENT')>0 ? 'vevent' : 'vtodo',
+ ];
+ }
+ else
+ {
+ $calevents[] = [
+ // 'calendardata' => $calendardata, not necessary because etag+size are present
+ 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY,
+ 'lastmodified' => strtotime($obj->lastupd),
+ 'etag' => '"'.md5($calendardata).'"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($calendardata),
+ 'component' => strpos($calendardata, 'BEGIN:VEVENT')>0 ? 'vevent' : 'vtodo',
+ ];
+ }
+ }
+ }
+ return $calevents;
+ }
+
+}
diff --git a/htdocs/dav/dav.lib.php b/htdocs/dav/dav.lib.php
new file mode 100644
index 00000000000..326ad7995b5
--- /dev/null
+++ b/htdocs/dav/dav.lib.php
@@ -0,0 +1,40 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/dav/dav.lib.php
+ * \ingroup dav
+ * \brief Server DAV
+ */
+
+// define CDAV_CONTACT_TAG if not
+if(!defined('CDAV_CONTACT_TAG'))
+{
+ if(isset($conf->global->CDAV_CONTACT_TAG))
+ define('CDAV_CONTACT_TAG', $conf->global->CDAV_CONTACT_TAG);
+ else
+ define('CDAV_CONTACT_TAG', '');
+}
+
+// define CDAV_URI_KEY if not
+if(!defined('CDAV_URI_KEY'))
+{
+ if(isset($conf->global->CDAV_URI_KEY))
+ define('CDAV_URI_KEY', $conf->global->CDAV_URI_KEY);
+ else
+ define('CDAV_URI_KEY', substr(md5($_SERVER['HTTP_HOST']),0,8));
+}
diff --git a/htdocs/dav/fileserver.php b/htdocs/dav/fileserver.php
index a597fa750fe..c8b71d1e3f5 100644
--- a/htdocs/dav/fileserver.php
+++ b/htdocs/dav/fileserver.php
@@ -35,10 +35,11 @@ define("NOCSRFCHECK",1); // We accept to go on this page from external web site.
require ("../main.inc.php");
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-
-// Files we need
+require_once DOL_DOCUMENT_ROOT.'/dav/dav.class.php';
+require_once DOL_DOCUMENT_ROOT.'/dav/dav.lib.php';
require_once DOL_DOCUMENT_ROOT.'/includes/sabre/autoload.php';
+
$user = new User($db);
if(isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_USER']!='')
{
@@ -83,7 +84,7 @@ $authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function ($username, $p
return true;
});
-$authBackend->setRealm('Dolibarr');
+$authBackend->setRealm(constant('DOL_APPLICATION_TITLE'));
@@ -95,16 +96,24 @@ $authBackend->setRealm('Dolibarr');
// Create the root node
// Setting up the directory tree //
-$nodes = array(
- // /principals
- //new \Sabre\DAVACL\PrincipalCollection($principalBackend),
- // /addressbook
- //new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend),
- // /calendars
- //new \Sabre\CalDAV\CalendarRoot($principalBackend, $caldavBackend),
- // / Public docs
- new \Sabre\DAV\FS\Directory($dolibarr_main_data_root. '/dav/public')
-);
+$nodes = array();
+
+// Enable directories and features according to DAV setup
+// / Public docs
+$nodes[] = new \Sabre\DAV\FS\Directory($dolibarr_main_data_root. '/dav/public');
+
+// Principals Backend
+//$principalBackend = new \Sabre\DAVACL\PrincipalBackend\Dolibarr($user,$db);
+// /principals
+//$nodes[] = new \Sabre\DAVACL\PrincipalCollection($principalBackend);
+// CardDav & CalDav Backend
+//$carddavBackend = new \Sabre\CardDAV\Backend\Dolibarr($user,$db,$langs);
+//$caldavBackend = new \Sabre\CalDAV\Backend\Dolibarr($user,$db,$langs, $cdavLib);
+// /addressbook
+//$nodes[] = new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend);
+// /calendars
+//$nodes[] = new \Sabre\CalDAV\CalendarRoot($principalBackend, $caldavBackend);
+
// The rootnode needs in turn to be passed to the server class
$server = new \Sabre\DAV\Server($nodes);