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