1083afc55SAndreas Gohr<?php 2083afc55SAndreas Gohr 3083afc55SAndreas Gohrnamespace plugin\struct\meta; 4083afc55SAndreas Gohr 51c502704SAndreas Gohruse dokuwiki\Form\Form; 6083afc55SAndreas Gohruse plugin\struct\types\AbstractBaseType; 7083afc55SAndreas Gohruse plugin\struct\types\Text; 8083afc55SAndreas 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 * 177182938bSAndreas Gohr * @package 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 27083afc55SAndreas Gohr /** @var string name of the associated table */ 28083afc55SAndreas Gohr protected $table = ''; 29083afc55SAndreas Gohr 30083afc55SAndreas Gohr /** 31083afc55SAndreas Gohr * @var string the current checksum of this schema 32083afc55SAndreas Gohr */ 33083afc55SAndreas Gohr protected $chksum = ''; 34083afc55SAndreas Gohr 351c502704SAndreas Gohr /** @var Column[] all the colums */ 36083afc55SAndreas Gohr protected $columns = array(); 37083afc55SAndreas Gohr 38083afc55SAndreas Gohr /** @var int */ 39083afc55SAndreas Gohr protected $maxsort = 0; 40083afc55SAndreas Gohr 41250c83c2SAndreas Gohr /** @var int */ 42250c83c2SAndreas Gohr protected $ts = 0; 43250c83c2SAndreas Gohr 44083afc55SAndreas Gohr /** 45083afc55SAndreas Gohr * Schema constructor 467182938bSAndreas Gohr * 47083afc55SAndreas Gohr * @param string $table The table this schema is for 48083afc55SAndreas Gohr * @param int $ts The timestamp for when this schema was valid, 0 for current 49083afc55SAndreas Gohr */ 50083afc55SAndreas Gohr public function __construct($table, $ts = 0) { 51083afc55SAndreas Gohr /** @var \helper_plugin_struct_db $helper */ 52083afc55SAndreas Gohr $helper = plugin_load('helper', 'struct_db'); 53083afc55SAndreas Gohr $this->sqlite = $helper->getDB(); 54083afc55SAndreas Gohr if(!$this->sqlite) return; 55083afc55SAndreas Gohr 56083afc55SAndreas Gohr $table = self::cleanTableName($table); 57083afc55SAndreas Gohr $this->table = $table; 58250c83c2SAndreas Gohr $this->ts = $ts; 59083afc55SAndreas Gohr 60083afc55SAndreas Gohr // load info about the schema itself 61083afc55SAndreas Gohr if($ts) { 62083afc55SAndreas Gohr $sql = "SELECT * 63083afc55SAndreas Gohr FROM schemas 64083afc55SAndreas Gohr WHERE tbl = ? 65083afc55SAndreas Gohr AND ts <= ? 66083afc55SAndreas Gohr ORDER BY ts DESC 67083afc55SAndreas Gohr LIMIT 1"; 68083afc55SAndreas Gohr $opt = array($table, $ts); 69083afc55SAndreas Gohr 70083afc55SAndreas Gohr } else { 71083afc55SAndreas Gohr $sql = "SELECT * 72083afc55SAndreas Gohr FROM schemas 73083afc55SAndreas Gohr WHERE tbl = ? 74083afc55SAndreas Gohr ORDER BY ts DESC 75083afc55SAndreas Gohr LIMIT 1"; 76083afc55SAndreas Gohr $opt = array($table); 77083afc55SAndreas Gohr } 78083afc55SAndreas Gohr $res = $this->sqlite->query($sql, $opt); 79083afc55SAndreas Gohr if($this->sqlite->res2count($res)) { 804e2abec0SMichael Große $schema = $this->sqlite->res2arr($res); 814e2abec0SMichael Große $result = array_shift($schema); 82083afc55SAndreas Gohr $this->id = $result['id']; 83083afc55SAndreas Gohr $this->chksum = $result['chksum']; 84083afc55SAndreas Gohr 85083afc55SAndreas Gohr } 86083afc55SAndreas Gohr $this->sqlite->res_close($res); 87083afc55SAndreas Gohr if(!$this->id) return; 88083afc55SAndreas Gohr 89083afc55SAndreas Gohr // load existing columns 90083afc55SAndreas Gohr $sql = "SELECT SC.*, T.* 91083afc55SAndreas Gohr FROM schema_cols SC, 92083afc55SAndreas Gohr types T 931c502704SAndreas Gohr WHERE SC.sid = ? 941c502704SAndreas Gohr AND SC.tid = T.id 95083afc55SAndreas Gohr ORDER BY SC.sort"; 961c502704SAndreas Gohr $res = $this->sqlite->query($sql, $this->id); 97083afc55SAndreas Gohr $rows = $this->sqlite->res2arr($res); 98083afc55SAndreas Gohr $this->sqlite->res_close($res); 99083afc55SAndreas Gohr 100083afc55SAndreas Gohr foreach($rows as $row) { 1011c502704SAndreas Gohr $class = 'plugin\\struct\\types\\' . $row['class']; 102083afc55SAndreas Gohr $config = json_decode($row['config'], true); 1031c502704SAndreas Gohr $this->columns[$row['colref']] = 1041c502704SAndreas Gohr new Column( 1051c502704SAndreas Gohr $row['sort'], 10604eb61a6SAndreas Gohr new $class($config, $row['label'], $row['ismulti'], $row['tid']), 1071c502704SAndreas Gohr $row['colref'], 108*63d51bbfSAndreas Gohr $row['enabled'], 109*63d51bbfSAndreas Gohr $table 1101c502704SAndreas Gohr ); 1111c502704SAndreas Gohr 112083afc55SAndreas Gohr if($row['sort'] > $this->maxsort) $this->maxsort = $row['sort']; 113083afc55SAndreas Gohr } 114083afc55SAndreas Gohr } 115083afc55SAndreas Gohr 116083afc55SAndreas Gohr /** 117083afc55SAndreas Gohr * Cleans any unwanted stuff from table names 118083afc55SAndreas Gohr * 119083afc55SAndreas Gohr * @param string $table 120083afc55SAndreas Gohr * @return string 121083afc55SAndreas Gohr */ 122083afc55SAndreas Gohr static public function cleanTableName($table) { 1232af472dcSAndreas Gohr $table = strtolower($table); 124083afc55SAndreas Gohr $table = preg_replace('/[^a-z0-9_]+/', '', $table); 125083afc55SAndreas Gohr $table = preg_replace('/^[0-9_]+/', '', $table); 126083afc55SAndreas Gohr $table = trim($table); 127083afc55SAndreas Gohr return $table; 128083afc55SAndreas Gohr } 129083afc55SAndreas Gohr 130083afc55SAndreas Gohr /** 1311c502704SAndreas Gohr * @return string 1321c502704SAndreas Gohr */ 1331c502704SAndreas Gohr public function getChksum() { 1341c502704SAndreas Gohr return $this->chksum; 1351c502704SAndreas Gohr } 1361c502704SAndreas Gohr 1371c502704SAndreas Gohr /** 1381c502704SAndreas Gohr * @return int 1391c502704SAndreas Gohr */ 1401c502704SAndreas Gohr public function getId() { 1411c502704SAndreas Gohr return $this->id; 1421c502704SAndreas Gohr } 1431c502704SAndreas Gohr 1441c502704SAndreas Gohr /** 145ce206ec7SAndreas Gohr * Returns a list of columns in this schema 146ce206ec7SAndreas Gohr * 147ce206ec7SAndreas Gohr * @param bool $withDisabled if false, disabled columns will not be returned 148ce206ec7SAndreas Gohr * @return Column[] 1491c502704SAndreas Gohr */ 150ce206ec7SAndreas Gohr public function getColumns($withDisabled = true) { 151ce206ec7SAndreas Gohr if(!$withDisabled) { 152ce206ec7SAndreas Gohr return array_filter( 153ce206ec7SAndreas Gohr $this->columns, 154ce206ec7SAndreas Gohr function (Column $col) { 155ce206ec7SAndreas Gohr return $col->isEnabled(); 156ce206ec7SAndreas Gohr } 157ce206ec7SAndreas Gohr ); 158ce206ec7SAndreas Gohr } 159ce206ec7SAndreas Gohr 1601c502704SAndreas Gohr return $this->columns; 1611c502704SAndreas Gohr } 1621c502704SAndreas Gohr 163ae697e1fSAndreas Gohr /** 164ae697e1fSAndreas Gohr * @return string 165ae697e1fSAndreas Gohr */ 166ae697e1fSAndreas Gohr public function getTable() { 167ae697e1fSAndreas Gohr return $this->table; 168ae697e1fSAndreas Gohr } 1691c502704SAndreas Gohr 170ae697e1fSAndreas Gohr /** 171ae697e1fSAndreas Gohr * @return int the highest sort number used in this schema 172ae697e1fSAndreas Gohr */ 173ae697e1fSAndreas Gohr public function getMaxsort() { 174ae697e1fSAndreas Gohr return $this->maxsort; 175ae697e1fSAndreas Gohr } 1761c502704SAndreas Gohr 177083afc55SAndreas Gohr} 178