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