ExportRenderer::valToCsvHelper()   B
last analyzed

Complexity

Conditions 8
Paths 16

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 16
nop 3
dl 0
loc 28
rs 8.4444
c 0
b 0
f 0
1
<?php namespace XoopsModules\Smartobject;
2
3
/*
4
 * You may not change or alter any portion of this comment or credits
5
 * of supporting developers from this source code or any supporting source code
6
 * which is considered copyrighted (c) material of the original comment or credit authors.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/**
14
 * @copyright    XOOPS Project https://xoops.org/
15
 * @license      GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
16
 * @package
17
 * @since
18
 * @author     XOOPS Development Team
19
 */
20
21
use XoopsModules\Smartobject;
22
23
/**
24
 * Contains the classes for easily exporting data
25
 *
26
 * @license GNU
27
 * @author  marcan <[email protected]>
28
 * @link    http://www.smartfactory.ca The SmartFactory
29
 * @package SmartObject
30
 */
31
32
33
/**
34
 * SmartExportRenderer class
35
 *
36
 * Class that renders a set of data into a specific export format
37
 *
38
 * @package SmartObject
39
 * @author  marcan <[email protected]>
40
 * @link    http://www.smartfactory.ca The SmartFactory
41
 */
42
class ExportRenderer
43
{
44
    public $data;
45
    public $format;
46
    public $filename;
47
    public $filepath;
48
    public $options;
49
50
    /**
51
     * Constructor
52
     *
53
     * @param array       $data     contains the data to be exported
54
     * @param bool|string $filename name of the file in which the exported data will be saved
55
     * @param bool|string $filepath path where the file will be saved
56
     * @param string      $format   format of the ouputed export. Currently only supports CSV
57
     * @param array       $options  options of the format to be exported in
58
     */
59
    public function __construct(
60
        $data,
61
        $filename = false,
62
        $filepath = false,
63
        $format = 'csv',
64
        $options = ['separator' => ';']
65
    ) {
66
        $this->data     = $data;
67
        $this->format   = $format;
68
        $this->filename = $filename;
69
        $this->filepath = $filepath;
70
        $this->options  = $options;
71
    }
72
73
    /**
74
     * @param         $dataArray
75
     * @param         $separator
76
     * @param  string $trim
77
     * @param  bool   $removeEmptyLines
78
     * @return string
79
     */
80
    public function arrayToCsvString($dataArray, $separator, $trim = 'both', $removeEmptyLines = true)
0 ignored issues
show
Unused Code introduced by
The parameter $removeEmptyLines is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
81
    {
82
        if (!is_array($dataArray) || empty($dataArray)) {
83
            return '';
84
        }
85
        switch ($trim) {
86
            case 'none':
87
                $trimFunction = false;
88
                break;
89
            case 'left':
90
                $trimFunction = 'ltrim';
91
                break;
92
            case 'right':
93
                $trimFunction = 'rtrim';
94
                break;
95
            default: //'both':
96
                $trimFunction = 'trim';
97
                break;
98
        }
99
        $ret = [];
100
        foreach ($dataArray as $key => $field) {
101
            $ret[$key] = $this->valToCsvHelper($field, $separator, $trimFunction);
102
        }
103
104
        return implode($separator, $ret);
105
    }
106
107
    /**
108
     * @param $val
109
     * @param $separator
110
     * @param $trimFunction
111
     * @return mixed|string
112
     */
113
    public function valToCsvHelper($val, $separator, $trimFunction)
114
    {
115
        if ($trimFunction) {
116
            $val = $trimFunction($val);
117
        }
118
        //If there is a separator (;) or a quote (") or a linebreak in the string, we need to quote it.
119
        $needQuote = false;
120
        do {
121
            if (false !== strpos($val, '"')) {
122
                $val       = str_replace('"', '""', $val);
123
                $needQuote = true;
124
                break;
125
            }
126
            if (false !== strpos($val, $separator)) {
127
                $needQuote = true;
128
                break;
129
            }
130
            if ((false !== strpos($val, "\n")) || (false !== strpos($val, "\r"))) { // \r is for mac
131
                $needQuote = true;
132
                break;
133
            }
134
        } while (false);
135
        if ($needQuote) {
136
            $val = '"' . $val . '"';
137
        }
138
139
        return $val;
140
    }
141
142
    public function execute()
143
    {
144
        $exportFileData = '';
145
146
        switch ($this->format) {
147
            case 'csv':
148
                $separator      = isset($this->options['separator']) ? $this->options['separator'] : ';';
149
                $firstRow       = implode($separator, $this->data['columnsHeaders']);
150
                $exportFileData .= $firstRow . "\r\n";
151
152
                foreach ($this->data['rows'] as $cols) {
153
                    $exportFileData .= $this->arrayToCsvString($cols, $separator) . "\r\n";
154
                }
155
                break;
156
        }
157
        $this->saveExportFile($exportFileData);
158
    }
159
160
    /**
161
     * @param $content
162
     */
163
    public function saveExportFile($content)
164
    {
165
        switch ($this->format) {
166
            case 'csv':
167
                $this->saveCsv($content);
168
                break;
169
        }
170
    }
171
172
    /**
173
     * @param $content
174
     */
175
    public function saveCsv($content)
176
    {
177
        if (!$this->filepath) {
178
            $this->filepath = XOOPS_UPLOAD_PATH . '/';
179
        }
180
        if (!$this->filename) {
181
            $this->filename .= time();
182
            $this->filename .= '.csv';
183
        }
184
185
        $fullFileName = $this->filepath . $this->filename;
186
187
        if (!$handle = fopen($fullFileName, 'a+')) {
188
            trigger_error('Unable to open ' . $fullFileName, E_USER_WARNING);
189
        } elseif (false === fwrite($handle, $content)) {
190
            trigger_error('Unable to write in ' . $fullFileName, E_USER_WARNING);
191
        } else {
192
            $mimeType  = 'text/csv';
193
            $file      = strrev($this->filename);
194
            $temp_name = strtolower(strrev(substr($file, 0, strpos($file, '--'))));
195
            if ('' === $temp_name) {
196
                $file_name = $this->filename;
197
            } else {
198
                $file_name = $temp_name;
199
            }
200
            $fullFileName = $this->filepath . stripslashes(trim($this->filename));
201
202
            if (ini_get('zlib.output_compression')) {
203
                ini_set('zlib.output_compression', 'Off');
204
            }
205
206
            header('Pragma: public');
207
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
208
            header('Cache-Control: private', false);
209
            header('Content-Transfer-Encoding: binary');
210
            if (isset($mimeType)) {
211
                header('Content-Type: ' . $mimeType);
212
            }
213
214
            header('Content-Disposition: attachment; filename=' . $file_name);
215
216
            if (isset($mimeType) && false !== strpos($mimeType, 'text/')) {
217
                $fp = fopen($fullFileName, 'r');
218
            } else {
219
                $fp = fopen($fullFileName, 'rb');
220
            }
221
            fpassthru($fp);
222
            exit();
223
        }
224
        fclose($handle);
225
    }
226
}
227