xref: /plugin/bez/mdl/Entity.php (revision 8a6381983135ed7de69b33e64aa0c1b16dbf69b0)
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