From 0bfff92032d8573a9ce96b285fcada70136acc80 Mon Sep 17 00:00:00 2001 From: "Sekan, Tobias" Date: Fri, 1 Nov 2019 11:59:54 +0100 Subject: [PATCH 1/6] Add attendee to ical export + cleanup --- htdocs/comm/action/class/actioncomm.class.php | 16 + htdocs/core/lib/xcal.lib.php | 847 +++++++++--------- 2 files changed, 459 insertions(+), 404 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 8432ba786a1..308012c6ca9 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1579,6 +1579,22 @@ class ActionComm extends CommonObject $event['created']=$this->db->jdate($obj->datec)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600)); $event['modified']=$this->db->jdate($obj->datem)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600)); + // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties + $this->id = $obj->id; + $this->fetch_userassigned(); + + $assignedUserArray = array(); + + foreach($this->userassigned as $key => $value) + { + $assignedUser = new User($this->db); + $assignedUser->fetch($value['id']); + + $assignedUserArray[$key]=$assignedUser; + } + + $event['assignedUsers']=$assignedUserArray; + if ($qualified && $datestart) { $eventarray[]=$event; diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index b45eaa4b7a9..40656e5c0c4 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ @@ -25,499 +25,538 @@ * Build a file from an array of events * All input params and data must be encoded in $conf->charset_output * - * @param string $format 'vcal' or 'ical' - * @param string $title Title of export - * @param string $desc Description of export - * @param array $events_array Array of events ('eid','startdate','duration','enddate','title','summary','category','email','url','desc','author') - * @param string $outputfile Output file - * @return int <0 if ko, Nb of events in file if ok + * @param string $format "vcal" or "ical" + * @param string $title Title of export + * @param string $desc Description of export + * @param array $events_array Array of events ("uid","startdate","duration","enddate","title","summary","category","email","url","desc","author") + * @param string $outputfile Output file + * @return int < 0 if ko, Nb of events in file if ok */ function build_calfile($format, $title, $desc, $events_array, $outputfile) { - global $conf,$langs; + global $conf, $langs; - dol_syslog("xcal.lib.php::build_calfile Build cal file ".$outputfile." to format ".$format); + dol_syslog("xcal.lib.php::build_calfile Build cal file ".$outputfile." to format ".$format); - if (empty($outputfile)) return -1; + if (empty($outputfile)) + { + // -1 = error + return -1; + } // Note: A cal file is an UTF8 encoded file - $calfileh=fopen($outputfile, 'w'); - if ($calfileh) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - $now=dol_now(); + $calfileh = fopen($outputfile, "w"); - $encoding=''; - if ($format == 'vcal') $encoding='ENCODING=QUOTED-PRINTABLE:'; + if ($calfileh) + { + include_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; - // Print header - fwrite($calfileh, "BEGIN:VCALENDAR\n"); - fwrite($calfileh, "VERSION:2.0\n"); - fwrite($calfileh, "METHOD:PUBLISH\n"); - //fwrite($calfileh,"PRODID:-//DOLIBARR ".DOL_VERSION."//EN\n"); - fwrite($calfileh, "PRODID:-//DOLIBARR ".DOL_VERSION."\n"); - fwrite($calfileh, "CALSCALE:GREGORIAN\n"); - fwrite($calfileh, "X-WR-CALNAME:".$encoding.format_cal($format, $title)."\n"); - fwrite($calfileh, "X-WR-CALDESC:".$encoding.format_cal($format, $desc)."\n"); - //fwrite($calfileh,"X-WR-TIMEZONE:Europe/Paris\n"); - if (! empty($conf->global->MAIN_AGENDA_EXPORT_CACHE) - && $conf->global->MAIN_AGENDA_EXPORT_CACHE > 60){ - $hh=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, 'hour'); - $mm=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, 'min'); - $ss=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, 'sec'); - fwrite($calfileh, "X-PUBLISHED-TTL: P".$hh."H".$mm."M".$ss."S\n"); + $now = dol_now(); + $encoding = ""; + + if ($format === "vcal") + { + $encoding = "ENCODING=QUOTED-PRINTABLE:"; } - foreach ($events_array as $key => $event) - { - $eventqualified=true; - if ($eventqualified) - { - // See http://fr.wikipedia.org/wiki/ICalendar for format - // See http://www.ietf.org/rfc/rfc2445.txt for RFC - $uid = $event['uid']; - $type = $event['type']; - $startdate = $event['startdate']; - $duration = $event['duration']; - $enddate = $event['enddate']; - $summary = $event['summary']; - $category = $event['category']; - $priority = $event['priority']; - $fulldayevent = $event['fulldayevent']; - $location = $event['location']; - $email = $event['email']; - $url = $event['url']; - $transparency = $event['transparency']; // OPAQUE (busy) or TRANSPARENT (not busy) - $description=preg_replace('//i', "\n", $event['desc']); - $description=dol_string_nohtmltag($description, 0); // Remove html tags - $created = $event['created']; - $modified = $event['modified']; + // Print header + fwrite($calfileh, "BEGIN:VCALENDAR\n"); - // Uncomment for tests - //$summary="Resume"; - //$description="Description"; - //$description="MemberValidatedInDolibarr gd gdf gd gdff\nNom: tgdf g dfgdf gfd r ter\nType: gdfgfdf dfg fd gfd gd gdf gdf gfd gdfg dfg ddf\nAuteur: AD01fg dgdgdfg df gdf gd"; + // version is always "2.0" + fwrite($calfileh, "VERSION:2.0\n"); - // Format - $summary=format_cal($format, $summary); - $description=format_cal($format, $description); - $category=format_cal($format, $category); - $location=format_cal($format, $location); + fwrite($calfileh, "METHOD:PUBLISH\n"); + fwrite($calfileh, "PRODID:-//DOLIBARR ".DOL_VERSION."\n"); + fwrite($calfileh, "CALSCALE:GREGORIAN\n"); + fwrite($calfileh, "X-WR-CALNAME:".$encoding.format_cal($format, $title)."\n"); + fwrite($calfileh, "X-WR-CALDESC:".$encoding.format_cal($format, $desc)."\n"); + //fwrite($calfileh,"X-WR-TIMEZONE:Europe/Paris\n"); - // Output the vCard/iCal VEVENT object - /* - Example from Google ical export for a 1 hour event: - BEGIN:VEVENT - DTSTART:20101103T120000Z - DTEND:20101103T130000Z - DTSTAMP:20101121T144902Z - UID:4eilllcsq8r1p87ncg7vc8dbpk@google.com - CREATED:20101121T144657Z - DESCRIPTION: - LAST-MODIFIED:20101121T144707Z - LOCATION: - SEQUENCE:0 - STATUS:CONFIRMED - SUMMARY:Tâche 1 heure - TRANSP:OPAQUE - END:VEVENT + if (! empty($conf->global->MAIN_AGENDA_EXPORT_CACHE) && $conf->global->MAIN_AGENDA_EXPORT_CACHE > 60) + { + $hh = convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, "hour"); + $mm = convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, "min"); + $ss = convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE, "sec"); - Example from Google ical export for a 1 day event: - BEGIN:VEVENT - DTSTART;VALUE=DATE:20101102 - DTEND;VALUE=DATE:20101103 - DTSTAMP:20101121T144902Z - UID:d09t43kcf1qgapu9efsmmo1m6k@google.com - CREATED:20101121T144607Z - DESCRIPTION: - LAST-MODIFIED:20101121T144607Z - LOCATION: - SEQUENCE:0 - STATUS:CONFIRMED - SUMMARY:Tâche 1 jour - TRANSP:TRANSPARENT - END:VEVENT - */ - if ($type == 'event') - { - fwrite($calfileh, "BEGIN:VEVENT\n"); - fwrite($calfileh, "UID:".$uid."\n"); - if (! empty($email)) - { - fwrite($calfileh, "ORGANIZER:MAILTO:".$email."\n"); - fwrite($calfileh, "CONTACT:MAILTO:".$email."\n"); - } - if (! empty($url)) - { - fwrite($calfileh, "URL:".$url."\n"); - }; + fwrite($calfileh, "X-PUBLISHED-TTL: P".$hh."H".$mm."M".$ss."S\n"); + } - if ($created) fwrite($calfileh, "CREATED:".dol_print_date($created, 'dayhourxcard', true)."\n"); - if ($modified) fwrite($calfileh, "LAST-MODIFIED:".dol_print_date($modified, 'dayhourxcard', true)."\n"); - fwrite($calfileh, "SUMMARY:".$encoding.$summary."\n"); - fwrite($calfileh, "DESCRIPTION:".$encoding.$description."\n"); + foreach ($events_array as $key => $event) + { + // See http://fr.wikipedia.org/wiki/ICalendar for format + // See http://www.ietf.org/rfc/rfc2445.txt for RFC - /* Other keys: - // Status values for a "VEVENT" - statvalue = "TENTATIVE" ;Indicates event is - ;tentative. - / "CONFIRMED" ;Indicates event is - ;definite. - / "CANCELLED" ;Indicates event was - // Status values for "VTODO". - statvalue =/ "NEEDS-ACTION" ;Indicates to-do needs action. - / "COMPLETED" ;Indicates to-do completed. - / "IN-PROCESS" ;Indicates to-do in process of - / "CANCELLED" ;Indicates to-do was cancelled. - // Status values for "VJOURNAL". - statvalue =/ "DRAFT" ;Indicates journal is draft. - / "FINAL" ;Indicates journal is final. - / "CANCELLED" ;Indicates journal is removed. - */ - //fwrite($calfileh,"CLASS:PUBLIC\n"); // PUBLIC, PRIVATE, CONFIDENTIAL - //fwrite($calfileh,"X-MICROSOFT-CDO-BUSYSTATUS:1\n"); - //ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Laurent Destailleur;X-NUM-GUESTS=0:mailto:eldy10@gmail.com + // TODO: avoid use extra event array, use objects direct thahtwas created before - if (! empty($location)) fwrite($calfileh, "LOCATION:".$encoding.$location."\n"); - if ($fulldayevent) fwrite($calfileh, "X-FUNAMBOL-ALLDAY:1\n"); + $uid = $event["uid"]; + $type = $event["type"]; + $startdate = $event["startdate"]; + $duration = $event["duration"]; + $enddate = $event["enddate"]; + $summary = $event["summary"]; + $category = $event["category"]; + $priority = $event["priority"]; + $fulldayevent = $event["fulldayevent"]; + $location = $event["location"]; + $email = $event["email"]; + $url = $event["url"]; + $transparency = $event["transparency"]; + $description = dol_string_nohtmltag(preg_replace("//i", "\n", $event["desc"]), 0); + $created = $event["created"]; + $modified = $event["modified"]; + $assignedUsers = $event["assignedUsers"]; - // see https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/0f262da6-c5fd-459e-9f18-145eba86b5d2 - if ($fulldayevent) fwrite($calfileh, "X-MICROSOFT-CDO-ALLDAYEVENT:TRUE\n"); + // Format + $summary = format_cal($format, $summary); + $description = format_cal($format, $description); + $category = format_cal($format, $category); + $location = format_cal($format, $location); - // Date must be GMT dates - // Current date - fwrite($calfileh, "DTSTAMP:".dol_print_date($now, 'dayhourxcard', true)."\n"); - // Start date - $prefix=''; - $startdatef = dol_print_date($startdate, 'dayhourxcard', true); - if ($fulldayevent) - { - $prefix=';VALUE=DATE'; - $startdatef = dol_print_date($startdate, 'dayxcard', false); // Local time - } - fwrite($calfileh, "DTSTART".$prefix.":".$startdatef."\n"); - // End date - if ($fulldayevent) - { - if (empty($enddate)) $enddate=dol_time_plus_duree($startdate, 1, 'd'); - } - else - { - if (empty($enddate)) $enddate=$startdate+$duration; - } - $prefix=''; - $enddatef = dol_print_date($enddate, 'dayhourxcard', true); - if ($fulldayevent) - { - $prefix=';VALUE=DATE'; - $enddatef = dol_print_date($enddate+1, 'dayxcard', false); - //$enddatef .= dol_print_date($enddate+1,'dayhourxcard',false); // Local time - } - fwrite($calfileh, "DTEND".$prefix.":".$enddatef."\n"); - fwrite($calfileh, 'STATUS:CONFIRMED'."\n"); - if (! empty($transparency)) fwrite($calfileh, "TRANSP:".$transparency."\n"); - if (! empty($category)) fwrite($calfileh, "CATEGORIES:".$encoding.$category."\n"); - fwrite($calfileh, "END:VEVENT\n"); - } + if ($type === "event") + { + fwrite($calfileh, "BEGIN:VEVENT\n"); + fwrite($calfileh, "UID:".$uid."\n"); - // Output the vCard/iCal VTODO object - // ... - //PERCENT-COMPLETE:39 + if (! empty($email)) + { + fwrite($calfileh, "ORGANIZER:MAILTO:".$email."\n"); + fwrite($calfileh, "CONTACT:MAILTO:".$email."\n"); + } - // Output the vCard/iCal VJOURNAL object - if ($type == 'journal') - { - fwrite($calfileh, "BEGIN:VJOURNAL\n"); - fwrite($calfileh, "UID:".$uid."\n"); - if (! empty($email)) - { - fwrite($calfileh, "ORGANIZER:MAILTO:".$email."\n"); - fwrite($calfileh, "CONTACT:MAILTO:".$email."\n"); - } - if (! empty($url)) - { - fwrite($calfileh, "URL:".$url."\n"); - }; + if (! empty($url)) + { + fwrite($calfileh, "URL:".$url."\n"); + } - if ($created) fwrite($calfileh, "CREATED:".dol_print_date($created, 'dayhourxcard', true)."\n"); - if ($modified) fwrite($calfileh, "LAST-MODIFIED:".dol_print_date($modified, 'dayhourxcard', true)."\n"); - fwrite($calfileh, "SUMMARY:".$encoding.$summary."\n"); - fwrite($calfileh, "DESCRIPTION:".$encoding.$description."\n"); - fwrite($calfileh, 'STATUS:CONFIRMED'."\n"); - fwrite($calfileh, "CATEGORIES:".$category."\n"); - fwrite($calfileh, "LOCATION:".$location."\n"); - fwrite($calfileh, "TRANSP:OPAQUE\n"); - fwrite($calfileh, "CLASS:CONFIDENTIAL\n"); - fwrite($calfileh, "DTSTAMP:".dol_print_date($startdatef, 'dayhourxcard', true)."\n"); + if (is_array($assignedUsers)) + { + foreach($assignedUsers as $assignedUser) + { + if($assignedUser->email === $email) + { + continue; + } - fwrite($calfileh, "END:VJOURNAL\n"); - } + fwrite($calfileh,"ATTENDEE;RSVP=TRUE:mailto:".$assignedUser->email."\n"); + } + } + if ($created) + { + fwrite($calfileh, "CREATED:".dol_print_date($created, "dayhourxcard", true)."\n"); + } - // Put other info in comment - /* - $comment=array(); - $comment ['eid'] = $eid; - $comment ['url'] = $linktoevent; - $comment ['date'] = dol_mktime($evttime,"Ymd"); - $comment ['duration'] = $duration; - $comment ['startdate'] = $startdate; - $comment ['enddate'] = $enddate; - fwrite($calfileh,"COMMENT:" . serialize ($comment) . "\n"); - */ - } - } + if ($modified) + { + fwrite($calfileh, "LAST-MODIFIED:".dol_print_date($modified, "dayhourxcard", true)."\n"); + } - // Footer - fwrite($calfileh, "END:VCALENDAR"); + fwrite($calfileh, "SUMMARY:".$encoding.$summary."\n"); + fwrite($calfileh, "DESCRIPTION:".$encoding.$description."\n"); - fclose($calfileh); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); - } - else - { - dol_syslog("xcal.lib.php::build_calfile Failed to open file ".$outputfile." for writing"); - return -2; - } + if (! empty($location)) + { + fwrite($calfileh, "LOCATION:".$encoding.$location."\n"); + } + + if ($fulldayevent) + { + fwrite($calfileh, "X-FUNAMBOL-ALLDAY:1\n"); + } + + // see https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/0f262da6-c5fd-459e-9f18-145eba86b5d2 + if ($fulldayevent) + { + fwrite($calfileh, "X-MICROSOFT-CDO-ALLDAYEVENT:TRUE\n"); + } + + // Date must be GMT dates + // Current date + fwrite($calfileh, "DTSTAMP:".dol_print_date($now, "dayhourxcard", true)."\n"); + + // Start date + $prefix = ""; + $startdatef = dol_print_date($startdate, "dayhourxcard", true); + + if ($fulldayevent) + { + // Local time + $prefix = ";VALUE=DATE"; + $startdatef = dol_print_date($startdate, "dayxcard", false); + } + + fwrite($calfileh, "DTSTART".$prefix.":".$startdatef."\n"); + + // End date + if ($fulldayevent) + { + if (empty($enddate)) + { + $enddate = dol_time_plus_duree($startdate, 1, "d"); + } + } + else + { + if (empty($enddate)) + { + $enddate = $startdate+$duration; + } + } + + $prefix = ""; + $enddatef = dol_print_date($enddate, "dayhourxcard", true); + + if ($fulldayevent) + { + $prefix = ";VALUE=DATE"; + $enddatef = dol_print_date($enddate+1, "dayxcard", false); + + // Local time + //$enddatef .= dol_print_date($enddate+1,"dayhourxcard",false); + } + + fwrite($calfileh, "DTEND".$prefix.":".$enddatef."\n"); + fwrite($calfileh, "STATUS:CONFIRMED"."\n"); + + if (! empty($transparency)) + { + fwrite($calfileh, "TRANSP:".$transparency."\n"); + } + + if (! empty($category)) + { + fwrite($calfileh, "CATEGORIES:".$encoding.$category."\n"); + } + + fwrite($calfileh, "END:VEVENT\n"); + } + + // Output the vCard/iCal VJOURNAL object + if ($type === "journal") + { + fwrite($calfileh, "BEGIN:VJOURNAL\n"); + fwrite($calfileh, "UID:".$uid."\n"); + + if (! empty($email)) + { + fwrite($calfileh, "ORGANIZER:MAILTO:".$email."\n"); + fwrite($calfileh, "CONTACT:MAILTO:".$email."\n"); + } + + if (! empty($url)) + { + fwrite($calfileh, "URL:".$url."\n"); + } + + if ($created) + { + fwrite($calfileh, "CREATED:".dol_print_date($created, "dayhourxcard", true)."\n"); + } + + if ($modified) + { + fwrite($calfileh, "LAST-MODIFIED:".dol_print_date($modified, "dayhourxcard", true)."\n"); + } + + fwrite($calfileh, "SUMMARY:".$encoding.$summary."\n"); + fwrite($calfileh, "DESCRIPTION:".$encoding.$description."\n"); + fwrite($calfileh, "STATUS:CONFIRMED"."\n"); + fwrite($calfileh, "CATEGORIES:".$category."\n"); + fwrite($calfileh, "LOCATION:".$location."\n"); + fwrite($calfileh, "TRANSP:OPAQUE\n"); + fwrite($calfileh, "CLASS:CONFIDENTIAL\n"); + fwrite($calfileh, "DTSTAMP:".dol_print_date($startdatef, "dayhourxcard", true)."\n"); + + fwrite($calfileh, "END:VJOURNAL\n"); + } + } + + // Footer + fwrite($calfileh, "END:VCALENDAR"); + + fclose($calfileh); + + if (! empty($conf->global->MAIN_UMASK)) + { + @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + } + else + { + dol_syslog("xcal.lib.php::build_calfile Failed to open file ".$outputfile." for writing"); + return -2; + } } /** - * Build a file from an array of events. + * Build a file from an array of events. * All input data must be encoded in $conf->charset_output * - * @param string $format 'rss' - * @param string $title Title of export - * @param string $desc Description of export - * @param array $events_array Array of events ('uid','startdate','summary','url','desc','author','category') - * @param string $outputfile Output file - * @param string $filter Filter - * @return int <0 if ko, Nb of events in file if ok + * @param string $format "rss" + * @param string $title Title of export + * @param string $desc Description of export + * @param array $events_array Array of events ("uid","startdate","summary","url","desc","author","category") + * @param string $outputfile Output file + * @param string $filter (optional) Filter + * @return int < 0 if ko, Nb of events in file if ok */ -function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '') +function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = "") { - global $user,$conf,$langs; - global $dolibarr_main_url_root; + global $user, $conf, $langs; + global $dolibarr_main_url_root; - dol_syslog("xcal.lib.php::build_rssfile Build rss file ".$outputfile." to format ".$format); + dol_syslog("xcal.lib.php::build_rssfile Build rss file ".$outputfile." to format ".$format); - if (empty($outputfile)) return -1; + if (empty($outputfile)) + { + // -1 = error + return -1; + } - $fichier=fopen($outputfile, 'w'); - if ($fichier) - { - $date=date("r"); + $fichier = fopen($outputfile, "w"); - // Print header - $form='charset_output.'"?>'; - fwrite($fichier, $form); - fwrite($fichier, "\n"); - $form=''; - fwrite($fichier, $form); - fwrite($fichier, "\n"); + if ($fichier) + { + $date = date("r"); - $form="\n".$title."\n"; - fwrite($fichier, $form); + // Print header + fwrite($fichier, 'charset_output.""?>'); + fwrite($fichier, "\n"); - $form=''."\n". - // 'fr'."\n". - 'Dolibarr'."\n". - ''.$date.''."\n". - 'Dolibarr'."\n"; + fwrite($fichier, ''); + fwrite($fichier, "\n"); - // Define $urlwithroot - $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - $url=$urlwithroot.'/public/agenda/agendaexport.php?format=rss&exportkey='.urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY); - $form.=''."\n"; + fwrite($fichier, "\n".$title."\n"); - //print $form; - fwrite($fichier, $form); + $form = ""."\n". + // "fr"."\n". + "Dolibarr"."\n". + "".$date.""."\n". + "Dolibarr"."\n"; + // Define $urlwithroot + $urlwithouturlroot = preg_replace("/".preg_quote(DOL_URL_ROOT, "/")."$/i", "", trim($dolibarr_main_url_root)); - foreach ($events_array as $key => $event) - { - $eventqualified=true; - if ($filter) - { - // TODO Add a filter + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - $eventqualified=false; - } + $url=$urlwithroot."/public/agenda/agendaexport.php?format=rss&exportkey=".urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY); - if ($eventqualified) - { - $uid = $event['uid']; - $startdate = $event['startdate']; - $summary = $event['summary']; - $url = $event['url']; - $author = $event['author']; - $category = $event['category']; - /* No place inside a RSS - $priority = $event['priority']; - $fulldayevent = $event['fulldayevent']; - $location = $event['location']; - $email = $event['email']; + fwrite($fichier, ""."\n"); + + foreach ($events_array as $key => $event) + { + $eventqualified = true; + + if ($filter) + { + // TODO Add a filter + + $eventqualified=false; + } + + if ($eventqualified) + { + $uid = $event["uid"]; + $startdate = $event["startdate"]; + $summary = $event["summary"]; + $url = $event["url"]; + $author = $event["author"]; + $category = $event["category"]; + + /* No place inside a RSS + $priority = $event["priority"]; + $fulldayevent = $event["fulldayevent"]; + $location = $event["location"]; + $email = $event["email"]; */ - $description=preg_replace('//i', "\n", $event['desc']); - $description=dol_string_nohtmltag($description, 0); // Remove html tags - fwrite($fichier, "\n"); - fwrite($fichier, "<![CDATA[".$summary."]]>\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "".date("r", $startdate)."\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "\n"); - fwrite($fichier, "\n"); - } - } + $description = dol_string_nohtmltag(preg_replace("//i", "\n", $event["desc"]), 0); - fwrite($fichier, ''); - fwrite($fichier, "\n"); - fwrite($fichier, ''); + fwrite($fichier, "\n"); + fwrite($fichier, "<![CDATA[".$summary."]]>\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "global->MAIN_UMASK)) - @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); - } + if ($description) + fwrite($fichier, $description); + // else + // fwrite($fichier, "NoDesc"); + + fwrite($fichier, "]]>\n"); + fwrite($fichier, "".date("r", $startdate)."\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "\n"); + } + } + + fwrite($fichier, ""); + fwrite($fichier, "\n"); + fwrite($fichier, ""); + + fclose($fichier); + + if (! empty($conf->global->MAIN_UMASK)) + { + @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + } } - /** - * Encode for cal export + * Encode for cal export * - * @param string $format vcal or ical - * @param string $string string to encode - * @return string string encoded + * @param string $format "vcal" or "ical" + * @param string $string String to encode + * @return string String encoded */ function format_cal($format, $string) { - global $conf; + global $conf; - $newstring=$string; + $newstring = $string; - if ($format == 'vcal') - { - $newstring=quotedPrintEncode($newstring); - } - if ($format == 'ical') - { - // Replace new lines chars by '\n' - $newstring=preg_replace('/'."\r\n".'/i', "\n", $newstring); - $newstring=preg_replace('/'."\n\r".'/i', "\n", $newstring); - $newstring=preg_replace('/'."\n".'/i', '\n', $newstring); - // Must not exceed 75 char. Cut with "\r\n"+Space - $newstring=calEncode($newstring); - } + if ($format === "vcal") + { + $newstring = quotedPrintEncode($newstring); + } - return $newstring; + if ($format === "ical") + { + // Replace new lines chars by "\n" + $newstring = preg_replace("/"."\r\n"."/i", "\n", $newstring); + $newstring = preg_replace("/"."\n\r"."/i", "\n", $newstring); + $newstring = preg_replace("/"."\n"."/i", "\n", $newstring); + + // Must not exceed 75 char. Cut with "\r\n"+Space + $newstring = calEncode($newstring); + } + + return $newstring; } /** - * Cut string after 75 chars. Add CRLF+Space. - * line must be encoded in UTF-8 + * Cut string after 75 chars. Add CRLF+Space. + * line must be encoded in UTF-8 * - * @param string $line String to convert - * @return string String converted + * @param string $line String to convert + * @return string String converted */ function calEncode($line) { - $out = ''; + $out = ""; + $newpara = ""; - $newpara = ''; + // If mb_ functions exists, it"s better to use them + if (function_exists("mb_strlen")) + { + $strlength = mb_strlen($line, "UTF-8"); - // If mb_ functions exists, it's better to use them - if (function_exists('mb_strlen')) - { - $strlength=mb_strlen($line, 'UTF-8'); - for ($j = 0; $j <= ($strlength - 1); $j++) - { - $char = mb_substr($line, $j, 1, 'UTF-8'); // Take char at position $j + for ($j = 0; $j < $strlength; $j++) + { + // Take char at position $j + $char = mb_substr($line, $j, 1, "UTF-8"); - if ((mb_strlen($newpara, 'UTF-8') + mb_strlen($char, 'UTF-8')) >= 75) - { - $out .= $newpara . "\r\n "; // CRLF + Space for cal - $newpara = ''; - } - $newpara .= $char; - } - $out .= $newpara; - } - else - { - $strlength=dol_strlen($line); - for ($j = 0; $j <= ($strlength - 1); $j++) - { - $char = substr($line, $j, 1); // Take char at position $j + if ((mb_strlen($newpara, "UTF-8") + mb_strlen($char, "UTF-8")) >= 75) + { + // CRLF + Space for cal + $out .= $newpara . "\r\n "; - if ((dol_strlen($newpara) + dol_strlen($char)) >= 75 ) - { - $out .= $newpara . "\r\n "; // CRLF + Space for cal - $newpara = ''; - } - $newpara .= $char; - } - $out .= $newpara; - } + $newpara = ""; + } - return trim($out); + $newpara .= $char; + } + + $out .= $newpara; + } + else + { + $strlength = dol_strlen($line); + + for ($j = 0; $j < $strlength; $j++) + { + // Take char at position $j + $char = substr($line, $j, 1); + + if ((dol_strlen($newpara) + dol_strlen($char)) >= 75 ) + { + // CRLF + Space for cal + $out .= $newpara . "\r\n "; + + $newpara = ""; + } + + $newpara .= $char; + } + + $out .= $newpara; + } + + return trim($out); } /** - * Encode into vcal format + * Encode into vcal format * - * @param string $str String to convert - * @param int $forcal 1=For cal - * @return string String converted + * @param string $str String to convert + * @param int $forcal (optional) 1 = For cal + * @return string String converted */ function quotedPrintEncode($str, $forcal = 0) { - $lines = preg_split("/\r\n/", $str); - $out = ''; + $lines = preg_split("/\r\n/", $str); + $out = ""; - foreach ($lines as $line) - { - $newpara = ''; + foreach ($lines as $line) + { + $newpara = ""; - $strlength=strlen($line); // Do not use dol_strlen here, we need number of bytes - for ($j = 0; $j <= ($strlength - 1); $j++) - { - $char = substr($line, $j, 1); - $ascii = ord($char); + // Do not use dol_strlen here, we need number of bytes + $strlength = strlen($line); - if ( $ascii < 32 || $ascii == 61 || $ascii > 126 ) - $char = '=' . strtoupper(sprintf("%02X", $ascii)); + for ($j = 0; $j < $strlength; $j++) + { + $char = substr($line, $j, 1); + $ascii = ord($char); - if ((strlen($newpara) + strlen($char)) >= 76 ) // Do not use dol_strlen here, we need number of bytes - { - $out .= $newpara . '=' . "\r\n"; // CRLF - if ($forcal) $out .= " "; // + Space for cal - $newpara = ''; - } - $newpara .= $char; - } - $out .= $newpara; - } - return trim($out); + if ( $ascii < 32 || $ascii === 61 || $ascii > 126 ) + { + $char = "=" . strtoupper(sprintf("%02X", $ascii)); + } + + // Do not use dol_strlen here, we need number of bytes + if ((strlen($newpara) + strlen($char)) >= 76 ) + { + // New line with carray-return (CR) and line-feed (LF) + $out .= $newpara . "=" . "\r\n"; + + // extra space for cal + if ($forcal) + $out .= " "; + + $newpara = ""; + } + + $newpara .= $char; + } + + $out .= $newpara; + } + return trim($out); } /** - * Decode vcal format + * Decode vcal format * - * @param string $str String to convert - * @return string String converted + * @param string $str String to convert + * @return string String converted */ function quotedPrintDecode($str) { - $out = preg_replace('/=\r?\n/', '', $str); - $out = quoted_printable_decode($out); // Available with PHP 4+ - return trim($out); + return trim(quoted_printable_decode(preg_replace("/=\r?\n/", "", $str))); } From 2a983a6a7c7cc38b2e686a4c950a1e8e44a87c70 Mon Sep 17 00:00:00 2001 From: "Sekan, Tobias" Date: Fri, 1 Nov 2019 12:09:43 +0100 Subject: [PATCH 2/6] fix link in documentation --- htdocs/core/lib/xcal.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 40656e5c0c4..67a978ec89c 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ From fee0a362adcc5a895407f61944b5b625376c7b5a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 1 Nov 2019 11:11:59 +0000 Subject: [PATCH 3/6] Fixing style errors. --- htdocs/core/lib/xcal.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 67a978ec89c..406601dedf0 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -137,7 +137,7 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) continue; } - fwrite($calfileh,"ATTENDEE;RSVP=TRUE:mailto:".$assignedUser->email."\n"); + fwrite($calfileh, "ATTENDEE;RSVP=TRUE:mailto:".$assignedUser->email."\n"); } } From 885c6e65163cc790b68de763a925af0814949b10 Mon Sep 17 00:00:00 2001 From: "Sekan, Tobias" Date: Fri, 1 Nov 2019 13:16:14 +0100 Subject: [PATCH 4/6] Fix wrong newline replacement --- htdocs/core/lib/xcal.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 67a978ec89c..0b999e7b75a 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -427,9 +427,9 @@ function format_cal($format, $string) if ($format === "ical") { // Replace new lines chars by "\n" - $newstring = preg_replace("/"."\r\n"."/i", "\n", $newstring); - $newstring = preg_replace("/"."\n\r"."/i", "\n", $newstring); - $newstring = preg_replace("/"."\n"."/i", "\n", $newstring); + $newstring = preg_replace("/"."\r\n"."/i", "\\n", $newstring); + $newstring = preg_replace("/"."\n\r"."/i", "\\n", $newstring); + $newstring = preg_replace("/"."\n"."/i", "\\n", $newstring); // Must not exceed 75 char. Cut with "\r\n"+Space $newstring = calEncode($newstring); From 37f4ebb1b2a54b9a411fe456cf056028dfe94246 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 2 Nov 2019 11:56:01 +0100 Subject: [PATCH 5/6] Update xcal.lib.php --- htdocs/core/lib/xcal.lib.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index d1679555c99..6d9fd4dab22 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -112,6 +112,41 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) $category = format_cal($format, $category); $location = format_cal($format, $location); + // Output the vCard/iCal VEVENT object + /* + Example from Google ical export for a 1 hour event: + BEGIN:VEVENT + DTSTART:20101103T120000Z + DTEND:20101103T130000Z + DTSTAMP:20101121T144902Z + UID:4eilllcsq8r1p87ncg7vc8dbpk@google.com + CREATED:20101121T144657Z + DESCRIPTION: + LAST-MODIFIED:20101121T144707Z + LOCATION: + SEQUENCE:0 + STATUS:CONFIRMED + SUMMARY:Tâche 1 heure + TRANSP:OPAQUE + END:VEVENT + + Example from Google ical export for a 1 day event: + BEGIN:VEVENT + DTSTART;VALUE=DATE:20101102 + DTEND;VALUE=DATE:20101103 + DTSTAMP:20101121T144902Z + UID:d09t43kcf1qgapu9efsmmo1m6k@google.com + CREATED:20101121T144607Z + DESCRIPTION: + LAST-MODIFIED:20101121T144607Z + LOCATION: + SEQUENCE:0 + STATUS:CONFIRMED + SUMMARY:Tâche 1 jour + TRANSP:TRANSPARENT + END:VEVENT + */ + if ($type === "event") { fwrite($calfileh, "BEGIN:VEVENT\n"); From b43d06db3714ba04b762a5338b73df64991ed424 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 2 Nov 2019 10:55:24 +0000 Subject: [PATCH 6/6] Fixing style errors. --- htdocs/core/lib/xcal.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 6d9fd4dab22..7e7cbd9672e 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -129,7 +129,7 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) SUMMARY:Tâche 1 heure TRANSP:OPAQUE END:VEVENT - + Example from Google ical export for a 1 day event: BEGIN:VEVENT DTSTART;VALUE=DATE:20101102 @@ -146,7 +146,7 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) TRANSP:TRANSPARENT END:VEVENT */ - + if ($type === "event") { fwrite($calfileh, "BEGIN:VEVENT\n");