1<?php
2	/*
3	 * The condition_plugin_custom_tester class defined in <tpl>/condition_plugin_custom_tester.php
4	 * MUST implements this class
5	 *
6	 * To add a custom test in condition_plugin_custom_tester you just have to add a method like :
7	 *
8	 *	function test_dummy($b, &$bug, $lop=false) { if($lop) return array(); return true; }
9	 *		this test will react to <if dummy></if> of <if dummy=3></if>
10	 *
11	 * or
12	 *
13	 *	function test_IP($b, &$bug, $lop=false) {
14	 *		if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\~\='); // pcre regexp list of allowed test operators
15	 *		$ip = clientIP(true);
16	 *		if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '') || ($ip == '0.0.0.0')) {
17	 *			$bug = true;
18	 *			return false;
19	 *		}
20	 *		switch($b['test']) {
21	 *			case '=' :
22	 *			case 'eq' :
23	 *			case '==' :
24	 *				return ($ip == $b['value']); break;
25	 *			case '!=' :
26	 *			case 'ne' :
27	 *			case 'neq' :
28	 *				return ($ip != $b['value']); break;
29	 *			case '~=' : // such new test operators must be added in syntax.php
30	 *				return (strpos($ip, $b['value']) !== false); break;
31	 *			default: // non allowed operators for the test must lead to a bug flag raise
32	 *				$bug = true;
33	 *				return false;
34	 *		}
35	 *	}
36	 *		this test will react to <if IP=127.0.0.1></if>
37	 */
38
39	class condition_plugin_base_tester {
40		function __construct() {}
41
42		// Wrapper for all tests
43		function run($b, &$bug) {
44			if(method_exists($this, 'test_'.$b['key'])) {
45				return call_user_func(array($this, 'test_'.$b['key']), $b, $bug);
46			}
47			$bug = true;
48			return false;
49		}
50
51		// Get allowed keys
52		function getkeys() {
53			$keys = array();
54			foreach(get_class_methods($this) as $m) {
55				if(preg_match('`^test_(.+)$`', $m, $r)) $keys[] = $r[1];
56			}
57			return $keys;
58		}
59
60		// Get test operators
61		function getops() {
62			$ops = array();
63			foreach($this->getkeys() as $m) $ops = array_merge($ops, call_user_func(array($this, 'test_'.$m), null, $dummy, true));
64			return array_unique($ops);
65		}
66
67		// Tests follows
68		// -------------
69
70		// user based tests
71		function test_user($b, &$bug, $lop=false) {
72			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?');
73			$rh = isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : '';
74			if(!$b['test'] || ($b['test'] == '')) return ($rh && ($rh != ''));
75			switch($b['test']) {
76				case '=' :
77				case 'eq' :
78				case '==' :
79					return $rh == $b['value']; break;
80				case '!=' :
81				case 'ne' :
82				case 'neq' :
83					return $rh != $b['value']; break;
84				default:
85					$bug = true;
86					return false;
87			}
88		}
89
90		function test_group($b, &$bug, $lop=false) {
91			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?');
92			global $INFO;
93			$grps = isset($INFO['userinfo']) ? $INFO['userinfo']['grps'] : array();
94			if(!$b['test'] || ($b['test'] == '')) return (count($grps) != 0);
95			switch($b['test']) {
96				case '=' :
97				case 'eq' :
98				case '==' :
99					if(!$b['value'] || ($b['value'] == '')) return (count($grps) == 0);
100					return in_array($b['value'], $grps); break;
101				case '!=' :
102				case 'ne' :
103				case 'neq' :
104					if(!$b['value'] || ($b['value'] == '')) return (count($grps) != 0);
105					return !in_array($b['value'], $grps); break;
106				default:
107					$bug = true;
108					return false;
109			}
110		}
111
112		// namespace based tests
113		function test_nsread($b, &$bug, $lop=false) {
114			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?');
115			if(!$b['test'] || ($b['test'] == '')) {
116				$bug = true;
117				return false;
118			}
119			if(!$b['value'] || ($b['value'] == '')) $b['value'] = '.';
120			switch($b['test']) {
121				case '=' :
122				case 'eq' :
123				case '==' :
124					return (auth_quickaclcheck($b['value']) >= AUTH_READ); break;
125				case '!=' :
126				case 'ne' :
127				case 'neq' :
128					return (auth_quickaclcheck($b['value']) < AUTH_READ); break;
129				default:
130					$bug = true;
131					return false;
132			}
133		}
134
135		function test_nsedit($b, &$bug, $lop=false) {
136			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?');
137			if(!$b['test'] || ($b['test'] == '')) {
138				$bug = true;
139				return false;
140			}
141			if(!$b['value'] || ($b['value'] == '')) $b['value'] = '.';
142			switch($b['test']) {
143				case '=' :
144				case 'eq' :
145				case '==' :
146					return (auth_quickaclcheck($b['value']) >= AUTH_EDIT); break;
147				case '!=' :
148				case 'ne' :
149				case 'neq' :
150					return (auth_quickaclcheck($b['value']) < AUTH_EDIT); break;
151				default:
152					$bug = true;
153					return false;
154			}
155		}
156
157		// time based tests
158		function test_time($b, &$bug, $lop=false) {
159			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\<\=?', 'lt', '\>\=?', 'gt');
160			global $INFO;
161			if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '')) {
162				$bug = true;
163				return false;
164			}
165			switch($b['test']) {
166				case '=' :
167				case 'eq' :
168				case '==' :
169					return $this->_bt_cmptimeandstr($b['value']); break;
170				case '!=' :
171				case 'ne' :
172				case 'neq' :
173					return !$this->_bt_cmptimeandstr($b['value']); break;
174				case '<' :
175				case 'lt' :
176					$t = time();
177					return ($t < $this->_bt_strtotime($b['value'], $t)); break;
178				case '>' :
179				case 'gt' :
180					$t = time();
181					return ($t > $this->_bt_strtotime($b['value'], $t)); break;
182				case '<=' :
183					$t = time();
184					return ($t <= $this->_bt_strtotime($b['value'], $t)); break;
185				case '>=' :
186					$t = time();
187					return ($t >= $this->_bt_strtotime($b['value'], $t)); break;
188				default:
189					$bug = true;
190					return false;
191			}
192		}
193		function _bt_strtotime($value, $default) {
194			if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $value, $reg)) $value = mktime($reg[7], $reg[8], $reg[10], $reg[3], $reg[5], $reg[1]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)?
195			if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})$`', $value, $reg)) $value = mktime($reg[2], $reg[3], $reg[5], $reg[8], $reg[10], $reg[6]); // (HH:II(:SS)?)? YYYY(-|/)MM(-|/)DD
196			if(preg_match('`^([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $value, $reg)) $value = mktime($reg[7], $reg[8], $reg[10], $reg[3], $reg[1], $reg[5]); // DD(-|/)MM(-|/)YYYY (HH:II(:SS)?)?
197			if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})$`', $value, $reg)) $value = mktime($reg[2], $reg[3], $reg[5], $reg[8], $reg[6], $reg[10]); // (HH:II(:SS)?)? DD(-|/)MM(-|/)YYYY
198			if(!is_numeric($value)) $value = $default;
199			return $value;
200		}
201		function _bt_cmptimeandstr($str) {
202			$matched = false;
203			$t = time();
204			$time = array('y' => date('Y', $t), 'm' => date('m', $t), 'd' => date('d', $t), 'h' => date('H', $t), 'i' => date('i', $t), 's' => date('s', $t));
205			$d = array('y' => '', 'm' => '', 'd' => '', 'h' => '', 'i' => '', 's' => '');
206
207			// full date y, m and d, time is optionnal
208			if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) {
209				$d = array('y' => $reg[1], 'm' => $reg[3], 'd' => $reg[5], 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)?
210				$matched = true;
211			}
212			if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{4})(-|/)([0-9]{2})(-|/)([0-9]{2})$`', $str, $reg)) {
213				$d = array('y' => $reg[6], 'm' => $reg[8], 'd' => $reg[10], 'h' => $reg[2], 'i' => $reg[3], 's' => $reg[5]); // (HH:II(:SS)?)? YYYY(-|/)MM(-|/)DD
214				$matched = true;
215			}
216			if(preg_match('`^([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})(\s+([0-9]{2}):([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) {
217				$d = array('y' => $reg[5], 'm' => $reg[3], 'd' => $reg[1], 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // DD(-|/)MM(-|/)YYYY (HH:II(:SS)?)?
218				$matched = true;
219			}
220			if(preg_match('`^(([0-9]{2}):([0-9]{2})(:([0-9]{2}))?\s+)?([0-9]{2})(-|/)([0-9]{2})(-|/)([0-9]{4})$`', $str, $reg)) {
221				$d = array('y' => $reg[10], 'm' => $reg[8], 'd' => $reg[6], 'h' => $reg[2], 'i' => $reg[3], 's' => $reg[5]); // (HH:II(:SS)?)? DD(-|/)MM(-|/)YYYY
222				$matched = true;
223			}
224
225			// only month and year
226			if(preg_match('`^([0-9]{2})(-|/)([0-9]{4})$`', $str, $reg)) {
227				$d = array('y' => $reg[3], 'm' => $reg[1], 'd' => '', 'h' => '', 'i' => '', 's' => '');
228				$matched = true;
229			}
230			if(preg_match('`^([0-9]{4})(-|/)([0-9]{2})$`', $str, $reg)) {
231				$d = array('y' => $reg[1], 'm' => $reg[3], 'd' => '', 'h' => '', 'i' => '', 's' => '');
232				$matched = true;
233			}
234
235			// only year
236			if(preg_match('`^([0-9]{4})$`', $str, $reg)) {
237				$d = array('y' => $reg[1], 'm' => '', 'd' => '', 'h' => '', 'i' => '', 's' => '');
238				$matched = true;
239			}
240
241			// full time hours, minutes (opt) and seconds (opt)
242			// 11 : 11h
243			// 11:30 : 11h30min
244			// 11:30:27 : 11h30min27sec
245			if(preg_match('`^([0-9]{2})(:([0-9]{2})(:([0-9]{2}))?)?$`', $str, $reg)) {
246				$d = array('y' => '', 'm' => '', 'd' => '', 'h' => $reg[7], 'i' => $reg[8], 's' => $reg[10]); // YYYY(-|/)MM(-|/)DD (HH:II(:SS)?)?
247				$matched = true;
248			}
249
250			// custom datetime format : (XX(XX)?i\s?)+
251			if(preg_match('`^[0-9]{2}([0-9]{2})?\s?[ymdhis](\s?[0-9]{2}([0-9]{2})?\s?[ymdhis])*$`', $str, $reg)) {
252				while(preg_match('`^(([0-9]{2}([0-9]{2})?)\s?([ymdhis]))`', $str, $reg)) {
253					$v = $reg[2];
254					$i = $reg[4];
255					$str = substr($str, strlen($reg[1]));
256					if(($i != 'y') || (strlen($v) == 4)) $d[$i] = $v;
257				}
258				$matched = true;
259			}
260
261			if(!$matched) return false;
262			$same = true;
263			foreach($time as $k => $v) if(($d[$k] != '') && ($d[$k] != $v)) $same = false;
264			return $same;
265		}
266
267		// test IP
268		function test_IP($b, &$bug, $lop=false) {
269			if($lop) return array('\=\=?', 'eq', '\!\=', 'neq?', '\~\=');
270			$ip = clientIP(true);
271			if(!$b['test'] || ($b['test'] == '') || !$b['value'] || ($b['value'] == '') || ($ip == '0.0.0.0')) {
272				$bug = true;
273				return false;
274			}
275			switch($b['test']) {
276				case '=' :
277				case 'eq' :
278				case '==' :
279					return ($ip == $b['value']); break;
280				case '!=' :
281				case 'ne' :
282				case 'neq' :
283					return ($ip != $b['value']); break;
284				case '~=' :
285					return (strpos($ip, $b['value']) !== false); break;
286				default:
287					$bug = true;
288					return false;
289			}
290		}
291	}
292?>
293