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