1<?php
2
3// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
4
5/**
6 * CSV export of tabular data generated in Aggregations
7 *
8 * Note: this is different from meta\CSVExporter
9 *
10 * @link https://tools.ietf.org/html/rfc4180
11 * @link http://csvlint.io/
12 */
13class renderer_plugin_struct_csv extends Doku_Renderer
14{
15    protected $first = false;
16
17    /**
18     * Determine if out put is wanted right now
19     *
20     * @return bool
21     */
22    protected function doOutput()
23    {
24        global $INPUT;
25
26        if (
27            !isset($this->info['struct_table_hash']) ||
28            $this->info['struct_table_hash'] != $INPUT->str('hash')
29        ) {
30            return false;
31        }
32
33        if (!empty($this->info['struct_table_meta'])) {
34            return false;
35        }
36
37        return true;
38    }
39
40    /**
41     * Our own format
42     *
43     * @return string
44     */
45    public function getFormat()
46    {
47        return 'struct_csv';
48    }
49
50    /**
51     * Set proper headers
52     */
53    public function document_start()
54    {
55        global $ID;
56        $filename = noNS($ID ?? 'data') . '.csv';
57        $headers = [
58            'Content-Type' => 'text/csv',
59            'Content-Disposition' => 'attachment; filename="' . $filename . '";'
60        ];
61        p_set_metadata($ID, ['format' => ['struct_csv' => $headers]]);
62        // don't cache
63        $this->nocache();
64    }
65
66    /**
67     * Opening a table row prevents the separator for the first following cell
68     */
69    public function tablerow_open()
70    {
71        if (!$this->doOutput()) return;
72        $this->first = true;
73    }
74
75    /**
76     * Output the delimiter (unless it's the first cell of this row) and the text wrapper
77     *
78     * @param int $colspan ignored
79     * @param null $align ignored
80     * @param int $rowspan ignored
81     *
82     */
83    public function tablecell_open($colspan = 1, $align = null, $rowspan = 1)
84    {
85        if (!$this->doOutput()) return;
86        if (!$this->first) {
87            $this->doc .= ",";
88        }
89        $this->first = false;
90
91        $this->doc .= '"';
92    }
93
94    /**
95     * Close the text wrapper
96     */
97    public function tablecell_close()
98    {
99        if (!$this->doOutput()) return;
100        $this->doc .= '"';
101    }
102
103    /**
104     * Alias for tablecell_open
105     *
106     * @param int $colspan ignored
107     * @param null $align ignored
108     * @param int $rowspan ignored
109     */
110    public function tableheader_open($colspan = 1, $align = null, $rowspan = 1)
111    {
112        $this->tablecell_open($colspan, $align, $rowspan);
113    }
114
115    /**
116     * Alias for tablecell_close
117     */
118    public function tableheader_close()
119    {
120        $this->tablecell_close();
121    }
122
123    /**
124     * Add CRLF newline at the end of one line
125     */
126    public function tablerow_close()
127    {
128        if (!$this->doOutput()) return;
129        $this->doc .= "\r\n";
130    }
131
132    /**
133     * Outputs cell content
134     *
135     * @param string $text
136     */
137    public function cdata($text)
138    {
139        if (!$this->doOutput()) return;
140        if ($text === '') return;
141
142        $this->doc .= str_replace('"', '""', $text);
143    }
144
145
146    #region overrides using cdata for output
147
148    public function internallink($link, $title = null)
149    {
150        if (is_null($title) || is_array($title) || $title == '') {
151            $title = $this->_simpleTitle($link);
152        }
153        $this->cdata($title);
154    }
155
156    public function externallink($link, $title = null)
157    {
158        if (is_null($title) || is_array($title) || $title == '') {
159            $title = $link;
160        }
161        $this->cdata($title);
162    }
163
164    public function emaillink($address, $name = null)
165    {
166        $this->cdata($address);
167    }
168
169    public function plugin($name, $args, $state = '', $match = '')
170    {
171        if (substr($name, 0, 7) == 'struct_') {
172            parent::plugin($name, $args, $state, $match);
173        } else {
174            $this->cdata($match);
175        }
176    }
177
178    public function acronym($acronym)
179    {
180        $this->cdata($acronym);
181    }
182
183    public function code($text, $lang = null, $file = null)
184    {
185        $this->cdata($text);
186    }
187
188    public function header($text, $level, $pos)
189    {
190        $this->cdata($text);
191    }
192
193    public function linebreak()
194    {
195        $this->cdata("\r\n");
196    }
197
198    public function unformatted($text)
199    {
200        $this->cdata($text);
201    }
202
203    public function php($text)
204    {
205        $this->cdata($text);
206    }
207
208    public function phpblock($text)
209    {
210        $this->cdata($text);
211    }
212
213    public function html($text)
214    {
215        $this->cdata($text);
216    }
217
218    public function htmlblock($text)
219    {
220        $this->cdata($text);
221    }
222
223    public function preformatted($text)
224    {
225        $this->cdata($text);
226    }
227
228    public function file($text, $lang = null, $file = null)
229    {
230        $this->cdata($text);
231    }
232
233    public function smiley($smiley)
234    {
235        $this->cdata($smiley);
236    }
237
238    public function entity($entity)
239    {
240        $this->cdata($entity);
241    }
242
243    public function multiplyentity($x, $y)
244    {
245        $this->cdata($x . 'x' . $y);
246    }
247
248    public function locallink($hash, $name = null)
249    {
250        if (is_null($name) || is_array($name) || $name == '') {
251            $name = $hash;
252        }
253        $this->cdata($name);
254    }
255
256    public function interwikilink($link, $title, $wikiName, $wikiUri)
257    {
258        if (is_array($title) || $title == '') {
259            $title = $wikiName . '>' . $link;
260        }
261        $this->cdata($title);
262    }
263
264    public function filelink($link, $title = null)
265    {
266        if (is_null($title) || is_array($title) || $title == '') {
267            $title = $link;
268        }
269        $this->cdata($title);
270    }
271
272    public function windowssharelink($link, $title = null)
273    {
274        if (is_null($title) || is_array($title) || $title == '') {
275            $title = $link;
276        }
277        $this->cdata($title);
278    }
279
280    public function internalmedia(
281        $src,
282        $title = null,
283        $align = null,
284        $width = null,
285        $height = null,
286        $cache = null,
287        $linking = null
288    ) {
289        $this->cdata($src);
290    }
291
292    public function externalmedia(
293        $src,
294        $title = null,
295        $align = null,
296        $width = null,
297        $height = null,
298        $cache = null,
299        $linking = null
300    ) {
301        $this->cdata($src);
302    }
303
304    public function internalmedialink(
305        $src,
306        $title = null,
307        $align = null,
308        $width = null,
309        $height = null,
310        $cache = null
311    ) {
312        $this->cdata($src);
313    }
314
315    public function externalmedialink(
316        $src,
317        $title = null,
318        $align = null,
319        $width = null,
320        $height = null,
321        $cache = null
322    ) {
323        $this->cdata($src);
324    }
325
326    #endregion
327}
328