1<?php
2	/**
3	* Setup
4	* @author Joseph Engo<jengo@phpgroupware.org>
5	* @author Dan Kuykendall<seek3r@phpgroupware.org>
6	* @author Mark Peters<skeeter@phpgroupware.org>
7	* @author Miles Lott<milosch@phpgroupware.org>
8	* @copyright Portions Copyright (C) 2001-2004 Free Software Foundation, Inc. http://www.fsf.org/
9	* @license http://www.fsf.org/licenses/gpl.html GNU General Public License
10	* @package phpgwapi
11	* @subpackage application
12	* @version $Id: class.setup.inc.php 19074 2009-02-16 10:36:45Z skwashd $
13	*/
14
15	/**
16	* Setup
17	*
18	* @package phpgwapi
19	* @subpackage application
20	*/
21	class setup
22	{
23		var $db;
24		var $oProc;
25
26		var $detection = '';
27		var $process = '';
28		var $lang = '';
29		var $html = '';
30		var $appreg = '';
31
32		/* table name vars */
33		var $tbl_apps;
34		var $tbl_config;
35		var $tbl_hooks;
36
37		function setup($html=False, $translation=False)
38		{
39			$this->detection = CreateObject('phpgwapi.setup_detection');
40			$this->process   = CreateObject('phpgwapi.setup_process');
41
42			/* The setup application needs these */
43			$this->html	= $html ? CreateObject('phpgwapi.setup_html') : '';
44			$this->translation = $translation ? CreateObject('phpgwapi.setup_translation') : '';
45
46			//$this->tbl_apps    = $this->get_apps_table_name();
47			//$this->tbl_config  = $this->get_config_table_name();
48                	$this->tbl_hooks   = $this->get_hooks_table_name();
49		}
50
51		/*!
52		@function loaddb
53		@abstract include api db class for the ConfigDomain and connect to the db
54		*/
55		function loaddb()
56		{
57			$GLOBALS['ConfigDomain'] = get_var('ConfigDomain',array('COOKIE','POST'),$_POST['FormDomain']);
58
59			$GLOBALS['phpgw_info']['server']['db_type'] = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_type'];
60
61			$this->db	  = CreateObject('phpgwapi.db');
62			$this->db->Host     = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_host'];
63			$this->db->Type     = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_type'];
64			$this->db->Database = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_name'];
65			$this->db->User     = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_user'];
66			$this->db->Password = $GLOBALS['phpgw_domain'][$GLOBALS['ConfigDomain']]['db_pass'];
67		}
68
69		/*!
70		@function auth
71		@abstract authenticate the setup user
72		@param	$auth_type	???
73		*/
74		function auth($auth_type='Config')
75		{
76			$remoteip     = $_SERVER['REMOTE_ADDR'];
77
78			$FormLogout   = get_var('FormLogout',  array('GET','POST'));
79			$ConfigLogin  = get_var('ConfigLogin', array('POST'));
80			$HeaderLogin  = get_var('HeaderLogin', array('POST'));
81			$FormDomain   = get_var('FormDomain',  array('POST'));
82			$FormPW       = stripslashes(get_var('FormPW',      array('POST')));
83
84			$ConfigDomain = get_var('ConfigDomain',array('POST','COOKIE'));
85			$ConfigPW     = get_var('ConfigPW',    array('POST','COOKIE'));
86			$HeaderPW     = get_var('HeaderPW',    array('POST','COOKIE'));
87			$ConfigLang   = get_var('ConfigLang',  array('POST','COOKIE'));
88
89			/*
90			if(!empty($remoteip) && !$this->checkip($remoteip))
91			{
92				return False;
93			}
94			*/
95
96			/* 6 cases:
97				1. Logging into header admin
98				2. Logging into config admin
99				3. Logging out of config admin
100				4. Logging out of header admin
101				5. Return visit to config OR header
102				6. None of the above
103			*/
104
105			$expire = time() + 1200; /* Expire login if idle for 20 minutes. */
106
107			if(!empty($HeaderLogin) && $auth_type == 'Header')
108			{
109				/* header admin login */
110				if($FormPW == stripslashes($GLOBALS['phpgw_info']['server']['header_admin_password']))
111				{
112					setcookie('HeaderPW',md5($FormPW),$expire);
113					setcookie('ConfigLang',$ConfigLang,$expire);
114					return True;
115				}
116				else
117				{
118					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = lang('Invalid password');
119					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = '';
120					return False;
121				}
122			}
123			elseif(!empty($ConfigLogin) && $auth_type == 'Config')
124			{
125				/* config login */
126				if($FormPW == stripslashes(@$GLOBALS['phpgw_domain'][$FormDomain]['config_passwd']))
127				{
128					setcookie('ConfigPW', md5($FormPW), $expire);
129					setcookie('ConfigDomain', $FormDomain, $expire);
130					setcookie('ConfigLang', $ConfigLang, $expire);
131					return True;
132				}
133				else
134				{
135					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = lang('Invalid password');
136					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = '';
137					return False;
138				}
139			}
140			elseif(!empty($FormLogout))
141			{
142				/* logout */
143				if($FormLogout == 'config')
144				{
145					/* config logout */
146					setcookie('ConfigPW','');
147					$GLOBALS['phpgw_info']['setup']['LastDomain'] = $_COOKIE['ConfigDomain'];
148					setcookie('ConfigDomain','');
149					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = lang('You have successfully logged out');
150					setcookie('ConfigLang','');
151					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = '';
152
153					return False;
154				}
155				elseif($FormLogout == 'header')
156				{
157					/* header admin logout */
158					setcookie('HeaderPW','');
159					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = lang('You have successfully logged out');
160					setcookie('ConfigLang','');
161					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = '';
162
163					return False;
164				}
165			}
166			elseif(!empty($ConfigPW) && $auth_type == 'Config')
167			{
168				/* Returning after login to config */
169				if($ConfigPW == md5(stripslashes($GLOBALS['phpgw_domain'][$ConfigDomain]['config_passwd'])))
170				{
171					setcookie('ConfigPW', $ConfigPW,  $expire);
172					setcookie('ConfigDomain', $ConfigDomain, $expire);
173					setcookie('ConfigLang', $ConfigLang, $expire);
174					return True;
175				}
176				else
177				{
178					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = lang('Invalid password');
179					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = '';
180					return False;
181				}
182			}
183			elseif(!empty($HeaderPW) && $auth_type == 'Header')
184			{
185				/* Returning after login to header admin */
186				if($HeaderPW == md5(stripslashes($GLOBALS['phpgw_info']['server']['header_admin_password'])))
187				{
188					setcookie('HeaderPW', $HeaderPW , $expire);
189					setcookie('ConfigLang', $ConfigLang, $expire);
190					return True;
191				}
192				else
193				{
194					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = lang('Invalid password');
195					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = '';
196					return False;
197				}
198			}
199			else
200			{
201				$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = '';
202				$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = '';
203				return False;
204			}
205		}
206
207		function checkip($remoteip='')
208		{
209			$allowed_ips = split(',',$GLOBALS['phpgw_info']['server']['setup_acl']);
210			if(is_array($allowed_ips))
211			{
212				$foundip = False;
213				while(list(,$value) = @each($allowed_ips))
214				{
215					$test = split("\.",$value);
216					if(count($test) < 3)
217					{
218						$value .= ".0.0";
219						$tmp = split("\.",$remoteip);
220						$tmp[2] = 0;
221						$tmp[3] = 0;
222						$testremoteip = join('.',$tmp);
223					}
224					elseif(count($test) < 4)
225					{
226						$value .= ".0";
227						$tmp = split("\.",$remoteip);
228						$tmp[3] = 0;
229						$testremoteip = join('.',$tmp);
230					}
231					elseif(count($test) == 4 &&
232						intval($test[3]) == 0)
233					{
234						$tmp = split("\.",$remoteip);
235						$tmp[3] = 0;
236						$testremoteip = join('.',$tmp);
237					}
238					else
239					{
240						$testremoteip = $remoteip;
241					}
242
243					//echo '<br />testing: ' . $testremoteip . ' compared to ' . $value;
244
245					if($testremoteip == $value)
246					{
247						//echo ' - PASSED!';
248						$foundip = True;
249					}
250				}
251				if(!$foundip)
252				{
253					$GLOBALS['phpgw_info']['setup']['HeaderLoginMSG'] = '';
254					$GLOBALS['phpgw_info']['setup']['ConfigLoginMSG'] = lang('Invalid IP address');
255					return False;
256				}
257			}
258			return True;
259		}
260
261		/*!
262		@function get_major
263		@abstract Return X.X.X major version from X.X.X.X versionstring
264		@param	$
265		*/
266		function get_major($versionstring)
267		{
268			if(!$versionstring)
269			{
270				return False;
271			}
272
273			$version = str_replace('pre','.',$versionstring);
274			$varray  = explode('.',$version);
275			$major   = implode('.',array($varray[0],$varray[1],$varray[2]));
276
277			return $major;
278		}
279
280		/*!
281		@function clear_session_cache
282		@abstract Clear system/user level cache so as to have it rebuilt with the next access
283		@param	None
284		*/
285		function clear_session_cache()
286		{
287			$tables = Array();
288			$tablenames = $this->db->table_names();
289			foreach($tablenames as $key => $val)
290			{
291				$tables[] = $val['table_name'];
292			}
293			if(in_array('phpgw_app_sessions',$tables))
294			{
295				$this->db->lock(array('phpgw_app_sessions'));
296				@$this->db->query("DELETE FROM phpgw_app_sessions WHERE sessionid = '0' and loginid = '0' and app = 'phpgwapi' and location = 'config'",__LINE__,__FILE__);
297				@$this->db->query("DELETE FROM phpgw_app_sessions WHERE app = 'phpgwapi' and location = 'phpgw_info_cache'",__LINE__,__FILE__);
298				$this->db->unlock();
299			}
300		}
301
302		/*!
303		@function register_app
304		@abstract Add an application to the phpgw_applications table
305		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
306		@param	$enable		optional, set to True/False to override setup.inc.php setting
307		*/
308		function register_app($appname,$enable=99)
309		{
310			$setup_info = $GLOBALS['setup_info'];
311
312			if(!$appname)
313			{
314				return False;
315			}
316
317			if($enable==99)
318			{
319				$enable = $setup_info[$appname]['enable'];
320			}
321			$enable = intval($enable);
322
323			if($GLOBALS['DEBUG'])
324			{
325				echo '<br>register_app(): ' . $appname . ', version: ' . $setup_info[$appname]['version'] . ', table: phpgw_applications<br>';
326			}
327
328			if($setup_info[$appname]['version'])
329			{
330				if($setup_info[$appname]['tables'])
331				{
332					$tables = implode(',',$setup_info[$appname]['tables']);
333				}
334				if ($setup_info[$appname]['tables_use_prefix'] == True)
335				{
336					echo $setup_info[$appname]['name'] . ' uses tables_use_prefix, storing '
337					. $setup_info[$appname]['tables_prefix']
338						. ' as prefix for ' . $setup_info[$appname]['name'] . " tables\n";
339
340					$sql = "INSERT INTO phpgw_config (config_app,config_name,config_value) "
341						."VALUES ('".$setup_info[$appname]['name']."','"
342						.$appname."_tables_prefix','".$setup_info[$appname]['tables_prefix']."')";
343					$this->db->query($sql,__LINE__,__FILE__);
344				}
345				$this->db->query("INSERT INTO phpgw_applications "
346					. "(app_name,app_enabled,app_order,app_tables,app_version) "
347					. "VALUES ("
348					. "'" . $setup_info[$appname]['name'] . "',"
349					. $enable . ","
350					. intval($setup_info[$appname]['app_order']) . ","
351					. "'" . $tables . "',"
352					. "'" . $setup_info[$appname]['version'] . "')"
353					,__LINE__,__FILE__
354				);
355				$this->clear_session_cache();
356			}
357		}
358
359		/*!
360		@function app_registered
361		@abstract Check if an application has info in the db
362		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
363		@param	$enabled	optional, set to False to not enable this app
364		*/
365		function app_registered($appname)
366		{
367			$setup_info = $GLOBALS['setup_info'];
368
369			if(!$appname)
370			{
371				return False;
372			}
373
374			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != ''))
375			{
376				$appstbl = 'applications';
377			}
378			else
379			{
380				$appstbl = 'phpgw_applications';
381			}
382
383			if(@$GLOBALS['DEBUG'])
384			{
385				echo '<br />app_registered(): checking ' . $appname . ', table: ' . $appstbl;
386				// _debug_array($setup_info[$appname]);
387			}
388
389			$this->db->query("SELECT COUNT(app_name) FROM $appstbl WHERE app_name='".$appname."'",__LINE__,__FILE__);
390			$this->db->next_record();
391			if($this->db->f(0))
392			{
393				if(@$GLOBALS['DEBUG'])
394				{
395					echo '... app previously registered.';
396				}
397				return True;
398			}
399			if(@$GLOBALS['DEBUG'])
400			{
401				echo '... app not registered';
402			}
403			return False;
404		}
405
406		/*!
407		@function update_app
408		@abstract Update application info in the db
409		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
410		@param	$enabled	optional, set to False to not enable this app
411		*/
412		function update_app($appname)
413		{
414			$setup_info = $GLOBALS['setup_info'];
415
416			if(!$appname)
417			{
418				return False;
419			}
420
421			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != ''))
422			{
423				$appstbl = 'applications';
424			}
425			else
426			{
427				$appstbl = 'phpgw_applications';
428			}
429
430			if($GLOBALS['DEBUG'])
431			{
432				echo '<br />update_app(): ' . $appname . ', version: ' . $setup_info[$appname]['currentver'] . ', table: ' . $appstbl . '<br />';
433				// _debug_array($setup_info[$appname]);
434			}
435
436			$this->db->query("SELECT COUNT(app_name) FROM $appstbl WHERE app_name='".$appname."'",__LINE__,__FILE__);
437			$this->db->next_record();
438			if(!$this->db->f(0))
439			{
440				return False;
441			}
442
443			if($setup_info[$appname]['version'])
444			{
445				//echo '<br />' . $setup_info[$appname]['version'];
446				if($setup_info[$appname]['tables'])
447				{
448					$tables = implode(',',$setup_info[$appname]['tables']);
449				}
450
451				$sql = "UPDATE $appstbl "
452					. "SET app_name='" . $setup_info[$appname]['name'] . "',"
453					. " app_enabled=" . intval($setup_info[$appname]['enable']) . ","
454					. " app_order=" . intval($setup_info[$appname]['app_order']) . ","
455					. " app_tables='" . $tables . "',"
456					. " app_version='" . $setup_info[$appname]['version'] . "'"
457					. " WHERE app_name='" . $appname . "'";
458				//echo $sql; exit;
459
460				$this->db->query($sql,__LINE__,__FILE__);
461			}
462		}
463
464		/*!
465		@function update_app_version
466		@abstract Update application version in applications table, post upgrade
467		@param	$setup_info		Array of application information (multiple apps or single)
468		@param	$appname		Application 'name' with a matching $setup_info[$appname] array slice
469		@param	$tableschanged	???
470		*/
471		function update_app_version($setup_info, $appname, $tableschanged = True)
472		{
473			if(!$appname)
474			{
475				return False;
476			}
477
478			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != ''))
479			{
480				$appstbl = 'applications';
481			}
482			else
483			{
484				$appstbl = 'phpgw_applications';
485			}
486
487			if($tableschanged == True)
488			{
489				$GLOBALS['phpgw_info']['setup']['tableschanged'] = True;
490			}
491			if($setup_info[$appname]['currentver'])
492			{
493				$this->db->query("UPDATE $appstbl SET app_version='" . $setup_info[$appname]['currentver'] . "' WHERE app_name='".$appname."'",__LINE__,__FILE__);
494			}
495			return $setup_info;
496		}
497
498		/*!
499		@function deregister_app
500		@abstract de-Register an application
501		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
502		*/
503		function deregister_app($appname)
504		{
505			if(!$appname)
506			{
507				return False;
508			}
509			$setup_info = $GLOBALS['setup_info'];
510
511			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.10pre8') && ($setup_info['phpgwapi']['currentver'] != ''))
512			{
513				$appstbl = 'applications';
514			}
515			else
516			{
517				$appstbl = 'phpgw_applications';
518			}
519
520			//echo 'DELETING application: ' . $appname;
521			$this->db->query("DELETE FROM $appstbl WHERE app_name='". $appname ."'",__LINE__,__FILE__);
522			$this->clear_session_cache();
523		}
524
525		/*!
526		@function register_hooks
527		@abstract Register an application's hooks
528		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
529		*/
530		function register_hooks($appname)
531		{
532			$setup_info = $GLOBALS['setup_info'];
533
534			if(!$appname)
535			{
536				return False;
537			}
538
539			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.8pre5') && ($setup_info['phpgwapi']['currentver'] != ''))
540			{
541				/* No phpgw_hooks table yet. */
542				return False;
543			}
544
545			if (!is_object($this->hooks))
546			{
547				$this->hooks = CreateObject('phpgwapi.hooks',$this->db);
548			}
549			$this->hooks->register_hooks($appname,$setup_info[$appname]['hooks']);
550		}
551
552		/*!
553		@function update_hooks
554		@abstract Update an application's hooks
555		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
556		*/
557		function update_hooks($appname)
558		{
559			$this->register_hooks($appname);
560		}
561
562		/*!
563		@function deregister_hooks
564		@abstract de-Register an application's hooks
565		@param	$appname	Application 'name' with a matching $setup_info[$appname] array slice
566		*/
567		function deregister_hooks($appname)
568		{
569			if($this->alessthanb($setup_info['phpgwapi']['currentver'],'0.9.8pre5'))
570			{
571				/* No phpgw_hooks table yet. */
572				return False;
573			}
574
575			if(!$appname)
576			{
577				return False;
578			}
579
580			//echo "DELETING hooks for: " . $setup_info[$appname]['name'];
581			if (!is_object($this->hooks))
582			{
583				$this->hooks = CreateObject('phpgwapi.hooks',$this->db);
584			}
585			$this->hooks->register_hooks($appname);
586		}
587
588		/*!
589		 @function hook
590		 @abstract call the hooks for a single application
591		 @param $location hook location - required
592		 @param $appname application name - optional
593		*/
594		function hook($location, $appname='')
595		{
596			if (!is_object($this->hooks))
597			{
598				$this->hooks = CreateObject('phpgwapi.hooks',$this->db);
599			}
600			return $this->hooks->single($location,$appname,True,True);
601		}
602
603		/*
604		@function alessthanb
605		@abstract phpgw version checking, is param 1 < param 2 in phpgw versionspeak?
606		@param	$a	phpgw version number to check if less than $b
607		@param	$b	phpgw version number to check $a against
608		#return	True if $a < $b
609		*/
610		function alessthanb($a,$b,$DEBUG=False)
611		{
612			$num = array('1st','2nd','3rd','4th');
613
614			if($DEBUG)
615			{
616				echo'<br />Input values: '
617					. 'A="'.$a.'", B="'.$b.'"';
618			}
619			$newa = ereg_replace('pre','.',$a);
620			$newb = ereg_replace('pre','.',$b);
621			$testa = explode('.',$newa);
622			if(@$testa[1] == '')
623			{
624				$testa[1] = 0;
625			}
626			if(@$testa[3] == '')
627			{
628				$testa[3] = 0;
629			}
630			$testb = explode('.',$newb);
631			if(@$testb[1] == '')
632			{
633				$testb[1] = 0;
634			}
635			if(@$testb[3] == '')
636			{
637				$testb[3] = 0;
638			}
639			$less = 0;
640
641			for($i=0;$i<count($testa);$i++)
642			{
643				if($DEBUG) { echo'<br />Checking if '. intval($testa[$i]) . ' is less than ' . intval($testb[$i]) . ' ...'; }
644				if(intval($testa[$i]) < intval($testb[$i]))
645				{
646					if ($DEBUG) { echo ' yes.'; }
647					$less++;
648					if($i<3)
649					{
650						/* Ensure that this is definitely smaller */
651						if($DEBUG) { echo"  This is the $num[$i] octet, so A is definitely less than B."; }
652						$less = 5;
653						break;
654					}
655				}
656				elseif(intval($testa[$i]) > intval($testb[$i]))
657				{
658					if($DEBUG) { echo ' no.'; }
659					$less--;
660					if($i<2)
661					{
662						/* Ensure that this is definitely greater */
663						if($DEBUG) { echo"  This is the $num[$i] octet, so A is definitely greater than B."; }
664						$less = -5;
665						break;
666					}
667				}
668				else
669				{
670					if($DEBUG) { echo ' no, they are equal.'; }
671					$less = 0;
672				}
673			}
674			if($DEBUG) { echo '<br />Check value is: "'.$less.'"'; }
675			if($less>0)
676			{
677				if($DEBUG) { echo '<br />A is less than B'; }
678				return True;
679			}
680			elseif($less<0)
681			{
682				if($DEBUG) { echo '<br />A is greater than B'; }
683				return False;
684			}
685			else
686			{
687				if($DEBUG) { echo '<br />A is equal to B'; }
688				return False;
689			}
690		}
691
692		/*!
693		@function amorethanb
694		@abstract phpgw version checking, is param 1 > param 2 in phpgw versionspeak?
695		@param	$a	phpgw version number to check if more than $b
696		@param	$b	phpgw version number to check $a against
697		#return	True if $a < $b
698		*/
699		function amorethanb($a,$b,$DEBUG=False)
700		{
701			$num = array('1st','2nd','3rd','4th');
702
703			if($DEBUG)
704			{
705				echo'<br />Input values: '
706					. 'A="'.$a.'", B="'.$b.'"';
707			}
708			$newa = ereg_replace('pre','.',$a);
709			$newb = ereg_replace('pre','.',$b);
710			$testa = explode('.',$newa);
711			if($testa[3] == '')
712			{
713				$testa[3] = 0;
714			}
715			$testb = explode('.',$newb);
716			if($testb[3] == '')
717			{
718				$testb[3] = 0;
719			}
720			$less = 0;
721
722			for($i=0;$i<count($testa);$i++)
723			{
724				if($DEBUG) { echo'<br />Checking if '. intval($testa[$i]) . ' is more than ' . intval($testb[$i]) . ' ...'; }
725				if(intval($testa[$i]) > intval($testb[$i]))
726				{
727					if($DEBUG) { echo ' yes.'; }
728					$less++;
729					if($i<3)
730					{
731						/* Ensure that this is definitely greater */
732						if($DEBUG) { echo"  This is the $num[$i] octet, so A is definitely greater than B."; }
733						$less = 5;
734						break;
735					}
736				}
737				elseif(intval($testa[$i]) < intval($testb[$i]))
738				{
739					if($DEBUG) { echo ' no.'; }
740					$less--;
741					if($i<2)
742					{
743						/* Ensure that this is definitely smaller */
744						if($DEBUG) { echo"  This is the $num[$i] octet, so A is definitely less than B."; }
745						$less = -5;
746						break;
747					}
748				}
749				else
750				{
751					if($DEBUG) { echo ' no, they are equal.'; }
752					$less = 0;
753				}
754			}
755			if($DEBUG) { echo '<br />Check value is: "'.$less.'"'; }
756			if($less>0)
757			{
758				if($DEBUG) { echo '<br />A is greater than B'; }
759				return True;
760			}
761			elseif($less<0)
762			{
763				if($DEBUG) { echo '<br />A is less than B'; }
764				return False;
765			}
766			else
767			{
768				if($DEBUG) { echo '<br />A is equal to B'; }
769				return False;
770			}
771		}
772
773		function get_hooks_table_name()
774		{
775			if($this->alessthanb($GLOBALS['setup_info']['phpgwapi']['currentver'],'0.9.8pre5') && ($GLOBALS['setup_info']['phpgwapi']['currentver'] != ''))
776			{
777				/* No phpgw_hooks table yet. */
778				return False;
779			}
780			return 'phpgw_hooks';
781		}
782}
783?>
784