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 = isset($input['config']) ? $input['config'] : array();
58        $data = array(
59            'config' => json_encode($config),
60            'cols' => array(),
61            'new' => array(),
62        );
63
64        foreach ($input['columns'] as $column) {
65            // config has to stay json
66            $column['config'] = json_encode($column['config'], JSON_PRETTY_PRINT);
67
68            if (!empty($column['colref']) && $column['colref'] <= $existing) {
69                // update existing column
70                $data['cols'][$column['colref']] = $column;
71            } else {
72                // add new column
73                $data['new'][] = $column;
74            }
75        }
76
77        $this->data = $data;
78    }
79}
80