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 /** 42 * Schema constructor 43 * 44 * @param string $table The table this schema is for 45 * @param int $ts The timestamp for when this schema was valid, 0 for current 46 */ 47 public function __construct($table, $ts = 0) { 48 /** @var \helper_plugin_struct_db $helper */ 49 $helper = plugin_load('helper', 'struct_db'); 50 $this->sqlite = $helper->getDB(); 51 if(!$this->sqlite) return; 52 53 $table = self::cleanTableName($table); 54 $this->table = $table; 55 56 // load info about the schema itself 57 if($ts) { 58 $sql = "SELECT * 59 FROM schemas 60 WHERE tbl = ? 61 AND ts <= ? 62 ORDER BY ts DESC 63 LIMIT 1"; 64 $opt = array($table, $ts); 65 66 } else { 67 $sql = "SELECT * 68 FROM schemas 69 WHERE tbl = ? 70 ORDER BY ts DESC 71 LIMIT 1"; 72 $opt = array($table); 73 } 74 $res = $this->sqlite->query($sql, $opt); 75 if($this->sqlite->res2count($res)) { 76 $result = array_shift($this->sqlite->res2arr($res)); 77 $this->id = $result['id']; 78 $this->chksum = $result['chksum']; 79 80 } 81 $this->sqlite->res_close($res); 82 if(!$this->id) return; 83 84 // load existing columns 85 $sql = "SELECT SC.*, T.* 86 FROM schema_cols SC, 87 types T 88 WHERE SC.sid = ? 89 AND SC.tid = T.id 90 ORDER BY SC.sort"; 91 $res = $this->sqlite->query($sql, $this->id); 92 $rows = $this->sqlite->res2arr($res); 93 $this->sqlite->res_close($res); 94 95 foreach($rows as $row) { 96 $class = 'plugin\\struct\\types\\' . $row['class']; 97 $config = json_decode($row['config'], true); 98 $this->columns[$row['colref']] = 99 new Column( 100 $row['sort'], 101 new $class($config, $row['label'], $row['ismulti']), 102 $row['tid'], 103 $row['colref'], 104 $row['enabled'] 105 ); 106 107 if($row['sort'] > $this->maxsort) $this->maxsort = $row['sort']; 108 } 109 } 110 111 /** 112 * Cleans any unwanted stuff from table names 113 * 114 * @param string $table 115 * @return string 116 */ 117 static public function cleanTableName($table) { 118 $table = strtolower($table); 119 $table = preg_replace('/[^a-z0-9_]+/', '', $table); 120 $table = preg_replace('/^[0-9_]+/', '', $table); 121 $table = trim($table); 122 return $table; 123 } 124 125 /** 126 * @return string 127 */ 128 public function getChksum() { 129 return $this->chksum; 130 } 131 132 /** 133 * @return int 134 */ 135 public function getId() { 136 return $this->id; 137 } 138 139 /** 140 * @return \plugin\struct\meta\Column[] 141 */ 142 public function getColumns() { 143 return $this->columns; 144 } 145 146 /** 147 * @return string 148 */ 149 public function getTable() { 150 return $this->table; 151 } 152 153 /** 154 * @return int the highest sort number used in this schema 155 */ 156 public function getMaxsort() { 157 return $this->maxsort; 158 } 159 160} 161