From 2ce255d30a9c19de623b2bfbb2b78a760278c31f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Morfin Date: Thu, 10 Mar 2022 11:33:14 +0100 Subject: [PATCH] Sync thirdparties addressbook --- admin/setup.php | 17 + class/CardDAVDolibarr.php | 885 +++++++++++++++++++++++++-------- core/modules/modCDav.class.php | 35 +- server.php | 11 + sql/llx_socpeople_cdav.sql | 26 - sql/update_001.sql | 1 - 6 files changed, 721 insertions(+), 254 deletions(-) delete mode 100644 sql/llx_socpeople_cdav.sql diff --git a/admin/setup.php b/admin/setup.php index 37cc5bc4..6869050b 100644 --- a/admin/setup.php +++ b/admin/setup.php @@ -65,6 +65,12 @@ '3' => $langs->trans("Sync as calendar events and todo tasks"), ); +$thirdsync_method=array( + '0' => $langs->trans("Not synchonized"), + '1' => $langs->trans("Only thirdparties without contact"), + '2' => $langs->trans("All thirdparties"), +); + $form = new Form($db); /* * Actions @@ -85,6 +91,10 @@ $db, "CDAV_CONTACT_TAG", GETPOST('CDAV_CONTACT_TAG', 'text'), 'chaine', 0, '', $conf->entity ); + dolibarr_set_const( + $db, "CDAV_THIRD_SYNC", + GETPOST('CDAV_THIRD_SYNC', 'text'), 'chaine', 0, '', $conf->entity + ); dolibarr_set_const( $db, "CDAV_SYNC_PAST", GETPOST('CDAV_SYNC_PAST', 'text'), 'chaine', 0, '', $conf->entity @@ -166,6 +176,7 @@ $CDAV_URI_KEY=substr($conf->global->CDAV_URI_KEY,0,8); $CDAV_CONTACT_TAG=$conf->global->CDAV_CONTACT_TAG; +$CDAV_THIRD_SYNC=$conf->global->CDAV_THIRD_SYNC; $CDAV_SYNC_PAST=$conf->global->CDAV_SYNC_PAST; $CDAV_SYNC_FUTURE=$conf->global->CDAV_SYNC_FUTURE; $CDAV_TASK_SYNC=$conf->global->CDAV_TASK_SYNC; @@ -209,6 +220,12 @@ print $form->select_all_categories("contact", $CDAV_CONTACT_TAG, 'CDAV_CONTACT_TAG', 0); print ''."\n"; +print ''; +print ''.$langs->trans("Enable thirdparties sync").'
'.$langs->trans("How to synchronize thirparties").''; +print ''; +print $form->selectarray('CDAV_THIRD_SYNC', $thirdsync_method, $CDAV_THIRD_SYNC); +print ''."\n"; + print ''; print ''.$langs->trans("Period to sync").'
'.$langs->trans("Number of days to sync before and after today").''; print ''; diff --git a/class/CardDAVDolibarr.php b/class/CardDAVDolibarr.php index 724b0411..e125c7a5 100644 --- a/class/CardDAVDolibarr.php +++ b/class/CardDAVDolibarr.php @@ -63,6 +63,8 @@ function __construct($user, $db, $langs) { */ function getAddressBooksForUser($principalUri) { + debug_log("getAddressBooksForUser( $principalUri )"); + $sql = 'SELECT MAX(GREATEST(COALESCE(s.tms, p.tms), p.tms)) lastupd FROM '.MAIN_DB_PREFIX.'socpeople as p LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc WHERE p.entity IN ('.getEntity('societe', 1).') @@ -77,12 +79,39 @@ function getAddressBooksForUser($principalUri) { 'id' => $this->user->id, 'uri' => 'default', 'principaluri' => $principalUri, - '{DAV:}displayname' => 'Dolibarr', + '{DAV:}displayname' => 'Dolibarr - contacts', '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'Contacts Dolibarr '.$this->user->login, '{http://calendarserver.org/ns/}getctag' => $lastupd, '{http://sabredav.org/ns}sync-token' => $lastupd, ]; - + + if(CDAV_THIRD_SYNC>0) + { + $sql = 'SELECT MAX(s.tms) lastupd FROM '.MAIN_DB_PREFIX.'societe as s + LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid + WHERE s.entity IN ('.getEntity('societe', 1).') + AND s.status=1'; + if(empty($this->user->rights->societe->client->voir)) + $sql.= ' AND s.rowid = sc.fk_soc AND sc.fk_user = '.((int) $this->user->id); + if (!$this->user->rights->fournisseur->lire) + $sql .= ' AND (s.fournisseur <> 1 OR s.client <> 0)'; // client=0, fournisseur=0 must be visible + if (CDAV_THIRD_SYNC==1) // without contact + $sql .= ' AND (SELECT count(sp.rowid) FROM llx_socpeople sp WHERE sp.fk_soc=s.rowid)=0'; + $result = $this->db->query($sql); + $row = $this->db->fetch_array($result); + $lastupd = strtotime($row['lastupd']); + + $addressBooks[] = [ + 'id' => $this->user->id + CDAV_ADDRESSBOOK_ID_SHIFT, + 'uri' => 'thirdparties', + 'principaluri' => $principalUri, + '{DAV:}displayname' => 'Dolibarr - thirdparties', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'Thirdparties-Societies Dolibarr '.$this->user->login, + '{http://calendarserver.org/ns/}getctag' => $lastupd, + '{http://sabredav.org/ns}sync-token' => $lastupd, + ]; + } + return $addressBooks; } @@ -104,7 +133,7 @@ function getAddressBooksForUser($principalUri) { * @param \Sabre\DAV\PropPatch $propPatch * @return void */ - function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) { + function updateAddressBook($addressbookId, \Sabre\DAV\PropPatch $propPatch) { // not supported return; @@ -132,7 +161,7 @@ function createAddressBook($principalUri, $url, array $properties) { * @param int $addressBookId * @return void */ - function deleteAddressBook($addressBookId) { + function deleteAddressBook($addressbookId) { // not supported return; @@ -148,11 +177,10 @@ protected function _getSqlContacts($sqlWhere='') { $sql = 'SELECT p.*, co.label country_label, GREATEST(COALESCE(s.tms, p.tms), p.tms) lastupd, s.code_client soc_code_client, s.code_fournisseur soc_code_fournisseur, s.nom soc_nom, s.name_alias soc_name_alias, s.address soc_address, s.zip soc_zip, s.town soc_town, cos.label soc_country_label, s.phone soc_phone, s.fax soc_fax, - s.email soc_email, s.url soc_url, s.client soc_client, s.fournisseur soc_fournisseur, s.note_private soc_note_private, s.note_public soc_note_public, spc.sourceuid, + s.email soc_email, s.url soc_url, s.client soc_client, s.fournisseur soc_fournisseur, s.note_private soc_note_private, s.note_public soc_note_public, GROUP_CONCAT(DISTINCT cat.label ORDER BY cat.label ASC SEPARATOR \',\') category_label, GROUP_CONCAT(DISTINCT cc.fk_categorie ORDER BY cc.fk_categorie ASC SEPARATOR \',\') category_ids FROM '.MAIN_DB_PREFIX.'socpeople as p - LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_cdav AS spc ON (p.rowid = spc.fk_object) LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON co.rowid = p.fk_pays LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc LEFT JOIN '.MAIN_DB_PREFIX.'c_country as cos ON cos.rowid = s.fk_pays @@ -169,6 +197,36 @@ protected function _getSqlContacts($sqlWhere='') return $sql; } + + /** + * Base sql request for thirdparties + * + * @return string + */ + protected function _getSqlThirdparties($sqlWhere='') + { + $sql = 'SELECT s.*, co.label country_label, s.tms lastupd, cfj.libelle as forme_juridique, + GROUP_CONCAT(DISTINCT cat.label ORDER BY cat.label ASC SEPARATOR \',\') category_label, + GROUP_CONCAT(DISTINCT cs.fk_categorie ORDER BY cs.fk_categorie ASC SEPARATOR \',\') category_ids + FROM '.MAIN_DB_PREFIX.'societe as s + LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid + LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON co.rowid = s.fk_pays + LEFT JOIN '.MAIN_DB_PREFIX.'c_country as cos ON cos.rowid = s.fk_pays + LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON cfj.rowid = s.fk_forme_juridique + LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cs ON cs.fk_soc = s.rowid + LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cat.rowid = cs.fk_categorie + WHERE s.entity IN ('.getEntity('societe', 1).') + AND s.status=1'; + if(empty($this->user->rights->societe->client->voir)) + $sql.= ' AND s.rowid = sc.fk_soc AND sc.fk_user = '.((int) $this->user->id); + if (!$this->user->rights->fournisseur->lire) + $sql .= ' AND (s.fournisseur <> 1 OR s.client <> 0)'; // client=0, fournisseur=0 must be visible + if (CDAV_THIRD_SYNC==1) // without contact + $sql .= ' AND (SELECT count(sp.rowid) FROM llx_socpeople sp WHERE sp.fk_soc=s.rowid)=0'; + $sql .= $sqlWhere.' GROUP BY s.rowid'; + + return $sql; + } /** * Convert contact row to VCard string @@ -176,7 +234,7 @@ protected function _getSqlContacts($sqlWhere='') * @param row object * @return string */ - protected function _toVCard($obj) + protected function _contactToVCard($obj) { global $conf; $nick = []; @@ -216,10 +274,7 @@ protected function _toVCard($obj) $carddata ="BEGIN:VCARD\n"; $carddata.="VERSION:3.0\n"; $carddata.="PRODID:-//Dolibarr CDav//FR\n"; - if($obj->sourceuid=='') - $carddata.="UID:".$obj->rowid.'-ct-'.CDAV_URI_KEY."\n"; - else - $carddata.="UID:".$obj->sourceuid."\n"; + $carddata.="UID:".$obj->rowid.'-ct-'.CDAV_URI_KEY."\n"; $carddata.="N;CHARSET=UTF-8:".str_replace(';','\;',$obj->lastname).";".str_replace(';','\;',$obj->firstname).";;".str_replace(';','\;',$obj->civility)."\n"; $carddata.="FN;CHARSET=UTF-8:".str_replace(';','\;',$obj->lastname." ".$obj->firstname)."\n"; if(!empty($obj->soc_nom) && !empty($obj->soc_name_alias)) @@ -309,15 +364,101 @@ protected function _toVCard($obj) $carddata.="END:VCARD\n"; return $carddata; } + + + /** + * Convert thirdparty row to VCard string + * + * @param row object + * @return string + */ + protected function _thirdpartyToVCard($obj) + { + global $conf; + $doliinfo = []; + $categ = []; + if($obj->client) + { + $doliinfo[] = "💼👑".$obj->code_client; + $categ[] = $this->langs->transnoentitiesnoconv('Customer'); + } + if($obj->fournisseur) + { + $doliinfo[] = "💼🏭".$obj->code_fournisseur; + $categ[] = $this->langs->transnoentitiesnoconv('Supplier'); + } + if (! empty($conf->categorie->enabled) && ! empty($this->user->rights->categorie->lire)) + if(trim($obj->category_label)!='') + $categ[] = trim($obj->category_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[]=''; + + $carddata ="BEGIN:VCARD\n"; + $carddata.="VERSION:3.0\n"; + $carddata.="PRODID:-//Dolibarr CDav//FR\n"; + $carddata.="UID:".$obj->rowid.'-th-'.CDAV_URI_KEY."\n"; + $carddata.="N;CHARSET=UTF-8:".str_replace(';','\;',$obj->nom)."\n"; + $carddata.="FN;CHARSET=UTF-8:".str_replace(';','\;',$obj->nom)."\n"; + if(!empty($obj->nom)) + $carddata.="ORG;CHARSET=UTF-8:".str_replace(';','\;',$obj->nom).";\n"; + if(!empty($obj->name_alias)) + $carddata.="NICKNAME;CHARSET=UTF-8:".str_replace(';','\;',$obj->name_alias).";\n"; + if(!empty($obj->forme_juridique)) + $carddata.="TITLE;CHARSET=UTF-8:".str_replace(';','\;',$obj->forme_juridique)."\n"; + if(count($categ)>0) + $carddata.="CATEGORIES;CHARSET=UTF-8:".str_replace(';','\;',implode(',',$categ))."\n"; + // $carddata.="CLASS:".($obj->priv?'PRIVATE':'PUBLIC')."\n"; + $carddata.="CLASS:PRIVATE\n"; + $carddata.="ADR;TYPE=WORK;CHARSET=UTF-8:;".str_replace(';','\;',$address[1]).";".str_replace(';','\;',$address[0]).";"; + $carddata.= str_replace(';','\;',$obj->town).";;".str_replace(';','\;',$obj->zip).";".str_replace(';','\;',$obj->country_label)."\n"; + $carddata.="TEL;TYPE=WORK,VOICE:".str_replace(';','\;',$obj->phone)."\n"; + if(!empty($obj->fax)) + $carddata.="TEL;TYPE=WORK,FAX:".str_replace(';','\;',$obj->fax)."\n"; + if(!empty($obj->email)) + $carddata.="EMAIL;PREF=1,INTERNET:".str_replace(';','\;',$obj->email)."\n"; + if(!empty($obj->url)) + { + if(strpos($obj->url,'://')===false) + $carddata.="URL:https://".trim($obj->url)."\n"; + } + if(!empty($obj->whatsapp)) + $carddata.="X-WHATSAPP:".str_replace(';','\;',$obj->whatsapp)."\n"; + if(!empty($obj->snapchat)) + $carddata.="X-SNAPCHAT:".str_replace(';','\;',$obj->snapchat)."\n"; + if(!empty($obj->linkedin)) + $carddata.="X-LINKEDIN:".str_replace(';','\;',$obj->linkedin)."\n"; + if(!empty($obj->instagram)) + $carddata.="X-INSTAGRAM:".str_replace(';','\;',$obj->instagram)."\n"; + if(!empty($obj->skype)) + $carddata.="X-SKYPE:".str_replace(';','\;',$obj->skype)."\n"; + $carddata.="NOTE;CHARSET=UTF-8:"; + foreach($doliinfo as $info) + $carddata.=strtr(trim($info),array("\n"=>"\\n", "\r"=>""))."\\n"; + if(!empty($obj->note_public)) + $carddata.=strtr(trim($obj->note_public),array("\n"=>"\\n", "\r"=>""))."\\n"; + if(!empty($obj->note_public)) + $carddata.=strtr(trim($obj->note_public),array("\n"=>"\\n", "\r"=>""))."\\n"; + $carddata.="\n"; + $carddata.="REV;TZID=".date_default_timezone_get().":".strtr($obj->lastupd,array(" "=>"T", ":"=>"", "-"=>""))."\n"; + $carddata.="END:VCARD\n"; + + return $carddata; + } /* * parse vcard data to dolibarr table fields * @param cardData : string vcard * @param mode : C=create / U=update */ - protected function _parseData($cardData, $mode) { + protected function _parseDataContact($cardData, $mode) { - debug_log("_parseData( $cardData )"); + debug_log("_parseDataContact( $cardData )"); $rdata = [] ; @@ -468,6 +609,209 @@ protected function _parseData($cardData, $mode) { return $rdata; } + + /* + * parse vcard data to dolibarr table fields + * @param cardData : string vcard + * @param mode : C=create / U=update + */ + protected function _parseDataThirdparty($cardData, $mode) { + + debug_log("_parseDataThirdparty( $cardData )"); + + $rdata = [] ; + + $vCard = VObject\Reader::read($cardData); + $vCard->validate(VObject\Node::REPAIR | VObject\Node::PROFILE_CARDDAV); + $vCard->convert(VObject\Document::VCARD30); + + // debug_log("_parseData__converted( ".$vCard->PHOTO." )"); + + $rdata['_uid'] = (string)$vCard->UID; + + if($mode=='C') + $rdata['status']=1; + + if(!empty((string)$vCard->FN)) + $rdata['nom'] = (string)$vCard->FN; + else + { + $rdata['nom']=''; + $names = $vCard->N->getParts(); + if(!empty((string)$names[0])) + $rdata['nom'].= (string)$names[0]; + if(!empty((string)$names[1])) + $rdata['nom'] = trim($rdata['nom']." ".(string)$names[1]); + if(!empty((string)$names[2])) + $rdata['nom'] = trim($rdata['nom']." ".(string)$names[2]); + if(!empty((string)$names[3])) + $rdata['nom'] = trim((string)$names[3]." ".$rdata['nom']); + if(empty($rdata['nom'])) + $rdata['nom'] = "New ".date('Y-m-d H:i:s'); + } + + if(isset($vCard->{'NICKNAME'})) + $rdata['name_alias'] = (string)$vCard->{'NICKNAME'}; + + if(isset($vCard->TEL)) + { + foreach($vCard->TEL as $tel) + { + $teltype = []; + $types = $tel['TYPE']; + foreach($types as $type) + { + $teltype[strtoupper($type)]=true; + } + + if(isset($teltype['VOICE']) && empty($rdata['phone'])) + $rdata['phone'] = (string)$tel; + + if(isset($teltype['WORK']) && isset($teltype['VOICE'])) + $rdata['phone'] = (string)$tel; + + if(isset($teltype['FAX'])) + $rdata['fax'] = (string)$tel; + } + } + + if(isset($vCard->EMAIL)) + { + foreach($vCard->EMAIL as $email) + { + if(!isset($rdata['email'])) + $rdata['email'] = (string)$email; + if(isset($email->PREF)) + $rdata['email'] = (string)$email; + } + } + + if(isset($vCard->URL)) + $rdata['url'] = (string)$vCard->URL; + + if(isset($vCard->ADR)) + { + foreach($vCard->ADR as $adr) + { + $types = $adr['TYPE']; + $adrtype = []; + foreach($types as $type) + { + $adrtype[strtoupper($type)]=true; + } + $adrparts = $adr->getParts(); + // debug_log("adrparts:\n".print_r($adrtype, true).print_r($adrparts, true)); + if(isset($adrtype['WORK']) || !isset($rdata['address'])) + { + $rdata['address'] = ''; + $rdata['town'] = ''; + $rdata['zip'] = ''; + $rdata['_country_label'] = ''; + if(isset($adrparts[2]) && !empty($adrparts[2])) + $rdata['address'].= str_replace(' | ',"\n",trim($adrparts[2]))."\n"; + if(isset($adrparts[0]) && !empty($adrparts[0])) + $rdata['address'].= $adrparts[0]."\n"; + if(isset($adrparts[1]) && !empty($adrparts[1])) + $rdata['address'].= str_replace(' | ',"\n",trim($adrparts[1]))."\n"; + $rdata['address'] = trim($rdata['address']); + if(isset($adrparts[3])) + $rdata['town'] = $adrparts[3]; + if(isset($adrparts[5])) + $rdata['zip'] = $adrparts[5]; + if(isset($adrparts[6])) + $rdata['_country_label'] = $adrparts[6]; + } + } + } + + if(isset($vCard->{'X-WHATSAPP'})) + $rdata['whatsapp'] = (string)$vCard->{'X-WHATSAPP'}; + if(isset($vCard->{'X-SNAPCHAT'})) + $rdata['snapchat'] = (string)$vCard->{'X-SNAPCHAT'}; + if(isset($vCard->{'X-LINKEDIN'})) + $rdata['linkedin'] = (string)$vCard->{'X-LINKEDIN'}; + if(isset($vCard->{'X-INSTAGRAM'})) + $rdata['instagram'] = (string)$vCard->{'X-INSTAGRAM'}; + if(isset($vCard->{'X-SKYPE'})) + $rdata['skype'] = (string)$vCard->{'X-SKYPE'}; + elseif(isset($vCard->{'X-SKYPE-USERNAME'})) + $rdata['skype'] = (string)$vCard->{'X-SKYPE-USERNAME'}; + + /** + IMPP;X-SERVICE-TYPE=GOOGLETALK:xmpp:goog + IMPP;X-SERVICE-TYPE=JABBER:xmpp:jabjab + IMPP;X-SERVICE-TYPE=YAHOO:ymsgr:yahoo + IMPP;X-SERVICE-TYPE=QQ:x-apple:qq + IMPP;X-SERVICE-TYPE=AIM:aim:aim + IMPP;X-SERVICE-TYPE=MSN:msnim:msn + IMPP;X-SERVICE-TYPE=SKYPE:skype:skyp + IMPP;X-SERVICE-TYPE=ICQ:aim:icqq + IMPP;X-SERVICE-TYPE=IRC:irc:irc + **/ + if(isset($vCard->IMPP)) + { + foreach($vCard->IMPP as $impp) + { + $type = strtoupper((string)$impp['X-SERVICE-TYPE']); + $pseudo = (string)$impp; + if(mb_strpos($pseudo,':',0,'UTF-8')!==false) + $pseudo = mb_substr($pseudo, mb_strpos($pseudo,':',0,'UTF-8')+1, null, 'UTF-8'); + + switch($type) + { + case "WHATSAPP": + $rdata['whatsapp'] = $pseudo; + break; + case "SNAPCHAT": + $rdata['snapchat'] = $pseudo; + break; + case "LINKEDIN": + $rdata['linkedin'] = $pseudo; + break; + case "INSTAGRAM": + $rdata['instagram'] = $pseudo; + break; + case "SKYPE": + $rdata['skype'] = $pseudo; + break; + } + } + } + + + if(isset($vCard->NOTE)) + { + $tmp = (string)$vCard->NOTE; + $arrNote = array(); + $arrTmp = explode("\n", $tmp); + foreach($arrTmp as $line) + { + if (mb_strpos($line, '💼', 0, 'UTF-8')!==0 + && mb_strpos($line, '??', 0, 'UTF-8')!==0 // 💼 could be converted in ?? if utf8 char is truncated on 2 VCal lines + && mb_strpos($line, '*DOLIBARR-', 0, 'UTF-8')===false) + { + $noteline = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD",$line); // remove utf8mb4 chars + $arrNote[] = $noteline; + } + } + $rdata['note_public'] = trim(implode("\n", $arrNote)); + } + + if(isset($rdata['_country_label']) && $rdata['_country_label']!='') + { + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'c_country + WHERE label LIKE "'.$this->db->escape($rdata['_country_label']).'" + AND active = 1'; + $result = $this->db->query($sql); + if($result!==false && ($row = $this->db->fetch_array($result))!==false) + $rdata['fk_pays'] = $row['rowid']; + } + + debug_log("parsed:\n".print_r($rdata, true)); + + return $rdata; + } + /** * Returns all cards for a specific addressbook id. * @@ -489,26 +833,49 @@ protected function _parseData($cardData, $mode) { */ function getCards($addressbookId) { + debug_log("getCards( $addressbookId )"); + $cards = [] ; - if(! $this->user->rights->societe->contact->lire) - return $cards; - - $sql = $this->_getSqlContacts(); - $result = $this->db->query($sql); - if ($result) + if(intval($addressbookId)user->rights->societe->contact->lire) { - while ($obj = $this->db->fetch_object($result)) + $sql = $this->_getSqlContacts(); + $result = $this->db->query($sql); + if ($result) { - $carddata = $this->_toVCard($obj); - - $cards[] = [ - // 'carddata' => $carddata, not necessary because etag+size are present - 'uri' => $obj->rowid.'-ct-'.CDAV_URI_KEY, - 'lastmodified' => strtotime($obj->lastupd), - 'etag' => '"'.md5($carddata).'"', - 'size' => strlen($carddata) - ]; + while ($obj = $this->db->fetch_object($result)) + { + $carddata = $this->_contactToVCard($obj); + + $cards[] = [ + // 'carddata' => $carddata, not necessary because etag+size are present + 'uri' => $obj->rowid.'-ct-'.CDAV_URI_KEY, + 'lastmodified' => strtotime($obj->lastupd), + 'etag' => '"'.md5($carddata).'"', + 'size' => strlen($carddata) + ]; + } + } + } + + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT) + { + $sql = $this->_getSqlThirdparties(); + $result = $this->db->query($sql); + if ($result) + { + while ($obj = $this->db->fetch_object($result)) + { + $carddata = $this->_thirdpartyToVCard($obj); + + $cards[] = [ + // 'carddata' => $carddata, not necessary because etag+size are present + 'uri' => $obj->rowid.'-th-'.CDAV_URI_KEY, + 'lastmodified' => strtotime($obj->lastupd), + 'etag' => '"'.md5($carddata).'"', + 'size' => strlen($carddata) + ]; + } } } return $cards; @@ -526,34 +893,61 @@ function getCards($addressbookId) { * @param string $cardUri * @return array */ - function getCard($addressBookId, $cardUri) { + function getCard($addressbookId, $cardUri) { - if(! $this->user->rights->societe->contact->lire) - return false; + debug_log("getCard( $addressbookId , $cardUri )"); - if(strpos($cardUri, '-ct-')>0) - $sqlWhere = ' AND p.rowid='.($cardUri*1); // cardUri starts with contact id - else - $sqlWhere = ' AND spc.uuidext = "'.$this->db->escape($cardUri).'"'; // cardUri comes from external apps - - $sql = $this->_getSqlContacts($sqlWhere); - - $result = $this->db->query($sql); - if ($result && $obj = $this->db->fetch_object($result)) + if(intval($addressbookId)user->rights->societe->contact->lire) { - $carddata = $this->_toVCard($obj); - - $card = [ - 'carddata' => $carddata, - 'uri' => $obj->rowid.'-ct-'.CDAV_URI_KEY, - 'lastmodified' => strtotime($obj->lastupd), - 'etag' => '"'.md5($carddata).'"', - 'size' => strlen($carddata) - ]; + if(strpos($cardUri, '-ct-')>0) + $sqlWhere = ' AND p.rowid='.($cardUri*1); // cardUri starts with contact id + else + return false; + + $sql = $this->_getSqlContacts($sqlWhere); - return $card; + $result = $this->db->query($sql); + if ($result && $obj = $this->db->fetch_object($result)) + { + $carddata = $this->_contactToVCard($obj); + + $card = [ + 'carddata' => $carddata, + 'uri' => $obj->rowid.'-ct-'.CDAV_URI_KEY, + 'lastmodified' => strtotime($obj->lastupd), + 'etag' => '"'.md5($carddata).'"', + 'size' => strlen($carddata) + ]; + + return $card; + } } + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT) + { + if(strpos($cardUri, '-th-')>0) + $sqlWhere = ' AND s.rowid='.($cardUri*1); // cardUri starts with contact id + else + return false; + + $sql = $this->_getSqlThirdparties($sqlWhere); + debug_log($sql); + $result = $this->db->query($sql); + if ($result && $obj = $this->db->fetch_object($result)) + { + $carddata = $this->_thirdpartyToVCard($obj); + + $card = [ + 'carddata' => $carddata, + 'uri' => $obj->rowid.'-th-'.CDAV_URI_KEY, + 'lastmodified' => strtotime($obj->lastupd), + 'etag' => '"'.md5($carddata).'"', + 'size' => strlen($carddata) + ]; + + return $card; + } + } return false; } @@ -569,48 +963,65 @@ function getCard($addressBookId, $cardUri) { * @param array $uris * @return array */ - function getMultipleCards($addressBookId, array $uris) { + function getMultipleCards($addressbookId, array $uris) { + debug_log("getMultipleCards( $addressbookId , ".implode('; ',$uris)." )"); + $cards = [] ; - if(! $this->user->rights->societe->contact->lire) - return $cards; - - $ids = []; - $extids = []; - foreach($uris as $cardUri) - { - if(strpos($cardUri, '-ct-')>0) - $ids[] = ($cardUri*1); // cardUri starts with contact id - else - $extids[] = '"'.$this->db->escape($cardUri).'"'; // cardUri comes from external apps - } + $typecth = ''; + $ids = []; + $extids = []; + + if(intval($addressbookId)user->rights->societe->contact->lire) + { + $typecth = '-ct-'; + foreach($uris as $cardUri) + { + if(strpos($cardUri, $typecth)>0) + $ids[] = ($cardUri*1); // cardUri starts with contact id + } - $sqlWhere = ''; - if(count($ids)>0 && count($extids)>0) - $sqlWhere = ' AND (p.rowid IN ('.implode(',', $ids).') - OR spc.uuidext IN ('.implode(',',$extids).') )'; - else if(count($ids)>0) - $sqlWhere = ' AND p.rowid IN ('.implode(',', $ids).')'; - else if(count($extids)>0) - $sqlWhere = ' AND spc.uuidext IN ('.implode(',',$extids).')'; + $sqlWhere = ' AND p.rowid IN ('.implode(',', $ids).')'; - $sql = $this->_getSqlContacts($sqlWhere); + $sql = $this->_getSqlContacts($sqlWhere); + } + + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT) + { + $typecth = '-th-'; + foreach($uris as $cardUri) + { + if(strpos($cardUri, $typecth)>0) + $ids[] = ($cardUri*1); // cardUri starts with contact id + } - $result = $this->db->query($sql); - if ($result) + $sqlWhere = ' AND s.rowid IN ('.implode(',', $ids).')'; + + $sql = $this->_getSqlThirdparties($sqlWhere); + } + + if($typecth!='') { - while ($obj = $this->db->fetch_object($result)) + + $result = $this->db->query($sql); + if ($result) { - $carddata = $this->_toVCard($obj); - - $cards[] = [ - 'carddata' => $carddata, - 'uri' => $obj->rowid.'-ct-'.CDAV_URI_KEY, - 'lastmodified' => strtotime($obj->lastupd), - 'etag' => '"'.md5($carddata).'"', - 'size' => strlen($carddata) - ]; + while ($obj = $this->db->fetch_object($result)) + { + if($typecth=='-th-') + $carddata = $this->_thirdpartyToVCard($obj); + else + $carddata = $this->_contactToVCard($obj); + + $cards[] = [ + 'carddata' => $carddata, + 'uri' => $obj->rowid.$typecth.CDAV_URI_KEY, + 'lastmodified' => strtotime($obj->lastupd), + 'etag' => '"'.md5($carddata).'"', + 'size' => strlen($carddata) + ]; + } } } return $cards; @@ -641,81 +1052,113 @@ function getMultipleCards($addressBookId, array $uris) { * @param string $cardData * @return string|null */ - function createCard($addressBookId, $cardUri, $cardData) { + function createCard($addressbookId, $cardUri, $cardData) { - global $conf; - - debug_log("createContactObject( $addressBookId , $cardUri )"); - - if(! $this->user->rights->societe->contact->creer) - return null; + global $conf; - $rdata = $this->_parseData($cardData, 'C'); + debug_log("createContactObject( $addressbookId , $cardUri )"); - if($rdata['_photo_bin']!==false) + if(intval($addressbookId)user->rights->societe->contact->creer) { - $gdim = @imagecreatefromstring($rdata['_photo_bin']); - if($gdim!==false) - $rdata['photo'] = 'cdavimage.jpg'; - } + $rdata = $this->_parseDataContact($cardData, 'C'); + + if($rdata['_photo_bin']!==false) + { + $gdim = @imagecreatefromstring($rdata['_photo_bin']); + if($gdim!==false) + $rdata['photo'] = 'cdavimage.jpg'; + } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."socpeople ("; - foreach($rdata as $fld => $val) - { - if(substr($fld,0,1)!='_') - $sql.="`".$fld."`,"; - } - $sql.= "entity,datec,tms,fk_user_creat,fk_user_modif) VALUES("; - foreach($rdata as $fld => $val) - { - if(substr($fld,0,1)!='_') - $sql.="'".$this->db->escape($val)."',"; - } - $sql.= "1,NOW(),NOW(),".$this->user->id.",".$this->user->id.")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."socpeople ("; + foreach($rdata as $fld => $val) + { + if(substr($fld,0,1)!='_') + $sql.="`".$fld."`,"; + } + $sql.= "entity,datec,tms,fk_user_creat,fk_user_modif) VALUES("; + foreach($rdata as $fld => $val) + { + if(substr($fld,0,1)!='_') + $sql.="'".$this->db->escape($val)."',"; + } + $sql.= "1,NOW(),NOW(),".$this->user->id.",".$this->user->id.")"; - $res = $this->db->query($sql); - if ( ! $res) - { + $res = $this->db->query($sql); + if ( ! $res) + { + return null; + } + + //Récupérer l'ID de l'event créer et faire une insertion dans actioncomm_resources + $id = $this->db->last_insert_id(MAIN_DB_PREFIX.'socpeople'); + if ( ! $id) + { + return null; + } + + if (! empty($conf->categorie->enabled) && intval(CDAV_CONTACT_TAG)>0) + { + $tagid = intval(CDAV_CONTACT_TAG); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_contact (`fk_categorie`, `fk_socpeople`) + VALUES ( ".$tagid.", ".$id.")"; + $this->db->query($sql); + } + + // save photo with jpeg format + if(isset($rdata['photo'])) + { + $dir = $conf->societe->dir_output."/contact/".$id."/photos"; + @mkdir($dir, 0777, true); + if(@imagejpeg($gdim, $dir.'/'.$rdata['photo'])) + { + $object = new \Contact($this->db); + if($object->fetch($id)>0) + $object->addThumbs($dir.'/'.$rdata['photo']); + } + } return null; } - //Récupérer l'ID de l'event créer et faire une insertion dans actioncomm_resources - $id = $this->db->last_insert_id(MAIN_DB_PREFIX.'socpeople'); - if ( ! $id) + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT) { - return; - } - - if (! empty($conf->categorie->enabled) && intval(CDAV_CONTACT_TAG)>0) - { - $tagid = intval(CDAV_CONTACT_TAG); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_contact (`fk_categorie`, `fk_socpeople`) - VALUES ( ".$tagid.", ".$id.")"; - $this->db->query($sql); - } + $rdata = $this->_parseDataThirdparty($cardData, 'C'); + - //Insérer l'UUID externe - $sql = "INSERT INTO ".MAIN_DB_PREFIX."socpeople_cdav (`fk_object`, `uuidext`, `sourceuid`) - VALUES ( - ".$id.", - '".$this->db->escape($cardUri)."', - '".$this->db->escape($rdata['_uid'])."' - )"; - $this->db->query($sql); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe ("; + foreach($rdata as $fld => $val) + { + if(substr($fld,0,1)!='_') + $sql.="`".$fld."`,"; + } + $sql.= "entity,datec,tms,fk_user_creat,fk_user_modif) VALUES("; + foreach($rdata as $fld => $val) + { + if(substr($fld,0,1)!='_') + $sql.="'".$this->db->escape($val)."',"; + } + $sql.= "1,NOW(),NOW(),".$this->user->id.",".$this->user->id.")"; - // save photo with jpeg format - if(isset($rdata['photo'])) - { - $dir = $conf->societe->dir_output."/contact/".$id."/photos"; - @mkdir($dir, 0777, true); - if(@imagejpeg($gdim, $dir.'/'.$rdata['photo'])) + $res = $this->db->query($sql); + if ( ! $res) { - $object = new \Contact($this->db); - if($object->fetch($id)>0) - $object->addThumbs($dir.'/'.$rdata['photo']); + return null; + } + + //Récupérer l'ID de l'event créer et faire une insertion dans actioncomm_resources + $id = $this->db->last_insert_id(MAIN_DB_PREFIX.'societe'); + if ( ! $id) + { + return null; } - } + //Insérer association user/thirdpartie + $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_commerciaux (`fk_soc`, `fk_user`) + VALUES (".$id.",".$this->user->id.")"; + $this->db->query($sql); + + return null; + } + return null; } @@ -744,63 +1187,76 @@ function createCard($addressBookId, $cardUri, $cardData) { * @param string $cardData * @return string|null */ - function updateCard($addressBookId, $cardUri, $cardData) { + function updateCard($addressbookId, $cardUri, $cardData) { global $conf; - debug_log("updateContactObject( $addressBookId , $cardUri )"); - - if(! $this->user->rights->societe->contact->creer) - return null; - - $rdata = $this->_parseData($cardData, 'U'); + debug_log("updateContactObject( $addressbookId , $cardUri )"); - if(strpos($cardUri, '-ct-')>0) + if(intval($addressbookId)user->rights->societe->contact->creer) { - $contactid = ($cardUri*1); // cardUri starts with contact id - } - else - { - $sql = "SELECT `fk_object` FROM ".MAIN_DB_PREFIX."socpeople_cdav - WHERE `uuidext`= '".$this->db->escape($cardUri)."'"; // cardUri comes from external apps - $result = $this->db->query($sql); - if($result!==false && ($row = $this->db->fetch_array($result))!==false) - $contactid = $row['fk_object']*1; + $rdata = $this->_parseDataContact($cardData, 'U'); + + if(strpos($cardUri, '-ct-')>0) + $contactid = ($cardUri*1); // cardUri starts with contact id else - return null; // not found - } + return false; - if($rdata['_photo_bin']!==false) - { - $gdim = @imagecreatefromstring($rdata['_photo_bin']); - if($gdim!==false) - $rdata['photo'] = 'cdavimage.jpg'; + if($rdata['_photo_bin']!==false) + { + $gdim = @imagecreatefromstring($rdata['_photo_bin']); + if($gdim!==false) + $rdata['photo'] = 'cdavimage.jpg'; + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET "; + foreach($rdata as $fld => $val) + { + if(substr($fld,0,1)!='_') + $sql.="`".$fld."` = '".$this->db->escape($val)."', "; + } + $sql.= " tms = NOW(), fk_user_modif = ".$this->user->id; + $sql.= " WHERE rowid = ".$contactid; + $res = $this->db->query($sql); + + $this->db->query($sql); + + // save photo with jpeg format + if(isset($rdata['photo'])) + { + $dir = $conf->societe->dir_output."/contact/".$contactid."/photos"; + @mkdir($dir, 0777, true); + if(@imagejpeg($gdim, $dir.'/'.$rdata['photo'])) + { + $object = new \Contact($this->db); + if($object->fetch($contactid)>0) + $object->addThumbs($dir.'/'.$rdata['photo']); + } + } } - $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET "; - foreach($rdata as $fld => $val) + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT) { - if(substr($fld,0,1)!='_') - $sql.="`".$fld."` = '".$this->db->escape($val)."', "; - } - $sql.= " tms = NOW(), fk_user_modif = ".$this->user->id; - $sql.= " WHERE rowid = ".$contactid; - $res = $this->db->query($sql); + $rdata = $this->_parseDataThirdparty($cardData, 'U'); - $this->db->query($sql); + if(strpos($cardUri, '-th-')>0) + $socid = ($cardUri*1); // cardUri starts with contact id + else + return false; - // save photo with jpeg format - if(isset($rdata['photo'])) - { - $dir = $conf->societe->dir_output."/contact/".$contactid."/photos"; - @mkdir($dir, 0777, true); - if(@imagejpeg($gdim, $dir.'/'.$rdata['photo'])) + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET "; + foreach($rdata as $fld => $val) { - $object = new \Contact($this->db); - if($object->fetch($contactid)>0) - $object->addThumbs($dir.'/'.$rdata['photo']); - } + if(substr($fld,0,1)!='_') + $sql.="`".$fld."` = '".$this->db->escape($val)."', "; + } + $sql.= " tms = NOW(), fk_user_modif = ".$this->user->id; + $sql.= " WHERE rowid = ".$socid; + $res = $this->db->query($sql); + $this->db->query($sql); } + + return null; } /** @@ -810,34 +1266,43 @@ function updateCard($addressBookId, $cardUri, $cardData) { * @param string $cardUri * @return bool */ - function deleteCard($addressBookId, $cardUri) { + function deleteCard($addressbookId, $cardUri) { - debug_log("deleteContactObject( $addressBookId , $cardUri )"); + debug_log("deleteContactObject( $addressbookId , $cardUri )"); - if(! $this->user->rights->societe->contact->supprimer) - return false; - - if(strpos($cardUri, '-ct-')>0) + if(intval($addressbookId)user->rights->societe->contact->supprimer) { - $contactid = ($cardUri*1); // cardUri starts with contact id + + if(strpos($cardUri, '-ct-')>0) + $contactid = ($cardUri*1); // cardUri starts with contact id + else + return false; + + $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET "; + $sql.= " statut = 0, tms = NOW(), fk_user_modif = ".$this->user->id; + $sql.= " WHERE rowid = ".$contactid; + $res = $this->db->query($sql); + + return true; } - else + + if(CDAV_THIRD_SYNC>0 && intval($addressbookId)>=CDAV_ADDRESSBOOK_ID_SHIFT && $this->user->rights->societe->supprimer) { - $sql.= "SELECT `fk_object` FROM ".MAIN_DB_PREFIX."socpeople_cdav - WHERE `uuidext`= '".$this->db->escape($cardUri)."'"; // cardUri comes from external apps - $result = $this->db->query($sql); - if($result!==false && ($row = $this->db->fetch_array($result))!==false) - $contactid = $row['fk_object']*1; - else - return false; // not found - } - $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET "; - $sql.= " statut = 0, tms = NOW(), fk_user_modif = ".$this->user->id; - $sql.= " WHERE rowid = ".$contactid; - $res = $this->db->query($sql); + if(strpos($cardUri, '-th-')>0) + $socid = ($cardUri*1); // cardUri starts with contact id + else + return false; - return true; + $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET "; + $sql.= " status = 0, tms = NOW(), fk_user_modif = ".$this->user->id; + $sql.= " WHERE rowid = ".$socid; + $res = $this->db->query($sql); + + return true; + } + + return false; } /** @@ -896,7 +1361,7 @@ function deleteCard($addressBookId, $cardUri) { * @param int $limit * @return array */ - function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null) { + function getChangesForAddressBook($addressbookId, $syncToken, $syncLevel, $limit = null) { // TODO return null; diff --git a/core/modules/modCDav.class.php b/core/modules/modCDav.class.php index df6e4872..f296930d 100644 --- a/core/modules/modCDav.class.php +++ b/core/modules/modCDav.class.php @@ -58,7 +58,7 @@ function __construct($db) // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) $this->description = "Allows caldav and carddav clients to sync with Dolibarr."; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = '2.05'; + $this->version = '2.10'; // Key used in llx_const table to save module status enabled/disabled (where CDAV is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) @@ -115,22 +115,23 @@ function __construct($db) $this->const = array( 0 => array('CDAV_URI_KEY', 'chaine', substr(md5(time()),0,8),'Change it to force client to resync',0,'current',0), 1 => array('CDAV_CONTACT_TAG', 'chaine', '', 'Contact tag to restrict contacts to sync, leave blank for all',0,'current',0), - 2 => array('CDAV_SYNC_PAST', 'chaine', '31', 'Number of days to sync before today',0,'current',0), - 3 => array('CDAV_SYNC_FUTURE', 'chaine', '365', 'Number of days to sync after today',0,'current',0), - 4 => array('CDAV_TASK_SYNC', 'chaine', '0', 'How to sync project tasks',0,'current',0), - 5 => array('CDAV_GENTASK', 'chaine', '0', 'Convert documents to tasks',0,'current',0), - 5 => array('CDAV_GENTASK_INI1', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), - 5 => array('CDAV_GENTASK_INI2', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), - 5 => array('CDAV_GENTASK_INI3', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), - 5 => array('CDAV_GENTASK_END1', 'chaine', '0', 'Generate final tasks from services',0,'current',0), - 5 => array('CDAV_GENTASK_END2', 'chaine', '0', 'Generate final tasks from services',0,'current',0), - 5 => array('CDAV_GENTASK_END3', 'chaine', '0', 'Generate final tasks from services',0,'current',0), - 6 => array('CDAV_PROJ_USER_ROLE', 'chaine', '', 'Project user role to find default task owner',0,'current',0), - 7 => array('CDAV_TASK_USER_ROLE', 'chaine', '', 'Project task user role when creating a new project task',0,'current',0), - 8 => array('CDAV_GENTASK_SERVICE_TAG', 'chaine', '', 'Service tag to restrict services to be converted as task, leave blank to sync all',0,'current',0), - 8 => array('CDAV_EXTRAFIELD_DURATION', 'chaine', '', 'Duration services',0,'current',0), - 8 => array('CDAV_TASK_HOUR_INI', 'chaine', '', 'Begining of a working day',0,'current',0), - 8 => array('CDAV_TASK_HOUR_END', 'chaine', '', 'Ending of a working day',0,'current',0), + 2 => array('CDAV_THIRD_SYNC', 'chaine', '0', 'How to sync thirdparties',0,'current',0), + 3 => array('CDAV_SYNC_PAST', 'chaine', '31', 'Number of days to sync before today',0,'current',0), + 4 => array('CDAV_SYNC_FUTURE', 'chaine', '365', 'Number of days to sync after today',0,'current',0), + 5 => array('CDAV_TASK_SYNC', 'chaine', '0', 'How to sync project tasks',0,'current',0), + 6 => array('CDAV_GENTASK', 'chaine', '0', 'Convert documents to tasks',0,'current',0), + 7 => array('CDAV_GENTASK_INI1', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), + 8 => array('CDAV_GENTASK_INI2', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), + 9 => array('CDAV_GENTASK_INI3', 'chaine', '0', 'Generate initial tasks from services',0,'current',0), + 10 => array('CDAV_GENTASK_END1', 'chaine', '0', 'Generate final tasks from services',0,'current',0), + 11 => array('CDAV_GENTASK_END2', 'chaine', '0', 'Generate final tasks from services',0,'current',0), + 12 => array('CDAV_GENTASK_END3', 'chaine', '0', 'Generate final tasks from services',0,'current',0), + 13 => array('CDAV_PROJ_USER_ROLE', 'chaine', '', 'Project user role to find default task owner',0,'current',0), + 14 => array('CDAV_TASK_USER_ROLE', 'chaine', '', 'Project task user role when creating a new project task',0,'current',0), + 15 => array('CDAV_GENTASK_SERVICE_TAG', 'chaine', '', 'Service tag to restrict services to be converted as task, leave blank to sync all',0,'current',0), + 16 => array('CDAV_EXTRAFIELD_DURATION', 'chaine', '', 'Duration services',0,'current',0), + 17 => array('CDAV_TASK_HOUR_INI', 'chaine', '', 'Begining of a working day',0,'current',0), + 18 => array('CDAV_TASK_HOUR_END', 'chaine', '', 'Ending of a working day',0,'current',0), ); // Array to add new pages in new tabs diff --git a/server.php b/server.php index d3bf0192..65c48a7f 100644 --- a/server.php +++ b/server.php @@ -161,6 +161,17 @@ function llxFooter() { } define('CDAV_TASK_SYNC', '0'); } +// define CDAV_THIRD_SYNC if not +if(!defined('CDAV_THIRD_SYNC')) +{ + if(isset($conf->global->CDAV_THIRD_SYNC)) + define('CDAV_THIRD_SYNC', $conf->global->CDAV_THIRD_SYNC); + else + define('CDAV_THIRD_SYNC', '0'); +} + +define('CDAV_ADDRESSBOOK_ID_SHIFT', 100000); + // Sabre/dav configuration use Sabre\DAV; diff --git a/sql/llx_socpeople_cdav.sql b/sql/llx_socpeople_cdav.sql deleted file mode 100644 index 74552851..00000000 --- a/sql/llx_socpeople_cdav.sql +++ /dev/null @@ -1,26 +0,0 @@ --- ============================================================================ --- Copyright (C) 2015 Jérôme ANDANSON --- --- 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 . --- --- Table of "socpeople_cdav" for cdav module --- ============================================================================ - -CREATE TABLE IF NOT EXISTS `llx_socpeople_cdav` ( - `fk_object` int(11) NOT NULL, - `uuidext` varchar(255) NOT NULL, - `sourceuid` varchar(255) NOT NULL, - PRIMARY KEY (`fk_object`), - KEY `uuidext` (`uuidext`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Storage of external UUID created by externals applications'; diff --git a/sql/update_001.sql b/sql/update_001.sql index 1115fac3..b616cfcc 100644 --- a/sql/update_001.sql +++ b/sql/update_001.sql @@ -18,4 +18,3 @@ -- ============================================================================ ALTER TABLE `llx_actioncomm_cdav` ADD `sourceuid` VARCHAR(255) NOT NULL AFTER `uuidext`; -ALTER TABLE `llx_socpeople_cdav` ADD `sourceuid` VARCHAR(255) NOT NULL AFTER `uuidext`;