1<?php 2/* Copyright (C) 2006-2008 Laurent Destailleur <eldy@users.sourceforge.net> 3 * Copyright (C) 2012 Marcos García <marcosgdf@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17*/ 18 19/** 20 * \file htdocs/core/modules/export/export_csv.modules.php 21 * \ingroup export 22 * \brief File of class to build export files with format TSV 23 */ 24 25require_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php'; 26 27 28/** 29 * Class to build export files with format TSV 30 */ 31class ExportTsv extends ModeleExports 32{ 33 /** 34 * @var string ID 35 */ 36 public $id; 37 38 /** 39 * @var string label 40 */ 41 public $label; 42 43 public $extension; 44 45 /** 46 * Dolibarr version of the loaded document 47 * @var string 48 */ 49 public $version = 'dolibarr'; 50 51 public $label_lib; 52 53 public $version_lib; 54 55 public $separator = "\t"; 56 57 public $handle; // Handle fichier 58 59 60 /** 61 * Constructor 62 * 63 * @param DoliDB $db Database handler 64 */ 65 public function __construct($db) 66 { 67 global $conf, $langs; 68 $this->db = $db; 69 70 $this->id = 'tsv'; // Same value then xxx in file name export_xxx.modules.php 71 $this->label = 'TSV'; // Label of driver 72 $this->desc = $langs->trans('TsvFormatDesc'); 73 $this->extension = 'tsv'; // Extension for generated file by this driver 74 $this->picto = 'mime/other'; // Picto 75 $this->version = '1.15'; // Driver version 76 77 // If driver use an external library, put its name here 78 $this->label_lib = 'Dolibarr'; 79 $this->version_lib = DOL_VERSION; 80 } 81 82 /** 83 * getDriverId 84 * 85 * @return string 86 */ 87 public function getDriverId() 88 { 89 return $this->id; 90 } 91 92 /** 93 * getDriverLabel 94 * 95 * @return string Return driver label 96 */ 97 public function getDriverLabel() 98 { 99 return $this->label; 100 } 101 102 /** 103 * getDriverDesc 104 * 105 * @return string 106 */ 107 public function getDriverDesc() 108 { 109 return $this->desc; 110 } 111 112 /** 113 * getDriverExtension 114 * 115 * @return string 116 */ 117 public function getDriverExtension() 118 { 119 return $this->extension; 120 } 121 122 /** 123 * getDriverVersion 124 * 125 * @return string 126 */ 127 public function getDriverVersion() 128 { 129 return $this->version; 130 } 131 132 /** 133 * getLibLabel 134 * 135 * @return string 136 */ 137 public function getLibLabel() 138 { 139 return $this->label_lib; 140 } 141 142 /** 143 * getLibVersion 144 * 145 * @return string 146 */ 147 public function getLibVersion() 148 { 149 return $this->version_lib; 150 } 151 152 153 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 154 /** 155 * Open output file 156 * 157 * @param string $file Path of filename to generate 158 * @param Translate $outputlangs Output language object 159 * @return int <0 if KO, >=0 if OK 160 */ 161 public function open_file($file, $outputlangs) 162 { 163 // phpcs:enable 164 global $langs; 165 166 dol_syslog("ExportTsv::open_file file=".$file); 167 168 $ret = 1; 169 170 $outputlangs->load("exports"); 171 $this->handle = fopen($file, "wt"); 172 if (!$this->handle) 173 { 174 $langs->load("errors"); 175 $this->error = $langs->trans("ErrorFailToCreateFile", $file); 176 $ret = -1; 177 } 178 179 return $ret; 180 } 181 182 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 183 /** 184 * Output header into file 185 * 186 * @param Translate $outputlangs Output language object 187 * @return int <0 if KO, >0 if OK 188 */ 189 public function write_header($outputlangs) 190 { 191 // phpcs:enable 192 return 0; 193 } 194 195 196 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 197 /** 198 * Output title line into file 199 * 200 * @param array $array_export_fields_label Array with list of label of fields 201 * @param array $array_selected_sorted Array with list of field to export 202 * @param Translate $outputlangs Object lang to translate values 203 * @param array $array_types Array with types of fields 204 * @return int <0 if KO, >0 if OK 205 */ 206 public function write_title($array_export_fields_label, $array_selected_sorted, $outputlangs, $array_types) 207 { 208 // phpcs:enable 209 foreach ($array_selected_sorted as $code => $value) 210 { 211 $newvalue = $outputlangs->transnoentities($array_export_fields_label[$code]); // newvalue is now $outputlangs->charset_output encoded 212 $newvalue = $this->tsv_clean($newvalue, $outputlangs->charset_output); 213 214 fwrite($this->handle, $newvalue.$this->separator); 215 } 216 fwrite($this->handle, "\n"); 217 return 0; 218 } 219 220 221 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 222 /** 223 * Output record line into file 224 * 225 * @param array $array_selected_sorted Array with list of field to export 226 * @param resource $objp A record from a fetch with all fields from select 227 * @param Translate $outputlangs Object lang to translate values 228 * @param array $array_types Array with types of fields 229 * @return int <0 if KO, >0 if OK 230 */ 231 public function write_record($array_selected_sorted, $objp, $outputlangs, $array_types) 232 { 233 // phpcs:enable 234 global $conf; 235 236 $this->col = 0; 237 foreach ($array_selected_sorted as $code => $value) 238 { 239 if (strpos($code, ' as ') == 0) $alias = str_replace(array('.', '-', '(', ')'), '_', $code); 240 else $alias = substr($code, strpos($code, ' as ') + 4); 241 if (empty($alias)) dol_print_error('', 'Bad value for field with code='.$code.'. Try to redefine export.'); 242 243 $newvalue = $outputlangs->convToOutputCharset($objp->$alias); // objp->$alias must be utf8 encoded as any var in memory // newvalue is now $outputlangs->charset_output encoded 244 $typefield = isset($array_types[$code]) ? $array_types[$code] : ''; 245 246 // Translation newvalue 247 if (preg_match('/^\((.*)\)$/i', $newvalue, $reg)) $newvalue = $outputlangs->transnoentities($reg[1]); 248 249 $newvalue = $this->tsv_clean($newvalue, $outputlangs->charset_output); 250 251 if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7)) 252 { 253 $array = unserialize($typefield); 254 $array = $array['options']; 255 $newvalue = $array[$newvalue]; 256 } 257 258 fwrite($this->handle, $newvalue.$this->separator); 259 $this->col++; 260 } 261 fwrite($this->handle, "\n"); 262 return 0; 263 } 264 265 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 266 /** 267 * Output footer into file 268 * 269 * @param Translate $outputlangs Output language object 270 * @return int <0 if KO, >0 if OK 271 */ 272 public function write_footer($outputlangs) 273 { 274 // phpcs:enable 275 return 0; 276 } 277 278 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 279 /** 280 * Close file handle 281 * 282 * @return int <0 if KO, >0 if OK 283 */ 284 public function close_file() 285 { 286 // phpcs:enable 287 fclose($this->handle); 288 return 0; 289 } 290 291 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 292 /** 293 * Clean a cell to respect rules of TSV file cells 294 * 295 * @param string $newvalue String to clean 296 * @param string $charset Input AND Output character set 297 * @return string Value cleaned 298 */ 299 public function tsv_clean($newvalue, $charset) 300 { 301 // phpcs:enable 302 // Rule Dolibarr: No HTML 303 $newvalue = dol_string_nohtmltag($newvalue, 1, $charset); 304 305 // Rule 1 TSV: No CR, LF in cells 306 $newvalue = str_replace("\r", '', $newvalue); 307 $newvalue = str_replace("\n", '\n', $newvalue); 308 309 // Rule 2 TSV: If value contains tab, we must replace by space 310 if (preg_match('/'.$this->separator.'/', $newvalue)) { 311 $newvalue = str_replace("\t", " ", $newvalue); 312 } 313 314 return $newvalue; 315 } 316} 317