1<?php 2 3//if(!defined('DOKU_INC')) die(); 4 5 6//~ abstract class BEZ_mdl_Dummy_Entity { 7 8 //~ protected $model; 9 10 //~ protected $id = NULL; 11 12 //~ public function __get($property) { 13 //~ if ($property === 'id') { 14 //~ return $this->id; 15 //~ } 16 //~ } 17 18 //~ public function get_table_singular() { 19 //~ $class = get_class($this); 20 //~ $exp = explode('_', $class); 21 //~ $singular = array_pop($exp); 22 //~ return lcfirst($singular); 23 //~ } 24 25 //~ public function get_table_name() { 26 //~ $singlar = $this->get_table_singular(); 27 //~ return $singular.'s'; 28 //~ } 29 30 //~ public function acl_of($field) { 31 //~ return $this->model->acl->check_field($this, $field); 32 //~ } 33 34 //~ public function __construct($model) { 35 //~ $this->model = $model; 36 //~ } 37//~ } 38 39namespace dokuwiki\plugin\bez\mdl; 40/* 41 * All fields are stored in object as strings. 42 * NULLs are converted to empty string. 43 * If any attribute in object === NULL -> it means that it was not initialized 44 * But we always inserts NULLs instead of empty strings. 45 * https://stackoverflow.com/questions/1267999/mysql-better-to-insert-null-or-empty-string 46 **/ 47 48use dokuwiki\plugin\bez\meta\PermissionDeniedException; 49 50abstract class Entity {// extends BEZ_mdl_Dummy_Entity { 51 52 /** @var Model */ 53 protected $model; 54 55 /** @var Validator */ 56 protected $validator; 57 58 //protected $columns_demendencies = array(); 59 60 //protected $parse_int = array(); 61 62 abstract public static function get_columns(); 63 64// abstract public static function get_virtual_columns(); 65 66// private function is_dummy() { 67// if (strstr(get_class(), 'Dummy') === false) { 68// return false; 69// } 70// return true; 71// } 72// 73// private function not_for_dummies() { 74// if ($this->is_dummy()) { 75// throw new Exception('dummy object doesn\'t contains data.'); 76// } 77// } 78 79 public function get_assoc($filter=NULL) { 80 //$this->not_for_dummies(); 81 82 $assoc = array(); 83 //$columns = array_merge($this->get_columns(), $this->get_virtual_columns()); 84 85 $columns = $this->get_columns(); 86 if ($filter !== NULL) { 87 $columns = array_intersect($columns, $filter); 88 } 89 90 foreach ($columns as $col) { 91 $assoc[$col] = $this->$col; 92 } 93 return $assoc; 94 } 95 96// public function get_table_singular() { 97// $class = get_class($this); 98// $exp = explode('_', $class); 99// $singular = array_pop($exp); 100// return lcfirst($singular); 101// } 102// 103 public function get_table_name() { 104 $class = (new \ReflectionClass($this))->getShortName(); 105 return lcfirst($class); 106 } 107 108// private function create_DateTime_from_column($column) { 109// $cols = array_merge($this->get_columns(), $this->get_virtual_columns()); 110// if (!in_array($column, $cols)) { 111// throw new Exception("$column is not a column"); 112// } 113// $dt = $this->$column; 114// if (is_numeric($dt)) { 115// return new DateTime('@'.$dt); 116// } 117// return new DateTime($dt); 118// } 119// 120// public function date_format($column) { 121// $date = $this->create_DateTime_from_column($column); 122// 123// return $date->format('Y-m-d'); 124// } 125// 126// public function datetime_format($column, $format='comment') { 127// $date = $this->create_DateTime_from_column($column);; 128// 129// if ($format === 'comment') { 130// return $dt->format('j') . ' ' . 131// $this->model->action->getLang('mon'.$dt->format('n').'_a') . ' ' . 132// ($dt->format('Y') === date('Y') ? '' : $dt->format('Y') . ' ') . 133// $this->model->action->getLang('at_hour') . ' ' . 134// $dt->format('G:i'); 135// } 136// } 137// 138// public function days_ago($column, $first_date = null) { 139// if ($first_date === null) { 140// $first_date = new DateTime(); 141// } elseif (is_string($first_date)) { 142// $first_date = $this->create_DateTime_from_column($first_date); 143// } 144// $interval = $first_date->diff($this->create_DateTime_from_column($column)); 145// $sign = $interval->format('%R'); 146// $days = $interval->format('%a'); 147// if ($sign === '-') { 148// return $days . ' ' . $this->model->action->getLang('days') . ' ' . 149// $this->model->action->getLang('ago'); 150// } 151// return $days . ' ' . $this->model->action->getLang('days'); 152// 153// } 154// 155// public function float_localized($column) { 156// $cols = array_merge($this->get_columns(), $this->get_virtual_columns()); 157// if (!in_array($column, $cols)) { 158// throw new Exception("$column is not a column"); 159// } 160// if ($this->$column === '') { 161// return ''; 162// } 163// 164// if (!is_numeric($this->$column)) { 165// throw new Exception('Column ' . $column . ' isn\'t numeric'); 166// } 167// 168// return sprintf('%.2f', $this->$column); 169// } 170 171 //set id when object is saved in database 172// public function set_id($id) { 173//// $this->not_for_dummies(); 174// 175// if ($this->id === NULL) { 176// $this->id = $id; 177// } else { 178// throw new \Exception('id already set for issue #'.$this->id); 179// } 180// } 181 182// public function sqlite_date($time=NULL) { 183// //SQLITE format: https://www.sqlite.org/lang_datefunc.html 184// if ($time === NULL) { 185// return date('Y-m-d H:i:s'); 186// } else { 187// return date('Y-m-d H:i:s', $time); 188// } 189// } 190 191 public function __get($property) { 192// $this->not_for_dummies(); 193 194// $columns = array_merge($this->get_columns(), $this->get_virtual_columns()); 195 if (!property_exists($this, $property) || !in_array($property, $this->get_columns())) { 196 throw new \Exception('there is no column: "'.$property. '"" in table: "' . $this->get_table_name() . '"'); 197 } 198 199 //now only normal db columns has ACL, it should be fixed 200 if ($this->acl_of($property) < BEZ_PERMISSION_VIEW) { 201 throw new PermissionDeniedException(); 202 } 203 204 return $this->$property; 205 206// if (property_exists($this, $property) && in_array($property, $this->get_columns())) { 207//// if (in_array($property, $this->parse_int)) { 208//// return (int)$this->$property; 209//// } else { 210// return $this->$property; 211//// } 212// } 213 } 214 215 protected function set_property($property, $value) { 216// $this->not_for_dummies(); 217 218 if (!in_array($property, $this->get_columns())) { 219 throw new \Exception('trying to set not existing column'); 220 } 221 222 //throws ValidationException 223 $this->validator->validate_field($property, $value); 224 225 //throws PermissionDeniedException 226 $this->model->acl->can_change($this, $property); 227 228 $this->$property = $value; 229 230// if (isset($this->columns_demendencies[$property])) { 231// $method = $this->columns_demendencies[$property]; 232// //convention -> run the method with the same name as $property 233// if (!method_exists($this, $method)) { 234// throw new Exception("denepndency method: $property not implemented"); 235// } 236// $this->$method(); 237// } 238 } 239 240 protected function set_property_array($array) { 241 foreach ($array as $k => $v) { 242 $this->set_property($k, $v); 243 } 244 } 245 246 //by default do nothing 247// private function update_virtual_columns() { 248// } 249// 250 251 public function set_data($post) { 252// $input = array_intersect($this->changable_fields($filter), array_keys($post), array_keys($this->validator->get_rules())); 253 254 $val_data = $this->validator->validate($post); 255 if ($val_data === false) { 256 throw new ValidationException($this->get_table_name(), $this->validator->get_errors()); 257 } 258 259 $this->set_property_array($val_data); 260 261// $this->update_virtual_columns(); 262 } 263 264// public function changable_fields($filter=NULL) { 265// $fields = $this->model->acl->check($this); 266// 267// if ($filter !== NULL) { 268// $fields = array_filter($fields, function ($k) use ($filter) { 269// return in_array($k, $filter); 270// }, ARRAY_FILTER_USE_KEY); 271// } 272// 273// return array_keys(array_filter($fields, function ($var) { 274// return $var >= BEZ_PERMISSION_CHANGE; 275// })); 276// } 277 278 public function acl_of($field) { 279 return $this->model->acl->check_field($this, $field); 280 } 281 282 public function __construct($model) { 283 //by convention all defaults must be strings 284// foreach ($defaults as $val) { 285// if (!is_string($val)) { 286// throw new Exception('all defaults must be strings'); 287// } 288// } 289// $this->model = $model; 290// 291// if (!$this->is_dummy()) { 292// $this->validator = new BEZ_mdl_Validator($this->model); 293// } 294 //$this->helper = plugin_load('helper', 'bez'); 295 296 $this->model = $model; 297 $this->validator = new Validator($this->model); 298 } 299} 300