xref: /plugin/struct/meta/CSVExporter.php (revision ba7f5789bbbcab95d7a655f6ec50a97b731b40d5)
1f36cc634SAndreas Gohr<?php
2f36cc634SAndreas Gohr
3f36cc634SAndreas Gohrnamespace dokuwiki\plugin\struct\meta;
4f36cc634SAndreas Gohr
5f36cc634SAndreas Gohr/**
6f36cc634SAndreas Gohr * Class CSVExporter
7f36cc634SAndreas Gohr *
8308cc83fSAndreas Gohr * exports raw schema data to CSV.
9f36cc634SAndreas Gohr *
10f36cc634SAndreas Gohr * Note this is different from syntax/csv.php
11f36cc634SAndreas Gohr *
12f36cc634SAndreas Gohr * @package dokuwiki\plugin\struct\meta
13f36cc634SAndreas Gohr */
14d6d97f60SAnna Dabrowskaclass CSVExporter
15d6d97f60SAnna Dabrowska{
1617a3a578SAndreas Gohr    public const DATATYPE_PAGE = 'page';
1717a3a578SAndreas Gohr    public const DATATYPE_GLOBAL = 'global';
1817a3a578SAndreas Gohr    public const DATATYPE_SERIAL = 'serial';
19ad86a824SAnna Dabrowska
2069d92b7aSAnna Dabrowska    protected $type = '';
2169d92b7aSAnna Dabrowska
22f36cc634SAndreas Gohr    /**
2369d92b7aSAnna Dabrowska     * CSVExporter constructor.
24f36cc634SAndreas Gohr     *
25f36cc634SAndreas Gohr     * @param string $table
2669d92b7aSAnna Dabrowska     * @param string $type
27f36cc634SAndreas Gohr     */
2869d92b7aSAnna Dabrowska    public function __construct($table, $type)
29d6d97f60SAnna Dabrowska    {
3069d92b7aSAnna Dabrowska        // TODO make it nicer
3169d92b7aSAnna Dabrowska        $this->type = $type;
32f36cc634SAndreas Gohr
33f36cc634SAndreas Gohr        $search = new Search();
34f36cc634SAndreas Gohr        $search->addSchema($table);
35f36cc634SAndreas Gohr        $search->addColumn('*');
367234bfb1Ssplitbrain
37*ba7f5789SAnna Dabrowska        $result = $search->getRows();
38f36cc634SAndreas Gohr
39308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
40f36cc634SAndreas Gohr            $pids = $search->getPids();
4169d92b7aSAnna Dabrowska        }
42f36cc634SAndreas Gohr
43f36cc634SAndreas Gohr        echo $this->header($search->getColumns());
44f36cc634SAndreas Gohr        foreach ($result as $i => $row) {
45308cc83fSAndreas Gohr            if ($this->type !== self::DATATYPE_GLOBAL) {
46f36cc634SAndreas Gohr                $pid = $pids[$i];
4769d92b7aSAnna Dabrowska            } else {
4869d92b7aSAnna Dabrowska                $pid = '';
4969d92b7aSAnna Dabrowska            }
50f36cc634SAndreas Gohr            echo $this->row($row, $pid);
51f36cc634SAndreas Gohr        }
52f36cc634SAndreas Gohr    }
53f36cc634SAndreas Gohr
54f36cc634SAndreas Gohr    /**
55f36cc634SAndreas Gohr     * Create the header
56f36cc634SAndreas Gohr     *
57f36cc634SAndreas Gohr     * @param Column[] $columns
58f36cc634SAndreas Gohr     * @return string
59f36cc634SAndreas Gohr     */
60d6d97f60SAnna Dabrowska    protected function header($columns)
61d6d97f60SAnna Dabrowska    {
62f36cc634SAndreas Gohr        $row = '';
6369d92b7aSAnna Dabrowska
64308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
65f36cc634SAndreas Gohr            $row .= $this->escape('pid');
66f36cc634SAndreas Gohr            $row .= ',';
6769d92b7aSAnna Dabrowska        }
68f36cc634SAndreas Gohr
697234bfb1Ssplitbrain        foreach ($columns as $col) {
70f36cc634SAndreas Gohr            $row .= $this->escape($col->getLabel());
71f36cc634SAndreas Gohr            $row .= ',';
72f36cc634SAndreas Gohr        }
73f36cc634SAndreas Gohr        return rtrim($row, ',') . "\r\n";
74f36cc634SAndreas Gohr    }
75f36cc634SAndreas Gohr
76f36cc634SAndreas Gohr    /**
77f36cc634SAndreas Gohr     * Create one row of data
78f36cc634SAndreas Gohr     *
79f36cc634SAndreas Gohr     * @param Value[] $values
80f36cc634SAndreas Gohr     * @param string $pid pid of this row
81f36cc634SAndreas Gohr     * @return string
82f36cc634SAndreas Gohr     */
83d6d97f60SAnna Dabrowska    protected function row($values, $pid)
84d6d97f60SAnna Dabrowska    {
85f36cc634SAndreas Gohr        $row = '';
86308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
87f36cc634SAndreas Gohr            $row .= $this->escape($pid);
88f36cc634SAndreas Gohr            $row .= ',';
8969d92b7aSAnna Dabrowska        }
90f36cc634SAndreas Gohr
91f36cc634SAndreas Gohr        foreach ($values as $value) {
92f36cc634SAndreas Gohr            /** @var Value $value */
93f36cc634SAndreas Gohr            $val = $value->getRawValue();
947234bfb1Ssplitbrain            if (is_array($val)) $val = implode(',', $val);
95f36cc634SAndreas Gohr
9669d92b7aSAnna Dabrowska            // FIXME check escaping of composite ids (JSON with """")
97f36cc634SAndreas Gohr            $row .= $this->escape($val);
98f36cc634SAndreas Gohr            $row .= ',';
99f36cc634SAndreas Gohr        }
100f36cc634SAndreas Gohr
101f36cc634SAndreas Gohr        return rtrim($row, ',') . "\r\n";
102f36cc634SAndreas Gohr    }
103f36cc634SAndreas Gohr
104f36cc634SAndreas Gohr    /**
105f36cc634SAndreas Gohr     * Escapes and wraps the given string
106f36cc634SAndreas Gohr     *
107f36cc634SAndreas Gohr     * Uses doubled quotes for escaping which seems to be the standard escaping method for CSV
108f36cc634SAndreas Gohr     *
109f36cc634SAndreas Gohr     * @param string $str
110f36cc634SAndreas Gohr     * @return string
111f36cc634SAndreas Gohr     */
112d6d97f60SAnna Dabrowska    protected function escape($str)
113d6d97f60SAnna Dabrowska    {
114f36cc634SAndreas Gohr        return '"' . str_replace('"', '""', $str) . '"';
115f36cc634SAndreas Gohr    }
116f36cc634SAndreas Gohr}
117