1083afc55SAndreas Gohr<?php 2083afc55SAndreas Gohr 3ba766201SAndreas Gohrnamespace dokuwiki\plugin\struct\meta; 4d486d6d7SAndreas Gohr 5ba766201SAndreas Gohruse dokuwiki\plugin\struct\types\AbstractBaseType; 6083afc55SAndreas Gohr 745560cc7SAndreas Gohrif(!defined('JSON_PRETTY_PRINT')) define('JSON_PRETTY_PRINT', 0); // PHP 5.3 compatibility 845560cc7SAndreas Gohr 97182938bSAndreas Gohr/** 107182938bSAndreas Gohr * Class Schema 117182938bSAndreas Gohr * 127182938bSAndreas Gohr * Represents the schema of a single data table and all its properties. It defines what can be stored in 137182938bSAndreas Gohr * the represented data table and how those contents are formatted. 147182938bSAndreas Gohr * 157182938bSAndreas Gohr * It can be initialized with a timestamp to access the schema as it looked at that particular point in time. 167182938bSAndreas Gohr * 17ba766201SAndreas Gohr * @package dokuwiki\plugin\struct\meta 187182938bSAndreas Gohr */ 19083afc55SAndreas Gohrclass Schema { 20083afc55SAndreas Gohr 21083afc55SAndreas Gohr /** @var \helper_plugin_sqlite|null */ 22083afc55SAndreas Gohr protected $sqlite; 23083afc55SAndreas Gohr 24083afc55SAndreas Gohr /** @var int The ID of this schema */ 25083afc55SAndreas Gohr protected $id = 0; 26083afc55SAndreas Gohr 27fa7b96aaSMichael Grosse /** @var string the user who last edited this schema */ 28fa7b96aaSMichael Grosse protected $user = ''; 29fa7b96aaSMichael Grosse 30083afc55SAndreas Gohr /** @var string name of the associated table */ 31083afc55SAndreas Gohr protected $table = ''; 32083afc55SAndreas Gohr 3388b7d2aaSAndreas Gohr /** @var bool is this a lookup schema? */ 3488b7d2aaSAndreas Gohr protected $islookup = false; 3588b7d2aaSAndreas Gohr 36083afc55SAndreas Gohr /** 37083afc55SAndreas Gohr * @var string the current checksum of this schema 38083afc55SAndreas Gohr */ 39083afc55SAndreas Gohr protected $chksum = ''; 40083afc55SAndreas Gohr 411c502704SAndreas Gohr /** @var Column[] all the colums */ 42083afc55SAndreas Gohr protected $columns = array(); 43083afc55SAndreas Gohr 44083afc55SAndreas Gohr /** @var int */ 45083afc55SAndreas Gohr protected $maxsort = 0; 46083afc55SAndreas Gohr 47250c83c2SAndreas Gohr /** @var int */ 48250c83c2SAndreas Gohr protected $ts = 0; 49250c83c2SAndreas Gohr 50d486d6d7SAndreas Gohr /** @var string struct version info */ 51d486d6d7SAndreas Gohr protected $structversion = '?'; 52d486d6d7SAndreas Gohr 53*127d6bacSMichael Große /** @var array config array with label translations */ 54*127d6bacSMichael Große protected $config = array(); 55e2c90eebSAndreas Gohr 56083afc55SAndreas Gohr /** 57083afc55SAndreas Gohr * Schema constructor 587182938bSAndreas Gohr * 59083afc55SAndreas Gohr * @param string $table The table this schema is for 60083afc55SAndreas Gohr * @param int $ts The timestamp for when this schema was valid, 0 for current 6188b7d2aaSAndreas Gohr * @param bool $islookup only used when creating a new schema, makes the new schema a lookup 62083afc55SAndreas Gohr */ 6388b7d2aaSAndreas Gohr public function __construct($table, $ts = 0, $islookup = false) { 64*127d6bacSMichael Große $baseconfig = array('allowed editors' => ''); 65*127d6bacSMichael Große 66083afc55SAndreas Gohr /** @var \helper_plugin_struct_db $helper */ 67083afc55SAndreas Gohr $helper = plugin_load('helper', 'struct_db'); 68d486d6d7SAndreas Gohr $info = $helper->getInfo(); 69d486d6d7SAndreas Gohr $this->structversion = $info['date']; 70083afc55SAndreas Gohr $this->sqlite = $helper->getDB(); 71083afc55SAndreas Gohr $table = self::cleanTableName($table); 72083afc55SAndreas Gohr $this->table = $table; 73250c83c2SAndreas Gohr $this->ts = $ts; 74083afc55SAndreas Gohr 75083afc55SAndreas Gohr // load info about the schema itself 76083afc55SAndreas Gohr if($ts) { 77083afc55SAndreas Gohr $sql = "SELECT * 78083afc55SAndreas Gohr FROM schemas 79083afc55SAndreas Gohr WHERE tbl = ? 80083afc55SAndreas Gohr AND ts <= ? 81083afc55SAndreas Gohr ORDER BY ts DESC 82083afc55SAndreas Gohr LIMIT 1"; 83083afc55SAndreas Gohr $opt = array($table, $ts); 84083afc55SAndreas Gohr } else { 85083afc55SAndreas Gohr $sql = "SELECT * 86083afc55SAndreas Gohr FROM schemas 87083afc55SAndreas Gohr WHERE tbl = ? 88083afc55SAndreas Gohr ORDER BY ts DESC 89083afc55SAndreas Gohr LIMIT 1"; 90083afc55SAndreas Gohr $opt = array($table); 91083afc55SAndreas Gohr } 92083afc55SAndreas Gohr $res = $this->sqlite->query($sql, $opt); 93*127d6bacSMichael Große $config = array(); 94083afc55SAndreas Gohr if($this->sqlite->res2count($res)) { 954e2abec0SMichael Große $schema = $this->sqlite->res2arr($res); 964e2abec0SMichael Große $result = array_shift($schema); 97083afc55SAndreas Gohr $this->id = $result['id']; 98fa7b96aaSMichael Grosse $this->user = $result['user']; 99083afc55SAndreas Gohr $this->chksum = $result['chksum']; 10088b7d2aaSAndreas Gohr $this->islookup = $result['islookup']; 101587e314dSAndreas Gohr $this->ts = $result['ts']; 102*127d6bacSMichael Große $config = json_decode($result['config'], true); 10388b7d2aaSAndreas Gohr } else { 10488b7d2aaSAndreas Gohr $this->islookup = $islookup; 105083afc55SAndreas Gohr } 106083afc55SAndreas Gohr $this->sqlite->res_close($res); 107*127d6bacSMichael Große $this->config = array_merge($baseconfig, $config); 108*127d6bacSMichael Große $this->initTransConfig(); 109083afc55SAndreas Gohr if(!$this->id) return; 110083afc55SAndreas Gohr 111083afc55SAndreas Gohr // load existing columns 112083afc55SAndreas Gohr $sql = "SELECT SC.*, T.* 113083afc55SAndreas Gohr FROM schema_cols SC, 114083afc55SAndreas Gohr types T 1151c502704SAndreas Gohr WHERE SC.sid = ? 1161c502704SAndreas Gohr AND SC.tid = T.id 117083afc55SAndreas Gohr ORDER BY SC.sort"; 1181c502704SAndreas Gohr $res = $this->sqlite->query($sql, $this->id); 119083afc55SAndreas Gohr $rows = $this->sqlite->res2arr($res); 120083afc55SAndreas Gohr $this->sqlite->res_close($res); 121083afc55SAndreas Gohr 122636c8abaSAndreas Gohr $typeclasses = Column::allTypes(); 123083afc55SAndreas Gohr foreach($rows as $row) { 124328db41bSAndreas Gohr if($row['class'] == 'Integer') { 125328db41bSAndreas Gohr $row['class'] = 'Decimal'; 126328db41bSAndreas Gohr } 127328db41bSAndreas Gohr 128636c8abaSAndreas Gohr $class = $typeclasses[$row['class']]; 12998eaa57dSAndreas Gohr if(!class_exists($class)) { 13098eaa57dSAndreas Gohr // This usually never happens, except during development 13198eaa57dSAndreas Gohr msg('Unknown type "' . hsc($row['class']) . '" falling back to Text', -1); 132ba766201SAndreas Gohr $class = 'dokuwiki\\plugin\\struct\\types\\Text'; 13398eaa57dSAndreas Gohr } 13498eaa57dSAndreas Gohr 135083afc55SAndreas Gohr $config = json_decode($row['config'], true); 136bbf3d6aaSAndreas Gohr /** @var AbstractBaseType $type */ 137bbf3d6aaSAndreas Gohr $type = new $class($config, $row['label'], $row['ismulti'], $row['tid']); 138bbf3d6aaSAndreas Gohr $column = new Column( 1391c502704SAndreas Gohr $row['sort'], 140bbf3d6aaSAndreas Gohr $type, 1411c502704SAndreas Gohr $row['colref'], 14263d51bbfSAndreas Gohr $row['enabled'], 14363d51bbfSAndreas Gohr $table 1441c502704SAndreas Gohr ); 145bbf3d6aaSAndreas Gohr $type->setContext($column); 1461c502704SAndreas Gohr 1477629557eSAndreas Gohr $this->columns[] = $column; 148083afc55SAndreas Gohr if($row['sort'] > $this->maxsort) $this->maxsort = $row['sort']; 149083afc55SAndreas Gohr } 150083afc55SAndreas Gohr } 151083afc55SAndreas Gohr 152083afc55SAndreas Gohr /** 153*127d6bacSMichael Große * Add the translatable keys to the configuration 154*127d6bacSMichael Große * 155*127d6bacSMichael Große * This checks if a configuration for the translation plugin exists and if so 156*127d6bacSMichael Große * adds all configured languages to the config array. 157*127d6bacSMichael Große * 158*127d6bacSMichael Große * Adapted from @see \dokuwiki\plugin\struct\types\AbstractBaseType::initTransConfig 159*127d6bacSMichael Große */ 160*127d6bacSMichael Große protected function initTransConfig() { 161*127d6bacSMichael Große global $conf; 162*127d6bacSMichael Große $lang = $conf['lang']; 163*127d6bacSMichael Große if(isset($conf['plugin']['translation']['translations'])) { 164*127d6bacSMichael Große $lang .= ' ' . $conf['plugin']['translation']['translations']; 165*127d6bacSMichael Große } 166*127d6bacSMichael Große $langs = explode(' ', $lang); 167*127d6bacSMichael Große $langs = array_map('trim', $langs); 168*127d6bacSMichael Große $langs = array_filter($langs); 169*127d6bacSMichael Große $langs = array_unique($langs); 170*127d6bacSMichael Große 171*127d6bacSMichael Große if(!isset($this->config['label'])) $this->config['label'] = array(); 172*127d6bacSMichael Große // initialize missing keys 173*127d6bacSMichael Große foreach($langs as $lang) { 174*127d6bacSMichael Große if(!isset($this->config['label'][$lang])) $this->config['label'][$lang] = ''; 175*127d6bacSMichael Große } 176*127d6bacSMichael Große // strip unknown languages 177*127d6bacSMichael Große foreach(array_keys($this->config['label']) as $key) { 178*127d6bacSMichael Große if(!in_array($key, $langs)) unset($this->config['label'][$key]); 179*127d6bacSMichael Große } 180*127d6bacSMichael Große } 181*127d6bacSMichael Große 182*127d6bacSMichael Große /** 18367641668SAndreas Gohr * @return string identifer for debugging purposes 18467641668SAndreas Gohr */ 18567641668SAndreas Gohr function __toString() { 18667641668SAndreas Gohr return __CLASS__ . ' ' . $this->table . ' (' . $this->id . ') ' . ($this->islookup ? 'LOOKUP' : 'DATA'); 18767641668SAndreas Gohr } 18867641668SAndreas Gohr 18967641668SAndreas Gohr /** 190083afc55SAndreas Gohr * Cleans any unwanted stuff from table names 191083afc55SAndreas Gohr * 192083afc55SAndreas Gohr * @param string $table 193083afc55SAndreas Gohr * @return string 194083afc55SAndreas Gohr */ 195083afc55SAndreas Gohr static public function cleanTableName($table) { 1962af472dcSAndreas Gohr $table = strtolower($table); 197083afc55SAndreas Gohr $table = preg_replace('/[^a-z0-9_]+/', '', $table); 198083afc55SAndreas Gohr $table = preg_replace('/^[0-9_]+/', '', $table); 199083afc55SAndreas Gohr $table = trim($table); 200083afc55SAndreas Gohr return $table; 201083afc55SAndreas Gohr } 202083afc55SAndreas Gohr 203083afc55SAndreas Gohr /** 204*127d6bacSMichael Große * Returns the translated label for this schema 205*127d6bacSMichael Große * 206*127d6bacSMichael Große * Uses the current language as determined by $conf['lang']. Falls back to english 207*127d6bacSMichael Große * and then to the table name 208*127d6bacSMichael Große * 209*127d6bacSMichael Große * @see \dokuwiki\plugin\struct\types\AbstractBaseType::getTranslatedLabel 210*127d6bacSMichael Große * 211*127d6bacSMichael Große * @return string 212*127d6bacSMichael Große */ 213*127d6bacSMichael Große public function getTranslatedLabel() { 214*127d6bacSMichael Große global $conf; 215*127d6bacSMichael Große $lang = $conf['lang']; 216*127d6bacSMichael Große if(!blank($this->config['label'][$lang])) { 217*127d6bacSMichael Große return $this->config['label'][$lang]; 218*127d6bacSMichael Große } 219*127d6bacSMichael Große if(!blank($this->config['label']['en'])) { 220*127d6bacSMichael Große return $this->config['label']['en']; 221*127d6bacSMichael Große } 222*127d6bacSMichael Große return $this->table; 223*127d6bacSMichael Große } 224*127d6bacSMichael Große 225*127d6bacSMichael Große /** 226097f4a53SAndreas Gohr * Gets a list of all available schemas 227097f4a53SAndreas Gohr * 2287c080d69SAndreas Gohr * @param string $filter either 'page' or 'lookup' 2297c080d69SAndreas Gohr * @return \string[] 230097f4a53SAndreas Gohr */ 2317c080d69SAndreas Gohr static public function getAll($filter = '') { 232097f4a53SAndreas Gohr /** @var \helper_plugin_struct_db $helper */ 233097f4a53SAndreas Gohr $helper = plugin_load('helper', 'struct_db'); 2347cbcfbdbSAndreas Gohr $db = $helper->getDB(false); 235097f4a53SAndreas Gohr if(!$db) return array(); 236097f4a53SAndreas Gohr 2377c080d69SAndreas Gohr if($filter == 'page') { 2387c080d69SAndreas Gohr $where = 'islookup = 0'; 2397c080d69SAndreas Gohr } elseif($filter == 'lookup') { 2407c080d69SAndreas Gohr $where = 'islookup = 1'; 2417c080d69SAndreas Gohr } else { 2427c080d69SAndreas Gohr $where = '1 = 1'; 2437c080d69SAndreas Gohr } 2447c080d69SAndreas Gohr 2457c080d69SAndreas Gohr $res = $db->query("SELECT DISTINCT tbl FROM schemas WHERE $where ORDER BY tbl"); 246097f4a53SAndreas Gohr $tables = $db->res2arr($res); 247097f4a53SAndreas Gohr $db->res_close($res); 248097f4a53SAndreas Gohr 249097f4a53SAndreas Gohr $result = array(); 250097f4a53SAndreas Gohr foreach($tables as $row) { 251097f4a53SAndreas Gohr $result[] = $row['tbl']; 252097f4a53SAndreas Gohr } 253097f4a53SAndreas Gohr return $result; 254097f4a53SAndreas Gohr } 255097f4a53SAndreas Gohr 256097f4a53SAndreas Gohr /** 257d5a1a6dcSAndreas Gohr * Delete all data associated with this schema 258d5a1a6dcSAndreas Gohr * 259d5a1a6dcSAndreas Gohr * This is really all data ever! Be careful! 260d5a1a6dcSAndreas Gohr */ 261d5a1a6dcSAndreas Gohr public function delete() { 262d5a1a6dcSAndreas Gohr if(!$this->id) throw new StructException('can not delete unsaved schema'); 263d5a1a6dcSAndreas Gohr 264d5a1a6dcSAndreas Gohr $this->sqlite->query('BEGIN TRANSACTION'); 265d5a1a6dcSAndreas Gohr 266d5a1a6dcSAndreas Gohr $sql = "DROP TABLE ?"; 267d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, 'data_' . $this->table); 268d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, 'multi_' . $this->table); 269d5a1a6dcSAndreas Gohr 270d5a1a6dcSAndreas Gohr $sql = "DELETE FROM schema_assignments WHERE tbl = ?"; 271d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, $this->table); 272d5a1a6dcSAndreas Gohr 273d5a1a6dcSAndreas Gohr $sql = "DELETE FROM schema_assignments_patterns WHERE tbl = ?"; 274d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, $this->table); 275d5a1a6dcSAndreas Gohr 276d5a1a6dcSAndreas Gohr $sql = "SELECT T.id 277d5a1a6dcSAndreas Gohr FROM types T, schema_cols SC, schemas S 278d5a1a6dcSAndreas Gohr WHERE T.id = SC.tid 279d5a1a6dcSAndreas Gohr AND SC.sid = S.id 280d5a1a6dcSAndreas Gohr AND S.tbl = ?"; 281d5a1a6dcSAndreas Gohr $sql = "DELETE FROM types WHERE id IN ($sql)"; 282d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, $this->table); 283d5a1a6dcSAndreas Gohr 284d5a1a6dcSAndreas Gohr $sql = "SELECT id 285d5a1a6dcSAndreas Gohr FROM schemas 286d5a1a6dcSAndreas Gohr WHERE tbl = ?"; 287d5a1a6dcSAndreas Gohr $sql = "DELETE FROM schema_cols WHERE sid IN ($sql)"; 288d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, $this->table); 289d5a1a6dcSAndreas Gohr 290d5a1a6dcSAndreas Gohr $sql = "DELETE FROM schemas WHERE tbl = ?"; 291d5a1a6dcSAndreas Gohr $this->sqlite->query($sql, $this->table); 292d5a1a6dcSAndreas Gohr 293d5a1a6dcSAndreas Gohr $this->sqlite->query('COMMIT TRANSACTION'); 294d5a1a6dcSAndreas Gohr $this->sqlite->query('VACUUM'); 295f9f13d8cSAndreas Gohr 296f9f13d8cSAndreas Gohr // a deleted schema should not be used anymore, but let's make sure it's somewhat sane anyway 297f9f13d8cSAndreas Gohr $this->id = 0; 298f9f13d8cSAndreas Gohr $this->chksum = ''; 299f9f13d8cSAndreas Gohr $this->columns = array(); 300f9f13d8cSAndreas Gohr $this->maxsort = 0; 301f9f13d8cSAndreas Gohr $this->ts = 0; 302d5a1a6dcSAndreas Gohr } 303d5a1a6dcSAndreas Gohr 304d5a1a6dcSAndreas Gohr /** 3051c502704SAndreas Gohr * @return string 3061c502704SAndreas Gohr */ 3071c502704SAndreas Gohr public function getChksum() { 3081c502704SAndreas Gohr return $this->chksum; 3091c502704SAndreas Gohr } 3101c502704SAndreas Gohr 3111c502704SAndreas Gohr /** 3121c502704SAndreas Gohr * @return int 3131c502704SAndreas Gohr */ 3141c502704SAndreas Gohr public function getId() { 3151c502704SAndreas Gohr return $this->id; 3161c502704SAndreas Gohr } 3171c502704SAndreas Gohr 3181c502704SAndreas Gohr /** 319587e314dSAndreas Gohr * @return int returns the timestamp this Schema was created at 320f411d872SAndreas Gohr */ 321f411d872SAndreas Gohr public function getTimeStamp() { 322f411d872SAndreas Gohr return $this->ts; 323f411d872SAndreas Gohr } 324f411d872SAndreas Gohr 325f411d872SAndreas Gohr /** 32688b7d2aaSAndreas Gohr * @return bool is this a lookup schema? 32788b7d2aaSAndreas Gohr */ 32888b7d2aaSAndreas Gohr public function isLookup() { 32988b7d2aaSAndreas Gohr return $this->islookup; 33088b7d2aaSAndreas Gohr } 33188b7d2aaSAndreas Gohr 33288b7d2aaSAndreas Gohr /** 333fa7b96aaSMichael Grosse * @return string 334fa7b96aaSMichael Grosse */ 335fa7b96aaSMichael Grosse public function getUser() { 336fa7b96aaSMichael Grosse return $this->user; 337fa7b96aaSMichael Grosse } 338fa7b96aaSMichael Grosse 339*127d6bacSMichael Große public function getConfig() { 340*127d6bacSMichael Große return $this->config; 341e2c90eebSAndreas Gohr } 342e2c90eebSAndreas Gohr 343fa7b96aaSMichael Grosse /** 3446ebbbb8eSAndreas Gohr * Checks if the current user may edit data in this schema 3456ebbbb8eSAndreas Gohr * 3466ebbbb8eSAndreas Gohr * @return bool 3476ebbbb8eSAndreas Gohr */ 3486ebbbb8eSAndreas Gohr public function isEditable() { 3496ebbbb8eSAndreas Gohr global $USERINFO; 350*127d6bacSMichael Große if($this->config['allowed editors'] === '') return true; 3516ebbbb8eSAndreas Gohr if(blank($_SERVER['REMOTE_USER'])) return false; 3526ebbbb8eSAndreas Gohr if(auth_isadmin()) return true; 353*127d6bacSMichael Große return auth_isMember($this->config['allowed editors'], $_SERVER['REMOTE_USER'], $USERINFO['grps']); 3546ebbbb8eSAndreas Gohr } 3556ebbbb8eSAndreas Gohr 3566ebbbb8eSAndreas Gohr /** 357ce206ec7SAndreas Gohr * Returns a list of columns in this schema 358ce206ec7SAndreas Gohr * 359ce206ec7SAndreas Gohr * @param bool $withDisabled if false, disabled columns will not be returned 360ce206ec7SAndreas Gohr * @return Column[] 3611c502704SAndreas Gohr */ 362ce206ec7SAndreas Gohr public function getColumns($withDisabled = true) { 363ce206ec7SAndreas Gohr if(!$withDisabled) { 364ce206ec7SAndreas Gohr return array_filter( 365ce206ec7SAndreas Gohr $this->columns, 366ce206ec7SAndreas Gohr function (Column $col) { 367ce206ec7SAndreas Gohr return $col->isEnabled(); 368ce206ec7SAndreas Gohr } 369ce206ec7SAndreas Gohr ); 370ce206ec7SAndreas Gohr } 371ce206ec7SAndreas Gohr 3721c502704SAndreas Gohr return $this->columns; 3731c502704SAndreas Gohr } 3741c502704SAndreas Gohr 375ae697e1fSAndreas Gohr /** 3765742aea9SAndreas Gohr * Find a column in the schema by its label 3775742aea9SAndreas Gohr * 3785742aea9SAndreas Gohr * Only enabled columns are returned! 3795742aea9SAndreas Gohr * 3805742aea9SAndreas Gohr * @param $name 3815742aea9SAndreas Gohr * @return bool|Column 3825742aea9SAndreas Gohr */ 3835742aea9SAndreas Gohr public function findColumn($name) { 3845742aea9SAndreas Gohr foreach($this->columns as $col) { 3855742aea9SAndreas Gohr if($col->isEnabled() && utf8_strtolower($col->getLabel()) == utf8_strtolower($name)) { 3865742aea9SAndreas Gohr return $col; 3875742aea9SAndreas Gohr } 3885742aea9SAndreas Gohr } 3895742aea9SAndreas Gohr return false; 3905742aea9SAndreas Gohr } 3915742aea9SAndreas Gohr 3925742aea9SAndreas Gohr /** 393ae697e1fSAndreas Gohr * @return string 394ae697e1fSAndreas Gohr */ 395ae697e1fSAndreas Gohr public function getTable() { 396ae697e1fSAndreas Gohr return $this->table; 397ae697e1fSAndreas Gohr } 3981c502704SAndreas Gohr 399ae697e1fSAndreas Gohr /** 400ae697e1fSAndreas Gohr * @return int the highest sort number used in this schema 401ae697e1fSAndreas Gohr */ 402ae697e1fSAndreas Gohr public function getMaxsort() { 403ae697e1fSAndreas Gohr return $this->maxsort; 404ae697e1fSAndreas Gohr } 4051c502704SAndreas Gohr 406d486d6d7SAndreas Gohr /** 407d486d6d7SAndreas Gohr * @return string the JSON representing this schema 408d486d6d7SAndreas Gohr */ 409d486d6d7SAndreas Gohr public function toJSON() { 410d486d6d7SAndreas Gohr $data = array( 411d486d6d7SAndreas Gohr 'structversion' => $this->structversion, 412d486d6d7SAndreas Gohr 'schema' => $this->getTable(), 413d486d6d7SAndreas Gohr 'id' => $this->getId(), 41445313413SMichael Grosse 'user' => $this->getUser(), 415*127d6bacSMichael Große 'config' => $this->getConfig(), 416d486d6d7SAndreas Gohr 'columns' => array() 417d486d6d7SAndreas Gohr ); 418d486d6d7SAndreas Gohr 419d486d6d7SAndreas Gohr foreach($this->columns as $column) { 420d486d6d7SAndreas Gohr $data['columns'][] = array( 421d486d6d7SAndreas Gohr 'colref' => $column->getColref(), 422d486d6d7SAndreas Gohr 'ismulti' => $column->isMulti(), 423d486d6d7SAndreas Gohr 'isenabled' => $column->isEnabled(), 424d486d6d7SAndreas Gohr 'sort' => $column->getSort(), 425d486d6d7SAndreas Gohr 'label' => $column->getLabel(), 426d486d6d7SAndreas Gohr 'class' => $column->getType()->getClass(), 427d486d6d7SAndreas Gohr 'config' => $column->getType()->getConfig(), 428d486d6d7SAndreas Gohr ); 429d486d6d7SAndreas Gohr } 430d486d6d7SAndreas Gohr 431d486d6d7SAndreas Gohr return json_encode($data, JSON_PRETTY_PRINT); 432d486d6d7SAndreas Gohr } 433083afc55SAndreas Gohr} 434