xref: /plugin/struct/meta/CSVExporter.php (revision 17a3a5782666ca8742a2c64cc11565d4f9fe1076)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class CSVExporter
7 *
8 * exports raw schema data to CSV.
9 *
10 * Note this is different from syntax/csv.php
11 *
12 * @package dokuwiki\plugin\struct\meta
13 */
14class CSVExporter
15{
16    public const DATATYPE_PAGE = 'page';
17    public const DATATYPE_GLOBAL = 'global';
18    public const DATATYPE_SERIAL = 'serial';
19
20    protected $type = '';
21
22    /**
23     * CSVExporter constructor.
24     *
25     * @param string $table
26     * @param string $type
27     */
28    public function __construct($table, $type)
29    {
30        // TODO make it nicer
31        $this->type = $type;
32
33        $search = new Search();
34        $search->addSchema($table);
35        $search->addColumn('*');
36        $result = $search->execute();
37
38        if ($this->type !== self::DATATYPE_GLOBAL) {
39            $pids = $search->getPids();
40        }
41
42        echo $this->header($search->getColumns());
43        foreach ($result as $i => $row) {
44            if ($this->type !== self::DATATYPE_GLOBAL) {
45                $pid = $pids[$i];
46            } else {
47                $pid = '';
48            }
49            echo $this->row($row, $pid);
50        }
51    }
52
53    /**
54     * Create the header
55     *
56     * @param Column[] $columns
57     * @return string
58     */
59    protected function header($columns)
60    {
61        $row = '';
62
63        if ($this->type !== self::DATATYPE_GLOBAL) {
64            $row .= $this->escape('pid');
65            $row .= ',';
66        }
67
68        foreach ($columns as $i => $col) {
69            $row .= $this->escape($col->getLabel());
70            $row .= ',';
71        }
72        return rtrim($row, ',') . "\r\n";
73    }
74
75    /**
76     * Create one row of data
77     *
78     * @param Value[] $values
79     * @param string $pid pid of this row
80     * @return string
81     */
82    protected function row($values, $pid)
83    {
84        $row = '';
85        if ($this->type !== self::DATATYPE_GLOBAL) {
86            $row .= $this->escape($pid);
87            $row .= ',';
88        }
89
90        foreach ($values as $value) {
91            /** @var Value $value */
92            $val = $value->getRawValue();
93            if (is_array($val)) $val = join(',', $val);
94
95            // FIXME check escaping of composite ids (JSON with """")
96            $row .= $this->escape($val);
97            $row .= ',';
98        }
99
100        return rtrim($row, ',') . "\r\n";
101    }
102
103    /**
104     * Escapes and wraps the given string
105     *
106     * Uses doubled quotes for escaping which seems to be the standard escaping method for CSV
107     *
108     * @param string $str
109     * @return string
110     */
111    protected function escape($str)
112    {
113        return '"' . str_replace('"', '""', $str) . '"';
114    }
115}
116