Commit 131cda76 authored by Chenu Denis's avatar Chenu Denis

[feature] Allow to choose delimiter, enclosure … for csv export. Default to real CSV

parent dd0c36a7
<?php
/**
* CsvFixedWriter
*
* @author Denis Chenu <denis@sondages.pro>
* @copyright 2018 Denis Chenu <http://www.sondages.pro>
* @license GPL v3
* @version 0.0.0
*
* 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.
*/
class CsvFixedWriter extends Writer
{
/* @var string */
public $delimiter = ",";
/* @var string */
public $enclosure = '"';
/* @var string */
public $escapechar = "\\";
/* @var boolean */
public $striptag;
/* @var boolean|string */
public $stripnewline;
/* @var boolean */
public $addnewline;
/* @var string */
private $output;
/* @var boolean */
private $hasOutputHeader;
/**
* Output file, can be a file or php://output
* @var string (with scheme)
**/
private $file = null;
/**
* The filename to use for the resulting file when output = display
* @var string
*/
protected $csvFilename = '';
/**
* Should headers be output? For example spss and r export use more or less
* the same output but do not need headers at all.
*
* @var boolean
*/
protected $doHeaders = true;
function __construct()
{
$this->output = '';
$this->hasOutputHeader = false;
}
public function init(SurveyObj $survey, $sLanguageCode, FormattingOptions $oOptions)
{
parent::init($survey, $sLanguageCode, $oOptions);
$this->csvFilename = "results-survey".$survey->id.".csv";
if ($oOptions->output == 'file') {
$this->output = 'file';
$this->file = fopen($this->filename, 'w');
} else {
header("Content-Disposition: attachment; filename=".$this->csvFilename);
header("Content-type: text/comma-separated-values; charset=UTF-8");
$this->file = fopen('php://output', 'w');
}
}
protected function outputRecord($headers, $values, FormattingOptions $oOptions)
{
$sRecord = '';
if (!$this->hasOutputHeader) {
fwrite($this->file, chr(239) . chr(187) . chr(191)); // Write UTF-8 Byte Order Mark (BOM) for … MS
// If we don't want headers in our csv, for example in exports like r/spss etc. we suppress the header by setting this switch in the init
if ($this->doHeaders === true) {
$index = 0;
foreach ($headers as $header) {
$headers[$index] = $this->updateValues($header);
$index++;
}
//Output the header...once and only once.
fputcsv($this->file,$headers,$this->delimiter,$this->enclosure,$this->escapechar);
}
$this->hasOutputHeader = true;
}
//Output the values.
$index = 0;
foreach ($values as $value) {
$values[$index] = $this->updateValues($value);
$index++;
}
fputcsv($this->file,$values,$this->delimiter,$this->enclosure,$this->escapechar);
}
public function close()
{
// Output white line at the end, better for R import
if($this->addnewline) {
fwrite($this->file, "\r\n"); // Seemls to be for R and spss
}
fclose($this->file);
}
/**
* Returns the value with all necessary escaping needed to place it into a CSV string.
*
* @param string $value
* @return string
*/
protected function updateValues($string)
{
$string = preg_replace(array('~\R~u'), array("\n"), $string);
if($this->striptag || $this->stripnewline) {
$string = str_replace("\n"," ", $string);
}
if($this->striptag) {
$string = preg_replace('@<script[^>]*?>.*?</script>@si', '', $string);
$string = strip_tags($string);
}
return $string;
}
}
<?php
/**
* exportCsvConfigurable
*
* @author Denis Chenu <denis@sondages.pro>
* @copyright 2018 Denis Chenu <http://www.sondages.pro>
* @license GPL v3
* @version 0.0.0
*
* 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.
*/
class exportCsvFixed extends PluginBase
{
protected $storage = 'DbStorage';
static protected $name = 'exportCsvFixed';
static protected $description = 'Allow to configure some csv options globally.';
protected $settings = array(
'replace'=>array(
'type'=>'boolean',
'label'=>'Replace exiting csv',
'default'=>1,
),
'asdefault'=>array(
'type'=>'boolean',
'label'=>'Set to default (if not replace)',
'default'=>1,
),
'delimiter'=>array(
'type'=>'select',
'options'=>array(
',' => "Comma (real csv)",
';' => "Semicolon",
"\t" => "Tabulation",
),
'label'=>'Separator',
'default'=>"\t",
),
'enclosure'=>array(
'type'=>'select',
'options'=>array(
'"' => "Double quote",
'\'' => "Simple quote",
),
'label'=>'Enclosure',
'default'=>'"',
),
'striptag'=>array(
'type'=>'boolean',
'label'=>'Strip tag and javascript',
'default'=>0,
'help'=>"This strip new line",
),
'stripnewline'=>array(
'type'=>'select',
'options'=>array(
//'survey' => "On survey text (not for user entered tex)",
'always' => "Yes (always)",
),
'htmlOptions' => array(
'empty'=> "No"
),
'label'=>'Strip new line',
'default'=>'',
),
'addnewline'=>array(
'type'=>'boolean',
'label'=>'Add a new line at end of CSV file',
'default'=>0,
),
);
public function init() {
$this->subscribe('listExportPlugins');
$this->subscribe('listExportOptions');
$this->subscribe('newExport');
}
public function listExportOptions()
{
$event = $this->getEvent();
$type = $event->get('type');
$label = $this->gT("fixed csv");
if($this->get('replace',null,null,$this->settings['replace']['default'])) {
$label = $this->gT("CSV");
}
switch ($type) {
case 'csv-fixed':
$event->set('label',$label);
if($this->get('replace',null,null,$this->settings['replace']['default']) || $this->get('asdefault',null,null,$this->settings['asdefault']['default'])) {
$event->set('default', true);
}
default:
break;
}
}
/**
* Registers this export type
*/
public function listExportPlugins()
{
$event = $this->getEvent();
$exports = $event->get('exportplugins');
$newExport=array('csv'=>$exports['csv'],'csv-fixed'=>get_class());
if($this->get('replace',null,null,$this->settings['replace']['default'])) {
$newExport=array('csv-fixed'=>get_class());
}
unset($exports['csv']);
$exports=$newExport+$exports;
$event->set('exportplugins', $exports);
}
public function newExport()
{
$event = $this->getEvent();
$type = $event->get('type');
switch ($type) {
case 'csv-fixed':
$writer = new CsvFixedWriter();
$writer->delimiter=$this->get('delimiter',null,null,$this->settings['delimiter']['default']);
$writer->enclosure=$this->get('enclosure',null,null,$this->settings['enclosure']['default']);
$writer->striptag=$this->get('striptag',null,null,$this->settings['striptag']['default']);
$writer->stripnewline=$this->get('stripnewline',null,null,$this->settings['stripnewline']['default']);
$writer->addnewline=$this->get('addnewline',null,null,$this->settings['addnewline']['default']);
$event->set('writer', $writer);
break;
default:
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment