xref: /plugin/struct/meta/CSVExporter.php (revision 308cc83fd5391df29d21d2bc1306c8da49fdb335)
1f36cc634SAndreas Gohr<?php
2f36cc634SAndreas Gohr
3f36cc634SAndreas Gohrnamespace dokuwiki\plugin\struct\meta;
4f36cc634SAndreas Gohr
5f36cc634SAndreas Gohr/**
6f36cc634SAndreas Gohr * Class CSVExporter
7f36cc634SAndreas Gohr *
8*308cc83fSAndreas 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{
16ad86a824SAnna Dabrowska    const DATATYPE_PAGE = 'page';
17*308cc83fSAndreas Gohr    const DATATYPE_GLOBAL = 'global';
18ad86a824SAnna Dabrowska    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('*');
36f36cc634SAndreas Gohr        $result = $search->execute();
37f36cc634SAndreas Gohr
38*308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
39f36cc634SAndreas Gohr            $pids = $search->getPids();
4069d92b7aSAnna Dabrowska        }
41f36cc634SAndreas Gohr
42f36cc634SAndreas Gohr        echo $this->header($search->getColumns());
43f36cc634SAndreas Gohr        foreach ($result as $i => $row) {
44*308cc83fSAndreas Gohr            if ($this->type !== self::DATATYPE_GLOBAL) {
45f36cc634SAndreas Gohr                $pid = $pids[$i];
4669d92b7aSAnna Dabrowska            } else {
4769d92b7aSAnna Dabrowska                $pid = '';
4869d92b7aSAnna Dabrowska            }
49f36cc634SAndreas Gohr            echo $this->row($row, $pid);
50f36cc634SAndreas Gohr        }
51f36cc634SAndreas Gohr    }
52f36cc634SAndreas Gohr
53f36cc634SAndreas Gohr    /**
54f36cc634SAndreas Gohr     * Create the header
55f36cc634SAndreas Gohr     *
56f36cc634SAndreas Gohr     * @param Column[] $columns
57f36cc634SAndreas Gohr     * @return string
58f36cc634SAndreas Gohr     */
59d6d97f60SAnna Dabrowska    protected function header($columns)
60d6d97f60SAnna Dabrowska    {
61f36cc634SAndreas Gohr        $row = '';
6269d92b7aSAnna Dabrowska
63*308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
64f36cc634SAndreas Gohr            $row .= $this->escape('pid');
65f36cc634SAndreas Gohr            $row .= ',';
6669d92b7aSAnna Dabrowska        }
67f36cc634SAndreas Gohr
68f36cc634SAndreas Gohr        foreach ($columns as $i => $col) {
69f36cc634SAndreas Gohr            $row .= $this->escape($col->getLabel());
70f36cc634SAndreas Gohr            $row .= ',';
71f36cc634SAndreas Gohr        }
72f36cc634SAndreas Gohr        return rtrim($row, ',') . "\r\n";
73f36cc634SAndreas Gohr    }
74f36cc634SAndreas Gohr
75f36cc634SAndreas Gohr    /**
76f36cc634SAndreas Gohr     * Create one row of data
77f36cc634SAndreas Gohr     *
78f36cc634SAndreas Gohr     * @param Value[] $values
79f36cc634SAndreas Gohr     * @param string $pid pid of this row
80f36cc634SAndreas Gohr     * @return string
81f36cc634SAndreas Gohr     */
82d6d97f60SAnna Dabrowska    protected function row($values, $pid)
83d6d97f60SAnna Dabrowska    {
84f36cc634SAndreas Gohr        $row = '';
85*308cc83fSAndreas Gohr        if ($this->type !== self::DATATYPE_GLOBAL) {
86f36cc634SAndreas Gohr            $row .= $this->escape($pid);
87f36cc634SAndreas Gohr            $row .= ',';
8869d92b7aSAnna Dabrowska        }
89f36cc634SAndreas Gohr
90f36cc634SAndreas Gohr        foreach ($values as $value) {
91f36cc634SAndreas Gohr            /** @var Value $value */
92f36cc634SAndreas Gohr            $val = $value->getRawValue();
93f36cc634SAndreas Gohr            if (is_array($val)) $val = join(',', $val);
94f36cc634SAndreas Gohr
9569d92b7aSAnna Dabrowska            // FIXME check escaping of composite ids (JSON with """")
96f36cc634SAndreas Gohr            $row .= $this->escape($val);
97f36cc634SAndreas Gohr            $row .= ',';
98f36cc634SAndreas Gohr        }
99f36cc634SAndreas Gohr
100f36cc634SAndreas Gohr        return rtrim($row, ',') . "\r\n";
101f36cc634SAndreas Gohr    }
102f36cc634SAndreas Gohr
103f36cc634SAndreas Gohr    /**
104f36cc634SAndreas Gohr     * Escapes and wraps the given string
105f36cc634SAndreas Gohr     *
106f36cc634SAndreas Gohr     * Uses doubled quotes for escaping which seems to be the standard escaping method for CSV
107f36cc634SAndreas Gohr     *
108f36cc634SAndreas Gohr     * @param string $str
109f36cc634SAndreas Gohr     * @return string
110f36cc634SAndreas Gohr     */
111d6d97f60SAnna Dabrowska    protected function escape($str)
112d6d97f60SAnna Dabrowska    {
113f36cc634SAndreas Gohr        return '"' . str_replace('"', '""', $str) . '"';
114f36cc634SAndreas Gohr    }
115f36cc634SAndreas Gohr}
116