ldapsaisie/src/includes/class/class.LSioFormatCSV.php
Benjamin Renard 9907e08f18 Code cleaning
2021-08-25 18:02:37 +02:00

248 lines
7.3 KiB
PHP

<?php
/*******************************************************************************
* Copyright (C) 2007 Easter-eggs
* https://ldapsaisie.org
*
* Author: See AUTHORS file in top-level directory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
******************************************************************************/
LSsession :: loadLSclass('LSioFormatDriver');
/**
* Driver to manage CSV ioFormat file of LSldapObject import/export
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSioFormatCSV extends LSioFormatDriver {
private $delimiter = null;
private $enclosure = null;
private $escape = null;
private $length = null;
private $rows = null;
private $headers = null;
/**
* Constructor
*
* @param[in] array $options Driver's options
*
* @retval void
**/
public function __construct($options) {
parent :: __construct($options);
// As recommend in PHP doc, we enable this ini parameter to allow detection of
// Macintosh line-ending convention.
ini_set("auto_detect_line_endings", true);
// Set CSV input/output parameters
$this -> delimiter = $this -> getOption('delimiter', ",", "string");
$this -> enclosure = $this -> getOption('enclosure', '"', "string");
$this -> escape = $this -> getOption('escape', "\\", "string");
$this -> length = $this -> getOption('length', 0, "int");
$this -> multiple_value_delimiter = $this -> getOption('multiple_value_delimiter', '|', "string");
self :: log_debug(
'New LSioFormatCSV objet started with delimiter="'.$this -> delimiter.'", '.
'enclosure = <'.$this -> enclosure.'>, escape = "'.$this -> escape.'", '.
'length = '.$this -> length.' and multiple value delimiter = "'.
$this -> multiple_value_delimiter.'"'
);
}
/**
* Load file
*
* @param[in] string $file The file path to load
*
* @retval boolean True if file is loaded, false otherwise
**/
public function loadFile($path) {
self :: log_debug("loadFile($path)");
$fd = fopen($path, 'r');
if ($fd === false) {
self :: log_error("Fail to open file '$path'.");
return false;
}
$this -> rows = array();
while (
(
$row = fgetcsv(
$fd, $this -> length, $this -> delimiter,
$this -> enclosure, $this -> escape
)
) !== FALSE) {
$this -> rows[] = $row;
}
if (!$this -> rows)
return false;
$this -> headers = array_shift($this -> rows);
self :: log_trace("loadFile($path): headers = ".varDump($this -> headers));
self :: log_debug("loadFile($path): ".count($this -> rows)." row(s) loaded.");
return true;
}
/**
* Check if loaded file data are valid
*
* @retval boolean True if loaded file data are valid, false otherwise
**/
public function isValid() {
if (!is_array($this -> rows) && empty($this -> rows)) {
self :: log_error("No data loaded from input file");
return false;
}
if (!$this -> headers) {
self :: log_error("Header line seem empty");
return false;
}
for($i = 0; $i < count($this -> rows); $i++) {
if (count($this -> rows[$i]) != count($this -> headers)) {
self :: log_error(
"Input row #$i contain ".count($this -> rows[$i])." field(s) when ".
"headers has ".count($this -> headers)
);
return false;
}
}
self :: log_debug("isValid(): all ".count($this -> rows)." row(s) are symetric.");
return True;
}
/**
* Retrieve all object data contained by the loaded file
*
* The objects are returned in array :
*
* array (
* array ( // Object 1
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* array ( // Object 2
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* )
*
* @retval array The objects contained by the loaded file
**/
public function getAll() {
$objects = array();
foreach($this -> rows as $row) {
$object = array();
foreach ($this -> headers as $idx => $key) {
$values = explode($this -> multiple_value_delimiter, $row[$idx]);
$object[$key] = (count($values) == 1?$values[0]:$values);
}
$objects[] = $object;
}
self :: log_trace("getAll(): objects = ".varDump($objects));
return $objects;
}
/**
* Retrieve fields names of the loaded file
*
* The fields names are returned in array :
*
* array (
* '[field1]',
* '[field2]',
* [...]
* )
*
* @retval array The fields names of the loaded file
**/
public function getFieldNames() {
return $this -> headers;
}
/**
* Export objects data
*
* @param[in] $stream The stream where objects's data have to be exported
* @param[in] $objects_data Array of objects data to export
* @param[in] $stream resource|null The output stream (optional, default: STDOUT)
*
* @return boolean True on success, False otherwise
*/
public function exportObjectsData($objects_data, $stream=null) {
if (!function_exists('fputcsv')) {
LSerror :: addErrorCode('LSioFormatCSV_01');
return false;
}
$stdout = false;
if (is_null($stream)) {
$stream = fopen('php://temp/maxmemory:'. (5*1024*1024), 'w+');
$stdout = true;
}
$first = true;
foreach($objects_data as $dn => $object_data) {
if ($first) {
$this -> writeRow($stream, array_keys($object_data));
$first = false;
}
$row = array();
foreach($object_data as $values)
$row[] = (is_array($values)?implode($this -> multiple_value_delimiter, $values):$values);
$this -> writeRow($stream, $row);
}
if (!$stdout)
return true;
header("Content-disposition: attachment; filename=export.csv");
header("Content-type: text/csv");
rewind($stream);
print stream_get_contents($stream);
@fclose($stream);
exit();
}
/**
* Write CSV row to stream
*
* @param[in] $stream The CSV file description reference
* @param[in] $row An array of a CSV row fields to write
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @retval boolean True if CSV row is successfully writed, false in other case
*/
private function writeRow($stream, $row) {
// Escape character could only be specified since php 5.5.4
if (!defined('PHP_VERSION_ID') or PHP_VERSION_ID < 50504) {
$result = fputcsv($stream, $row, $this -> delimiter, $this -> enclosure);
}
else {
$result = fputcsv($stream, $row, $this -> delimiter, $this -> enclosure, $this -> escape);
}
return ($result !== false);
}
}
LSerror :: defineError('LSioFormatCSV_01',
___("LSioFormatCSV: function fputcsv is not available.")
);