1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class SchemaImporter
7 *
8 * This works just like the schema builder, except that it expects a JSON structure as input
9 *
10 * @package dokuwiki\plugin\struct\meta
11 */
12class SchemaImporter extends SchemaBuilder
13{
14    /**
15     * Import a schema using JSON
16     *
17     * @param string $table
18     * @param string $json
19     * @todo sanity checking of the input data should be added
20     *
21     */
22    public function __construct($table, $json)
23    {
24        parent::__construct($table, []);
25
26        // number of existing columns
27        $existing = count($this->oldschema->getColumns());
28
29        $input = json_decode($json, true);
30        if ($input === null) {
31            switch (json_last_error()) {
32                case JSON_ERROR_NONE:
33                    $error = 'No errors';
34                    break;
35                case JSON_ERROR_DEPTH:
36                    $error = 'Maximum stack depth exceeded';
37                    break;
38                case JSON_ERROR_STATE_MISMATCH:
39                    $error = 'Underflow or the modes mismatch';
40                    break;
41                case JSON_ERROR_CTRL_CHAR:
42                    $error = 'Unexpected control character found';
43                    break;
44                case JSON_ERROR_SYNTAX:
45                    $error = 'Syntax error, malformed JSON';
46                    break;
47                case JSON_ERROR_UTF8:
48                    $error = 'Malformed UTF-8 characters, possibly incorrectly encoded';
49                    break;
50                default:
51                    $error = 'Unknown error';
52                    break;
53            }
54
55            throw new StructException('JSON couldn\'t be decoded: ' . $error);
56        }
57        $config = $input['config'] ?? [];
58        $data = ['config' => json_encode($config), 'cols' => [], 'new' => []];
59
60        foreach ($input['columns'] as $column) {
61            // config has to stay json
62            $column['config'] = json_encode($column['config'], JSON_PRETTY_PRINT);
63
64            if (!empty($column['colref']) && $column['colref'] <= $existing) {
65                // update existing column
66                $data['cols'][$column['colref']] = $column;
67            } else {
68                // add new column
69                $data['new'][] = $column;
70            }
71        }
72
73        $this->data = $data;
74    }
75}
76