1<?php
2
3namespace dokuwiki\plugin\bez\mdl;
4
5use dokuwiki\plugin\bez\meta\ValidationException;
6
7class Validator {
8	private $rules=array(), $errors=array(), $model;
9	public function __construct($model) {
10		$this->model = $model;
11	}
12
13	public function add_rule($field, $rule) {
14        $this->rules[$field] = $rule;
15    }
16
17    public function delete_rule($field) {
18	    if (isset($this->rules[$field])) {
19            unset($this->rules[$field]);
20        }
21    }
22
23	public function set_rules($rules) {
24		$this->rules = array_merge($this->rules, $rules);
25	}
26
27	public function get_rules() {
28		return $this->rules;
29	}
30
31	public function get_rule($field) {
32	    if (!isset($this->rules[$field])) {
33            throw new \Exception("no rule exists for $field");
34        }
35        return $this->rules[$field];
36    }
37
38	public function get_errors() {
39		return $this->errors;
40	}
41
42	public function set_error($field, $code) {
43		$this->errors[$field] = $code;
44	}
45
46	protected function check_against_val_method($value, $method, $args) {
47		$validator = 'validate_'.$method;
48		if (!method_exists($this, $validator)) {
49			throw new \Exception("there is no validation function $validator");
50		}
51
52		array_unshift($args, $value);
53		$result = call_user_func_array(array($this, $validator), $args);
54		return array($result, $method);
55	}
56
57	protected function validate_one($value, $method, $args, $null) {
58			if ($null === 'NOT NULL' && $value == '') {
59				return array(false, 'is_null');
60			} else if ($null === 'NULL' && $value == '') {
61				return array(true, 'is_null');
62			}
63
64			return $this->check_against_val_method($value, $method, $args);
65	}
66
67    public function validate_field($field, $value) {
68        if (!isset($this->rules[$field])) {
69            throw new \Exception('no validation rule for '.$field);
70        }
71
72        $args = $this->rules[$field][0];
73        $null = $this->rules[$field][1];
74
75        $method = array_shift($args);
76        list($result, $code) = $this->validate_one($value, $method, $args, $null);
77        if ($result === false) {
78            throw new ValidationException('-unknown', array($field => $code));
79        }
80
81        /*by convention all values as passed as strings*/
82        return (string) $value;
83    }
84
85	public function validate($data, $fields=null) {
86		$val_data = array();
87
88		if (is_null($fields)) {
89		    $fields = array_keys($this->rules);
90        }
91
92		foreach ($data as $key => $value) {
93			if (!in_array($key, $fields)) {
94				continue;
95			}
96			try {
97                $val_data[$key] = $this->validate_field($key, $value);
98
99            } catch (ValidationException $e) {
100				$this->errors[$key] = $e->get_errors()[$key];
101			}
102		}
103		if (count($this->errors) > 0) {
104			return false;
105		}
106
107		return $val_data;
108	}
109
110	public function validate_array_of($array, $args) {
111
112		$method = array_shift($args);
113
114		foreach ($array as $value) {
115			$result = $this->check_against_val_method($value, $method, $args);
116			if ($result === false) {
117				return false;
118			}
119		}
120		return true;
121	}
122
123	public function validate_select($value, $options) {
124		if (in_array($value, $options)) {
125			return true;
126		}
127		return false;
128	}
129
130	public function validate_dw_user($user, $addtitional_values=array()) {
131		$wiki_users = $this->model->userFactory->get_all();
132		if (array_key_exists($user, $wiki_users) ||
133			in_array($user, $addtitional_values)) {
134			return true;
135		}
136		return false;
137	}
138
139	public function validate_unix_timestamp($stamp) {
140		if (is_numeric($stamp)) {
141			return true;
142		}
143		return false;
144	}
145
146	public function validate_numeric($value) {
147		if (is_numeric($value)) {
148			return true;
149		}
150		return false;
151	}
152
153	public function validate_length($value, $max_length) {
154		if (strlen($value) <= $max_length) {
155			return true;
156		}
157		return false;
158	}
159
160	public function validate_iso_date($date) {
161		if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $date, $parts)) {
162			$year  = $parts[1];
163			$month = $parts[2];
164			$day   = $parts[3];
165			if (mktime(0, 0, 0, $month, $day, $year)) {
166				return true;
167			}
168			return false;
169		}
170		return false;
171	}
172
173    public function validate_sqlite_datetime($date) {
174        $strtotime = strtotime($date);
175        if ($strtotime === false) {
176            return false;
177        }
178
179        $datetime = date('Y-m-d H:i:s', $strtotime);
180        if ($datetime !== $date) {
181            return false;
182        }
183
184		return true;
185	}
186
187	public function validate_time($time) {
188		if (preg_match('/^(\d{1,2}):(\d{1,2})$/', $time, $parts)) {
189			$hours  = $parts[1];
190			$minutes = $parts[2];
191
192			if (mktime($hours, $minutes, 0)) {
193				return true;
194			}
195			return false;
196		}
197		return false;
198	}
199
200	public function validate_must_be_empty($value) {
201		if ($value == '') {
202			return true;
203		}
204		return false;
205	}
206}
207