From ba648f8a856d022e3c0ce3086db00522b9bbf117 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Oct 2008 02:03:26 +0000 Subject: [PATCH] ical export now support utf8 --- htdocs/actioncomm.class.php | 64 ++++++++-------- htdocs/comm/action/agendaexport.php | 16 ++-- htdocs/langs/en_US/agenda.lang | 1 + htdocs/langs/fr_FR/agenda.lang | 1 + htdocs/lib/xcal.lib.php | 115 ++++++++++++++++++---------- htdocs/translate.class.php | 6 +- 6 files changed, 122 insertions(+), 81 deletions(-) diff --git a/htdocs/actioncomm.class.php b/htdocs/actioncomm.class.php index b918b9924c0..ccd41ce7b17 100644 --- a/htdocs/actioncomm.class.php +++ b/htdocs/actioncomm.class.php @@ -547,18 +547,18 @@ class ActionComm /** - \brief Export fichier cal depuis base webcalendar - \param format 'ical' or 'vcal' - \param type 'event' or 'journal' - \param cachedelay Do not rebuild file if date older than cachedelay seconds - \param filename Force filename - \param filters Array of filters - \return int <0 if error, nb of events in new file if ok - */ + * \brief Export events from database into a cal file. + * \param format 'ical' or 'vcal' + * \param type 'event' or 'journal' + * \param cachedelay Do not rebuild file if date older than cachedelay seconds + * \param filename Force filename + * \param filters Array of filters + * \return int <0 if error, nb of events in new file if ok + */ function build_exportfile($format,$type,$cachedelay,$filename,$filters) { global $conf,$langs,$dolibarr_main_url_root; - + require_once (DOL_DOCUMENT_ROOT ."/lib/xcal.lib.php"); dolibarr_syslog("ActionComm::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".sizeof($filters), LOG_DEBUG); @@ -592,12 +592,12 @@ class ActionComm $eventarray=array(); $sql = "SELECT a.id,"; - $sql.= " ".$this->db->pdate("a.datep")." as datep,"; - $sql.= " ".$this->db->pdate("a.datep2")." as datep2,"; - //$sql.= " ".$this->db->pdate("a.datea")." as datea,"; - //$sql.= " ".$this->db->pdate("a.datea2")." as datea2,"; + $sql.= " a.datep,"; + $sql.= " a.datep2,"; + //$sql.= " datea,"; + //$sql.= " datea2,"; $sql.= " a.durationp, a.durationa,"; - $sql.= " ".$this->db->pdate("a.datec")." as datec, tms as datem,"; + $sql.= " a.datec, tms as datem,"; $sql.= " a.note, a.label, a.fk_action as type_id,"; $sql.= " a.fk_soc,"; $sql.= " a.fk_user_author, a.fk_user_mod,"; @@ -644,13 +644,15 @@ class ActionComm $sql.= " AND a.fk_user_done = ".$userforfilter->id; } } - $sql.= " AND a.datep != 'null' "; // To exclude corrupted events and avoid errors in lightning/sunbird import + $sql.= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import + //$sql.= " AND a.datep != 'null'"; // To exclude corrupted events and avoid errors in lightning/sunbird import $sql.= " ORDER by datep"; dolibarr_syslog("ActionComm::build_exportfile select events sql=".$sql); $resql=$this->db->query($sql); if ($resql) { + // Note: Output of sql request is encoded in $conf->character_set_client while ($obj=$this->db->fetch_object($resql)) { $qualified=true; @@ -662,19 +664,20 @@ class ActionComm //$datestart=$obj->datea?$obj->datea:$obj->datep; //$dateend=$obj->datea2?$obj->datea2:$obj->datep2; //$duration=$obj->durationa?$obj->durationa:$obj->durationp; - $datestart=$obj->datep; - $dateend=$obj->datep2; + $datestart=dolibarr_stringtotime($obj->datep); + //print $datestart.'x'; exit; + $dateend=dolibarr_stringtotime($obj->datep2); $duration=$obj->durationp; - $event['summary']=$obj->label; - $event['desc']=$obj->note; + $event['summary']=$langs->convToOutputCharset($obj->label); + $event['desc']=$langs->convToOutputCharset($obj->note); $event['startdate']=$datestart; $event['duration']=$duration; // Not required with type 'journal' $event['enddate']=$dateend; // Not required with type 'journal' $event['author']=$obj->fk_user_author; $event['priority']=$obj->priority; - $event['location']=$obj->location; + $event['location']=$langs->convToOutputCharset($obj->location); $event['transparency']='TRANSPARENT'; // TRANSPARENT or OPAQUE - $event['category']=$obj->libelle; // libelle type action + $event['category']=$langs->convToOutputCharset($obj->libelle); // libelle type action $url=$dolibarr_main_url_root; if (! eregi('\/$',$url)) $url.='/'; $url.='comm/action/fiche.php?id='.$obj->id; @@ -695,23 +698,24 @@ class ActionComm $langs->load("agenda"); - // Write file + // Define title and desc $more=''; - if ($login) $more=$langs->transnoentities("User").' '.$login; - if ($logina) $more=$langs->transnoentities("ActionsAskedBy").' '.$logina; - if ($logint) $more=$langs->transnoentities("ActionsToDoBy").' '.$logint; - if ($logind) $more=$langs->transnoentities("ActionsDoneBy").' '.$logind; + if ($login) $more=$langs->transnoentities("User").' '.$langs->convToOutputCharset($login); + if ($logina) $more=$langs->transnoentities("ActionsAskedBy").' '.$langs->convToOutputCharset($logina); + if ($logint) $more=$langs->transnoentities("ActionsToDoBy").' '.$langs->convToOutputCharset($logint); + if ($logind) $more=$langs->transnoentities("ActionsDoneBy").' '.$langs->convToOutputCharset($logind); if ($more) { - $title='Dolibarr actions - '.$more; - $desc=$more.' - built by Dolibarr'; + $title=$langs->convToOutputCharset('Dolibarr actions - ').$more; + $desc=$more.$langs->convToOutputCharset(' - built by Dolibarr'); } else { - $title='Dolibarr actions'; - $desc=$langs->transnoentities('ListOfActions').' - built by Dolibarr'; + $title=$langs->convToOutputCharset('Dolibarr actions'); + $desc=$langs->transnoentities('ListOfActions').$langs->convToOutputCharset(' - built by Dolibarr'); } + // Write file if ($format == 'ical') $result=build_calfile($format,$title,$desc,$eventarray,$outputfile); if ($format == 'vcal') $result=build_calfile($format,$title,$desc,$eventarray,$outputfile); if ($format == 'rss') $result=build_rssfile($format,$title,$desc,$eventarray,$outputfile); diff --git a/htdocs/comm/action/agendaexport.php b/htdocs/comm/action/agendaexport.php index 34d07f223f9..76a3605de8b 100644 --- a/htdocs/comm/action/agendaexport.php +++ b/htdocs/comm/action/agendaexport.php @@ -103,15 +103,15 @@ if ($format == 'ical' || $format == 'vcal') $result=$agenda->build_exportfile($format,$type,0,$filename,$filters); if ($result >= 0) { - $encoding='UTF-8'; $attachment = true; $type='text/calendar'; //$type='text/plain'; // OK //$attachment = false; // OK - if ($encoding) header('Content-Encoding: '.$encoding); - if ($type) header('Content-Type: '.$type); - if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); + $outputencoding='UTF-8'; + if ($outputencoding) header('Content-Encoding: '.$outputencoding); + if ($type) header('Content-Type: '.$type); + if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); // Ajout directives pour resoudre bug IE //header('Cache-Control: Public, must-revalidate'); @@ -132,15 +132,15 @@ if ($format == 'rss') $result=$agenda->build_exportfile($format,$type,0,$filename,$filters); if ($result >= 0) { - $encoding='iso-8859-1'; $attachment = false; $type='application/rss+xml'; //$type='text/plain'; // OK //$attachment = false; // OK - if ($encoding) header('Content-Encoding: '.$encoding); - if ($type) header('Content-Type: '.$type); - if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); + $outputencoding='UTF-8'; + if ($outputencoding) header('Content-Encoding: '.$outputencoding); + if ($type) header('Content-Type: '.$type); + if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); // Ajout directives pour resoudre bug IE //header('Cache-Control: Public, must-revalidate'); diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 228aa93e2c8..a965088c8f1 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -8,6 +8,7 @@ Calendars = Calendars AffectedTo = Affected to DoneBy = Done by Events = Events +ListOfActions=List of events Location=Location SearchAnAction = Search an action/task MenuToDoActions = All uncomplete actions diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 460f4e10f93..171cd8f36ff 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -8,6 +8,7 @@ Calendars=Calendriers AffectedTo=Affecté à DoneBy=Réalisé par Events=Evênements +ListOfActions=Liste des évênements Location=Lieu SearchAnAction=Rechercher une action/tache MenuToDoActions=Les actions incomplètes diff --git a/htdocs/lib/xcal.lib.php b/htdocs/lib/xcal.lib.php index 05b71673f9c..b8c3115c3d5 100644 --- a/htdocs/lib/xcal.lib.php +++ b/htdocs/lib/xcal.lib.php @@ -24,34 +24,41 @@ */ /** - \brief Build a file from an array of events - \param format 'vcal' or 'ical' - \param title Title of export - \param desc Description of export - \param events_array Array of events ('eid','startdate','duration','enddate','title','summary','category','email','url','desc','author') - \param outputfile Output file - \param filter Filter - \return int <0 if ko, Nb of events in file if ok -*/ + * \brief Build a file from an array of events + * \param format 'vcal' or 'ical' + * \param title Title of export + * \param desc Description of export + * \param events_array Array of events ('eid','startdate','duration','enddate','title','summary','category','email','url','desc','author') + * \param outputfile Output file + * \param filter Filter + * \return int <0 if ko, Nb of events in file if ok + * \remarks All input params and data must be encoded in $conf->charset_output + */ function build_calfile($format='vcal',$title,$desc,$events_array,$outputfile,$filter='') { + global $langs; + dolibarr_syslog("xcal.lib.php::build_calfile Build cal file ".$outputfile." to format ".$format); if (empty($outputfile)) return -1; + // Note: A cal file is an UTF8 encoded file $calfileh=fopen($outputfile,'w'); if ($calfileh) { $now=mktime(); + $encoding=''; + if ($format == 'vcal') $encoding='ENCODING=QUOTED-PRINTABLE:'; + // 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,"CALSCALE:GREGORIAN\n"); - fwrite($calfileh,"X-WR-CALNAME:".utf8_encode($title)."\n"); - fwrite($calfileh,"X-WR-CALDESC:".utf8_encode($desc)."\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"); foreach ($events_array as $date => $event) @@ -93,9 +100,6 @@ function build_calfile($format='vcal',$title,$desc,$events_array,$outputfile,$fi $category=format_cal($format,$category); $location=format_cal($format,$location); - $encoding=''; - if ($format == 'vcal') $encoding='ENCODING=QUOTED-PRINTABLE:'; - // Output the vCard/iCal VEVENT object if ($type == 'event') { @@ -212,15 +216,16 @@ function build_calfile($format='vcal',$title,$desc,$events_array,$outputfile,$fi } /** - \brief Build a file from an array of events - \param format 'rss' - \param title Title of export - \param desc Description of export - \param events_array Array of events ('uid','startdate','summary','url','desc','author','category') - \param outputfile Output file - \param filter Filter - \return int <0 if ko, Nb of events in file if ok -*/ + * \brief Build a file from an array of events + * \param format 'rss' + * \param title Title of export + * \param desc Description of export + * \param events_array Array of events ('uid','startdate','summary','url','desc','author','category') + * \param outputfile Output file + * \param filter Filter + * \return int <0 if ko, Nb of events in file if ok + * \remarks All input data must be encoded in $conf->charset_output + */ function build_rssfile($format='rss',$title,$desc,$events_array,$outputfile,$filter='') { global $user,$conf,$langs; @@ -236,7 +241,7 @@ function build_rssfile($format='rss',$title,$desc,$events_array,$outputfile,$fil $date=date("r"); // Print header - $html=''; + $html='charset_output.'"?>'; fwrite($fichier, $html); fwrite($fichier, "\n"); $html=''; @@ -320,11 +325,21 @@ function build_rssfile($format='rss',$title,$desc,$events_array,$outputfile,$fil } - +/** + * \brief Encode for cal export + * \param format vcal or ical + * \param string string to encode + * \return string string encoded + * \remarks string must be encoded in conf->character_set_client + */ function format_cal($format,$string) { - $newstring=$string; + global $conf; + if ($conf->character_set_client == 'ISO-8859-1') $newstring=utf8_encode($string); + else $newstring=$string; + + // Now newstring is always UTF8 string if ($format == 'vcal') { $newstring=QPEncode($newstring); @@ -343,30 +358,50 @@ function format_cal($format,$string) } /** - \brief Cut string after 75 chars. Add CRLF+Space. - \param string String to convert - \return string String converted + * \brief Cut string after 75 chars. Add CRLF+Space. + * \param string String to convert + * \return string String converted + * \remarks line must be encoded in UTF-8 */ function CalEncode($line) { $out = ''; $newpara = ''; - - for ($j = 0; $j <= strlen($line) - 1; $j++) + + // If mb_ functions exists, it's better to use them + if (function_exists('mb_strlen')) { - $char = substr ( $line, $j, 1 ); - - if ( ( strlen ( $newpara ) + strlen ( $char ) ) >= 75 ) + for ($j = 0; $j <= mb_strlen($line, 'UTF-8') - 1; $j++) { - $out .= $newpara . "\r\n "; // CRLF + Space for cal - $newpara = ''; + $char = mb_substr ( $line, $j, 1, 'UTF-8' ); // Take char at position $j + + if ( ( mb_strlen ( $newpara, 'UTF-8') + mb_strlen ( $char, 'UTF-8' ) ) >= 75 ) + { + $out .= $newpara . "\r\n "; // CRLF + Space for cal + $newpara = ''; + } + $newpara .= $char; } - $newpara .= $char; + $out .= $newpara; } - $out .= $newpara; - - return utf8_encode(trim($out)); + else + { + for ($j = 0; $j <= strlen($line) - 1; $j++) + { + $char = substr ( $line, $j, 1 ); // Take char at position $j + + if ( ( strlen ( $newpara ) + strlen ( $char ) ) >= 75 ) + { + $out .= $newpara . "\r\n "; // CRLF + Space for cal + $newpara = ''; + } + $newpara .= $char; + } + $out .= $newpara; + } + + return trim($out); } diff --git a/htdocs/translate.class.php b/htdocs/translate.class.php index 468257b8885..b693f50941c 100644 --- a/htdocs/translate.class.php +++ b/htdocs/translate.class.php @@ -424,10 +424,10 @@ class Translate { /** - * \brief Convert a string into output charset (this->charset_output) - * \param str chaine a convertir + * \brief Convert a string into output charset (this->charset_output that should be defined to conf->character_set_client) + * \param str String to convert * \param pagecodefrom Page code of src string - * \return string chaine traduite + * \return string Converted string */ function convToOutputCharset($str,$pagecodefrom='UTF-8') {