xref: /plugin/struct/meta/Schema.php (revision 750a393b38a130546e68f22d86ab591a22bbc7a6)
1<?php
2
3namespace plugin\struct\meta;
4
5use dokuwiki\Form\Form;
6use plugin\struct\types\AbstractBaseType;
7use plugin\struct\types\Text;
8
9/**
10 * Class Schema
11 *
12 * Represents the schema of a single data table and all its properties. It defines what can be stored in
13 * the represented data table and how those contents are formatted.
14 *
15 * It can be initialized with a timestamp to access the schema as it looked at that particular point in time.
16 *
17 * @package plugin\struct\meta
18 */
19class Schema {
20
21    /** @var \helper_plugin_sqlite|null */
22    protected $sqlite;
23
24    /** @var int The ID of this schema */
25    protected $id = 0;
26
27    /** @var string name of the associated table */
28    protected $table = '';
29
30    /**
31     * @var string the current checksum of this schema
32     */
33    protected $chksum = '';
34
35    /** @var Column[] all the colums */
36    protected $columns = array();
37
38    /** @var int */
39    protected $maxsort = 0;
40
41    /** @var int */
42    protected $ts = 0;
43
44    /**
45     * Schema constructor
46     *
47     * @param string $table The table this schema is for
48     * @param int $ts The timestamp for when this schema was valid, 0 for current
49     */
50    public function __construct($table, $ts = 0) {
51        /** @var \helper_plugin_struct_db $helper */
52        $helper = plugin_load('helper', 'struct_db');
53        $this->sqlite = $helper->getDB();
54        if(!$this->sqlite) return;
55
56        $table = self::cleanTableName($table);
57        $this->table = $table;
58        $this->ts = $ts;
59
60        // load info about the schema itself
61        if($ts) {
62            $sql = "SELECT *
63                      FROM schemas
64                     WHERE tbl = ?
65                       AND ts <= ?
66                  ORDER BY ts DESC
67                     LIMIT 1";
68            $opt = array($table, $ts);
69
70        } else {
71            $sql = "SELECT *
72                      FROM schemas
73                     WHERE tbl = ?
74                  ORDER BY ts DESC
75                     LIMIT 1";
76            $opt = array($table);
77        }
78        $res = $this->sqlite->query($sql, $opt);
79        if($this->sqlite->res2count($res)) {
80            $schema = $this->sqlite->res2arr($res);
81            $result = array_shift($schema);
82            $this->id = $result['id'];
83            $this->chksum = $result['chksum'];
84
85        }
86        $this->sqlite->res_close($res);
87        if(!$this->id) return;
88
89        // load existing columns
90        $sql = "SELECT SC.*, T.*
91                  FROM schema_cols SC,
92                       types T
93                 WHERE SC.sid = ?
94                   AND SC.tid = T.id
95              ORDER BY SC.sort";
96        $res = $this->sqlite->query($sql, $this->id);
97        $rows = $this->sqlite->res2arr($res);
98        $this->sqlite->res_close($res);
99
100        foreach($rows as $row) {
101            $class = 'plugin\\struct\\types\\' . $row['class'];
102            $config = json_decode($row['config'], true);
103            $this->columns[$row['colref']] =
104                new Column(
105                    $row['sort'],
106                    new $class($config, $row['label'], $row['ismulti'], $row['tid']),
107                    $row['colref'],
108                    $row['enabled']
109                );
110
111            if($row['sort'] > $this->maxsort) $this->maxsort = $row['sort'];
112        }
113    }
114
115    /**
116     * Cleans any unwanted stuff from table names
117     *
118     * @param string $table
119     * @return string
120     */
121    static public function cleanTableName($table) {
122        $table = strtolower($table);
123        $table = preg_replace('/[^a-z0-9_]+/', '', $table);
124        $table = preg_replace('/^[0-9_]+/', '', $table);
125        $table = trim($table);
126        return $table;
127    }
128
129    /**
130     * @return string
131     */
132    public function getChksum() {
133        return $this->chksum;
134    }
135
136    /**
137     * @return int
138     */
139    public function getId() {
140        return $this->id;
141    }
142
143    /**
144     * Returns a list of columns in this schema
145     *
146     * @param bool $withDisabled if false, disabled columns will not be returned
147     * @return Column[]
148     */
149    public function getColumns($withDisabled = true) {
150        if(!$withDisabled) {
151            return array_filter(
152                $this->columns,
153                function (Column $col) {
154                    return $col->isEnabled();
155                }
156            );
157        }
158
159        return $this->columns;
160    }
161
162    /**
163     * @return string
164     */
165    public function getTable() {
166        return $this->table;
167    }
168
169    /**
170     * @return int the highest sort number used in this schema
171     */
172    public function getMaxsort() {
173        return $this->maxsort;
174    }
175
176}
177