xref: /plugin/struct/meta/CSVPageImporter.php (revision 34f483db1909585e6a5d5e29b3b904424f3660d1)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4use dokuwiki\plugin\struct\types\Page;
5
6class CSVPageImporter extends CSVImporter {
7
8    protected $importedPids = array();
9
10    /**
11     * Chceck if schema is page schema
12     *
13     * @throws StructException
14     * @param string $table
15     * @param string $file
16     */
17    public function __construct($table, $file) {
18        parent::__construct($table, $file);
19
20        if($this->schema->isLookup()) throw new StructException($table.' is not a page schema');
21    }
22
23    /**
24     * Import page schema only when the pid header is present.
25     */
26    protected function readHeaders() {
27
28        //add pid to struct
29        $pageType = new Page(null, 'pid');
30        $this->columns[] = new Column(0, $pageType);
31
32        parent::readHeaders();
33
34        if(!in_array('pid', $this->header)) throw new StructException('There is no "pid" header in the CSV. Schema not imported.');
35    }
36
37    /**
38     * Creates the insert string for the single value table
39     *
40     * @return string
41     */
42    protected function getSQLforAllValues() {
43        $colnames = array();
44        foreach($this->columns as $i => $col) {
45            $colnames[] = 'col' . $col->getColref();
46        }
47        //replace first column with pid
48        $colnames[0] = 'pid';
49        //insert rev at the end
50        $colnames[] = 'rev';
51
52        $placeholds = join(', ', array_fill(0, count($colnames), '?'));
53        $colnames = join(', ', $colnames);
54        $table = $this->schema->getTable();
55
56        return "INSERT INTO data_$table ($colnames, latest) VALUES ($placeholds, 1)";
57    }
58
59    /**
60     * Add the revision.
61     *
62     * @param string[] $values
63     * @param          $line
64     * @param string   $single
65     * @param string   $multi
66     */
67    protected function saveLine($values, $line, $single, $multi) {
68        //create new page revision
69        $pid = $values[0];
70        $helper = plugin_load('helper', 'struct');
71        $revision = $helper->createPageRevision($pid, 'CSV data imported');
72        p_get_metadata($pid); // reparse the metadata of the page top update the titles/rev/lasteditor table
73
74        // make sure this schema is assigned
75        /** @noinspection PhpUndefinedVariableInspection */
76        Assignments::getInstance()->assignPageSchema(
77            $pid,
78            $this->schema->getTable()
79        );
80
81        //add page revision to values
82        $values[] = $revision;
83
84        parent::saveLine($values, $line, $single, $multi);
85    }
86
87    /**
88     * In the paga schemas primary key is a touple of (pid, rev)
89     *
90     * @param string[] $values
91     * @param string   $single
92     * @return array(pid, rev)
93     */
94    protected function insertIntoSingle($values, $single) {
95        $pid = $values[0];
96        $rev = $values[count($values) - 1];
97
98        //update latest
99        $table = $this->schema->getTable();
100        $this->sqlite->query("UPDATE data_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid));
101
102        //insert into table
103        parent::insertIntoSingle($values, $single);
104
105        //primary key is touple of (pid, rev)
106        return array($pid, $rev);
107    }
108
109    /**
110     * Add pid and rev to insert query parameters
111     *
112     * @param string $multi
113     * @param string $pk
114     * @param string $column
115     * @param string $row
116     * @param string $value
117     */
118    protected function insertIntoMulti($multi, $pk, $column, $row, $value) {
119        list($pid, $rev) = $pk;
120
121        //update latest
122        $table = $this->schema->getTable();
123        $this->sqlite->query("UPDATE multi_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid));
124
125        $this->sqlite->query($multi, array($pid, $rev, $column->getColref(), $row + 1, $value));
126    }
127
128    /**
129     * In page schemas we use REPLACE instead of INSERT to prevent ambiguity
130     *
131     * @return string
132     */
133    protected function getSQLforMultiValue() {
134        $table = $this->schema->getTable();
135        /** @noinspection SqlResolve */
136        return "INSERT INTO multi_$table (pid, rev, colref, row, value, latest) VALUES (?,?,?,?,?,1)";
137    }
138
139    /**
140     * Check if page id realy exists
141     *
142     * @param Column $col
143     * @param mixed  $rawvalue
144     * @return bool
145     */
146    protected function validateValue(Column $col, &$rawvalue) {
147        //check if page id exists and schema is bounded to the page
148        if($col->getLabel() == 'pid') {
149            $pid = cleanID($rawvalue);
150            if (isset($this->importedPids[$pid])) {
151                $this->errors[] = 'Page "'.$pid.'" already imported. Skipping the row.';
152                return false;
153            }
154            if(page_exists($pid)) {
155                $this->importedPids[$pid] = true;
156                return true;
157            }
158            $this->errors[] = 'Page "'.$pid.'" does not exists. Skipping the row.';
159            return false;
160        }
161
162        return parent::validateValue($col, $rawvalue);
163    }
164}
165