1<?php
2/**
3 * Configuration processing and defaults.
4 *
5 * @author The phpLDAPadmin development team
6 * @package phpLDAPadmin
7 * @todo Add validation of set variables to enforce limits or particular values.
8 */
9
10/** The minimum version of PHP required to run phpLDAPadmin. */
11define('REQUIRED_PHP_VERSION','7.0.0');
12
13/**
14 * The config class contains all our configuration settings for a session.
15 *
16 * An instance of this class should be stored in $_SESSION to maintain state, and to avoid
17 * rebuilding/rereading it at the state of each page output.
18 *
19 * @package phpLDAPadmin
20 * @subpackage Tree
21 */
22class Config {
23	public $custom;
24	protected $default;
25	protected $servers = array();
26
27	public $hooks = array();
28
29	public function __construct() {
30		$this->custom = new stdClass;
31		$this->default = new stdClass;
32
33		/*
34		 * What to do after entry creation :
35		 * 2 : display the creation form again
36		 * 1 : display the new created entry
37		 * 0 : display the choice between 1 and 2
38		 */
39		$this->default->appearance['action_after_creation'] = array(
40			'desc'=>'Display the new created entry',
41			'default'=>1);
42
43		## Appearance Attributes
44		/** Anonymous implies read only
45		 * Set to true if you want LDAP data to be displayed read-only (without input fields)
46		 * when a user logs in to a server anonymously
47		 */
48		$this->default->appearance['anonymous_bind_implies_read_only'] = array(
49			'desc'=>'Display as read only if user logs in with anonymous bind',
50			'default'=>true);
51
52		$this->default->appearance['attr_display_order'] = array(
53			'desc'=>'Custom order to display attributes',
54			'default'=>array());
55
56		/*
57		* @todo Compression is not working,
58		* purge_cache shows blank,
59		* tree refresh shows blank - and if view_tree_node is modified to compress output, then previously opened items show up as compressed data.
60		*/
61		$this->default->appearance['compress'] = array(
62			'desc'=>'Compress Output',
63			'untested'=>true,
64			'default'=>false);
65
66		$this->default->appearance['control_icons'] = array(
67			'desc'=>'Show the control as icons or text',
68			'default'=>false);
69
70		$this->default->appearance['custom_templates_only'] = array(
71			'desc'=>'Only display the custom templates.',
72			'default'=>false);
73
74		$this->default->appearance['date'] = array(
75			'desc'=>'Date format whenever dates are shown',
76			'default'=>'%A %e %B %Y');
77
78		$this->default->appearance['date_attrs'] = array(
79			'desc'=>'Array of attributes that should show a jscalendar',
80			'default'=>array('shadowExpire'=>'%es','shadowLastChange'=>'%es'));
81
82		$this->default->appearance['date_attrs_showtime'] = array(
83			'desc'=>'Array of attributes that should show a the time when showing the jscalendar',
84			'default'=>array(''));
85
86		$this->default->appearance['disable_default_template'] = array(
87			'desc'=>'Disabled the Default Template',
88			'default'=>false);
89
90		$this->default->appearance['disable_default_leaf'] = array(
91			'desc'=>'Disabled creating leaf entries in the Default Template',
92			'default'=>false);
93
94		$this->default->appearance['friendly_attrs'] = array(
95			'desc'=>'Friendly names for attributes',
96			'default'=>array());
97
98		$this->default->appearance['hide_attrs'] = array(
99			'desc'=>'Hide attributes from display',
100			'default'=>array());
101
102		$this->default->appearance['hide_attrs_exempt'] = array(
103			'desc'=>'Group DN, where membership will exempt the users from hide_attrs',
104			'default'=>null);
105
106		$this->default->appearance['hide_debug_info'] = array(
107			'desc'=>'Hide the features that may provide sensitive debugging information to the browser',
108			'default'=>true);
109
110		$this->default->appearance['hide_template_regexp'] = array(
111			'desc'=>'Templates that are disabled by their regex are not shown',
112			'default'=>false);
113
114		$this->default->appearance['hide_template_warning'] = array(
115			'desc'=>'Hide template errors from being displayed',
116			'default'=>false);
117
118		/** Language
119		 * The language setting. If you set this to 'auto', phpLDAPadmin will
120		 * attempt to determine your language automatically. Otherwise, set
121		 * this to your applicable language in xx_XX format.
122		 * Localization is not complete yet, but most strings have been translated.
123		 * Please help by writing language files.
124		 */
125		$this->default->appearance['language'] = array(
126			'desc'=>'Language',
127			'default'=>'auto');
128
129		$this->default->appearance['max_add_attrs'] = array(
130			'desc'=>'Maximum number of attrs to show in the add attr form',
131			'default'=>10);
132
133		/**
134		 * If you want certain attributes to be editable as multi-line, include them in this list
135		 * A multi-line textarea will be drawn instead of a single-line text field
136		 */
137		$this->default->appearance['multi_line_attributes'] = array(
138			'desc'=>'Attributes to show as multiline attributes',
139			'default'=>array('postalAddress','homePostalAddress','personalSignature','description','mailReplyText'));
140
141		/**
142		 * A list of syntax OIDs which support multi-line attribute values:
143		 */
144		$this->default->appearance['multi_line_syntax_oids'] = array(
145			'desc'=>'Attributes to show as multiline attributes',
146			'default'=>array(
147				// octet string syntax OID:
148				'1.3.6.1.4.1.1466.115.121.1.40',
149				// postal address syntax OID:
150				'1.3.6.1.4.1.1466.115.121.1.41'));
151
152		/** Obfuscate Password
153		 * If true, display all password hash values as "******". Note that clear-text
154		 * passwords will always be displayed as "******", regardless of this setting.
155		 */
156		$this->default->appearance['obfuscate_password_display'] = array(
157			'desc'=>'Obfuscate the display of passwords',
158			'default'=>true);
159
160		$this->default->appearance['page_title'] = array(
161			'desc'=>'Change the page title to this text',
162			'default'=>'');
163
164		$this->default->appearance['rdn_all_attrs'] = array(
165			'desc'=>'Whether to show all attributes in the RDN chooser, or just the required ones',
166			'default'=>true);
167
168		$this->default->appearance['readonly_attrs'] = array(
169			'desc'=>'Mark these attributes as readonly',
170			'default'=>array());
171
172		$this->default->appearance['readonly_attrs_exempt'] = array(
173			'desc'=>'Group DN, where membership will exempt the users from readonly attrs',
174			'default'=>null);
175
176		$this->default->appearance['remoteurls'] = array(
177			'desc'=>'Whether to include renders for remote URLs',
178			'default'=>true);
179
180		$this->default->appearance['show_clear_password'] = array(
181			'desc'=>'Whether to show clear passwords if we dont obfuscate them',
182			'default'=>false);
183
184		$this->default->appearance['show_hints'] = array(
185			'desc'=>'Show helpful hints',
186			'default'=>true);
187
188		$this->default->appearance['show_top_create'] = array(
189			'desc'=>'Show a additional create link on the top of the list if there are more than 10 entries',
190			'default'=>true);
191
192		$this->default->appearance['show_schema_link'] = array(
193			'desc'=>'Show the schema link for each attribute',
194			'default'=>true);
195
196		$this->default->appearance['show_attribute_notes'] = array(
197			'desc'=>'Show notes for each attribute',
198			'default'=>true);
199
200		$this->default->appearance['stylesheet'] = array(
201			'desc'=>'Style sheet to use',
202			'default'=>'style.css');
203
204		$this->default->appearance['theme'] = array(
205			'desc'=>'Which theme to use',
206			'default'=>'default');
207
208		$this->default->appearance['timezone'] = array(
209			'desc'=>'Define our timezone, if not defined in php.ini',
210			'default'=>null);
211
212		$this->default->appearance['tree'] = array(
213			'desc'=>'Class name which inherits from Tree class and implements the draw() method',
214			'default'=>'AJAXTree');
215
216		/** Tree display
217		 * An array of format strings used to display enties in the
218		 * tree viewer (left-hand side). The first format string that
219		 * is completely defined (i.e., does not reference attributes
220		 * that are not defined the object). If there is no format
221		 * string that is completely defined, the last one is used.
222		 *
223		 * You can use special tokens to draw the entries as you wish.
224		 * You can even mix in HTML to format the string.
225		 * Here are all the tokens you can use:
226		 *	%rdn - draw the RDN of the entry (ie, "cn=Dave")
227		 *	%dn - draw the DN of the entry (ie, "cn=Dave,ou=People,dc=example,dc=com"
228		 *	%rdnValue - draw the value of the RDN (ie, instead of "cn=Dave", just draw "Dave")
229		 *	%[attrname]- draw the value (or values) of the specified attribute.
230		 *	 example: %gidNumber
231		 *
232		 * Any multivalued attributes will be displayed as a comma separated list.
233		 *
234		 * Examples:
235		 *
236		 * To draw the gidNumber and uidNumber to the right of the RDN in a small, gray font:
237		 *	'%rdn <small style="color:gray">( %gidNumber / %uidNumber )</small>'
238		 * To draw the full DN of each entry:
239		 *	'%dn'
240		 * To draw the objectClasses to the right in parenthesis:
241		 *	'%rdn <small style="color: gray">( %objectClass )</small>'
242		 * To draw the user-friendly RDN value (ie, instead of "cn=Dave", just draw "Dave"):
243		 *	'%rdnValue'
244		 */
245		$this->default->appearance['tree_display_format'] = array(
246			'desc'=>'LDAP attribute to show in the tree',
247			'default'=>array('%rdn'));
248
249		$this->default->appearance['tree_height'] = array(
250			'desc'=>'Pixel height of the tree browser',
251			'default'=>null);
252
253		$this->default->appearance['tree_width'] = array(
254			'desc'=>'Pixel width of the tree browser',
255			'default'=>null);
256
257		/** Tree display filter
258		 * LDAP filter used to search entries for the tree viewer (left-hand side)
259		 */
260		$this->default->appearance['tree_filter'] = array(
261			'desc'=>'LDAP search filter for the tree entries',
262			'default'=>'(objectClass=*)');
263
264		$this->default->appearance['tree_icons'] = array(
265			'desc'=>'Number of Tree Icons to display on a row',
266			'default'=>0);
267
268		# PLA will not display the header and footer parts in minimal mode.
269		$this->default->appearance['minimalMode'] = array(
270			'desc'=>'Minimal mode hides header and footer parts',
271			'default'=>false);
272
273		## Caching
274		$this->default->cache['schema'] = array(
275			'desc'=>'Cache Schema Activity',
276			'default'=>true);
277
278		$this->default->cache['query'] = array(
279			'desc'=>'Cache Query Configuration',
280			'default'=>true);
281
282		$this->default->cache['query_time'] = array(
283			'desc'=>'Cache the query configuration for atleast this amount of time in seconds',
284			'default'=>5);
285
286		$this->default->cache['template'] = array(
287			'desc'=>'Cache Template Configuration',
288			'default'=>true);
289
290		$this->default->cache['template_time'] = array(
291			'desc'=>'Cache the template configuration for atleast this amount of time in seconds',
292			'default'=>60);
293
294		$this->default->cache['tree'] = array(
295			'desc'=>'Cache Browser Tree',
296			'default'=>true);
297
298		/** Confirm actions
299		 */
300		$this->default->confirm['copy'] = array(
301			'desc'=>'Confirm copy actions',
302			'default'=>true);
303
304		$this->default->confirm['create'] = array(
305			'desc'=>'Confirm creation actions',
306			'default'=>true);
307
308		$this->default->confirm['update'] = array(
309			'desc'=>'Confirm update actions',
310			'default'=>true);
311
312		/** Commands
313		 * Define command availability ; if the value of a command is true,
314		 * the command will be available.
315		 */
316		$this->default->commands['cmd'] = array(
317			'desc'=>'Define command availability',
318			'default'=> array(
319				'entry_internal_attributes_show' => true,
320				'entry_refresh' => true,
321				'oslinks' => true,
322				'switch_template' => true
323			));
324
325		$this->default->commands['script'] = array(
326			'desc'=>'Define scripts availability',
327			'default'=> array(
328				'add_attr_form' => true,
329				'add_oclass_form' => true,
330				'add_value_form' => true,
331				'collapse' => true,
332				'compare' => true,
333				'compare_form' => true,
334				'copy' => true,
335				'copy_form' => true,
336				'create' => true,
337				'create_confirm' => true,
338				'delete' => true,
339				'delete_attr' => true,
340				'delete_form' => true,
341				'draw_tree_node' => true,
342				'expand' => true,
343				'export' => true,
344				'export_form' => true,
345				'import' => true,
346				'import_form' => true,
347				'login' => true,
348				'logout' => true,
349				'login_form' => true,
350				'mass_delete' => true,
351				'mass_edit' => true,
352				'mass_update' => true,
353				'modify_member_form' => true,
354				'monitor' => true,
355				'purge_cache' => true,
356				'query_engine' => true,
357				'rename' => true,
358				'rename_form' => true,
359				'rdelete' => true,
360				'refresh' => true,
361				'schema' => true,
362				'server_info' => true,
363				'show_cache' => true,
364				'template_engine' => true,
365				'update_confirm' => true,
366				'update' => true
367			));
368
369		/** Aliases and Referrrals
370		 * Similar to ldapsearch's -a option, the following options allow you to configure
371		 * how phpLDAPadmin will treat aliases and referrals in the LDAP tree.
372		 * For the following four settings, avaialable options include:
373		 *
374		 * LDAP_DEREF_NEVER	- aliases are never dereferenced (eg, the contents of
375		 *			the alias itself are shown and not the referenced entry).
376		 * LDAP_DEREF_SEARCHING	- aliases should be dereferenced during the search but
377		 *			not when locating the base object of the search.
378		 * LDAP_DEREF_FINDING	- aliases should be dereferenced when locating the base
379		 *			object but not during the search.
380		 * LDAP_DEREF_ALWAYS	- aliases should be dereferenced always (eg, the contents
381		 *			of the referenced entry is shown and not the aliasing entry)
382		 * We superceed these definitions with @ to suppress the error if php-ldap is
383		 * not installed.
384		 */
385		@$this->default->deref['export'] = array(
386			'desc'=>'',
387			'default'=>LDAP_DEREF_NEVER);
388
389		@$this->default->deref['search'] = array(
390			'desc'=>'',
391			'default'=>LDAP_DEREF_ALWAYS);
392
393		@$this->default->deref['tree'] = array(
394			'desc'=>'',
395			'default'=>LDAP_DEREF_NEVER);
396
397		@$this->default->deref['view'] = array(
398			'desc'=>'',
399			'default'=>LDAP_DEREF_NEVER);
400
401		## Debug Attributes
402		$this->default->debug['level'] = array(
403			'desc'=>'Debug level verbosity',
404			'default'=>0);
405
406		$this->default->debug['syslog'] = array(
407			'desc'=>'Whether to send debug messages to syslog',
408			'default'=>false);
409
410		$this->default->debug['file'] = array(
411			'desc'=>'Name of file to send debug output to',
412			'default'=>null);
413
414		$this->default->debug['addr'] = array(
415			'desc'=>'IP address of client to provide debugging info.',
416			'default'=>null);
417
418		$this->default->debug['append'] = array(
419			'desc'=>'Whether to append to the debug file, or create it fresh each time',
420			'default'=>true);
421
422		## Temp Directories
423		/** JPEG TMPDir
424		 * This directory must be readable and writable by your web server
425		 */
426		$this->default->jpeg['tmpdir'] = array(
427			'desc'=>'Temporary directory for jpegPhoto data',
428			'default'=>'/tmp');
429
430		## Mass update commands
431		$this->default->mass['enabled'] = array(
432			'desc'=>'Are mass update commands enabled',
433			'default'=>true);
434
435		## Modify members feature
436		/**
437		 * Search filter setting for new members. This is used to search possible members that can be added
438		 * to the group. See modify_member_form.php
439		 */
440		$this->default->modify_member['filter'] = array(
441			'desc'=>'Search filter for member searches',
442			'default'=>'(objectclass=Person)');
443
444		/**
445		 * Group attributes. When these attributes are seen in template_engine.php, add "modify group members"
446		 * link to the attribute
447		 * See template_engine.php
448		 */
449		$this->default->modify_member['groupattr'] = array(
450			'desc'=>'Group member attributes',
451			'default'=>array('member','uniqueMember','memberUid','uid'));
452
453		/**
454		 * Attribute that is added to the group member attribute. For groupOfNames or groupOfUniqueNames this is dn,
455		 * for posixGroup it's uid. See modify_member_form.php
456		 */
457		$this->default->modify_member['attr'] = array(
458			'desc'=>'Default attribute that is added to the group member attribute',
459			'default'=>'dn');
460
461		/**
462		 * Attribute that is added to the group member attribute.
463		 * For posixGroup it's uid. See modify_member_form.php
464		 */
465		$this->default->modify_member['posixattr'] = array(
466			'desc'=>'Contents of the group member attribute',
467			'default'=>'uid');
468
469		/**
470		 * Search filter setting for new members to group. This is used to search possible members that can be added
471		 * to the posixGroup. See modify_member_form.php
472		 */
473		$this->default->modify_member['posixfilter'] = array(
474			'desc'=>'Search filter for posixmember searches',
475			'default'=>'(uid=*)');
476
477		/**
478		 * posixGroup attribute. When this attribute are seen in modify_member_form.php, only posixGroup members are shown
479		 * See modify_member_form.php
480		 */
481		$this->default->modify_member['posixgroupattr'] = array(
482			'desc'=>'posixGroup member attribute',
483			'default'=>'memberUid');
484
485		## Session Attributes
486		/** Cookie Encryption
487		 * phpLDAPadmin can encrypt the content of sensitive cookies if you set this to a big random string.
488		 */
489		$this->default->session['blowfish'] = array(
490			'desc'=>'Blowfish key to encrypt cookie details',
491			'default'=>null);
492
493		/** Cookie Time
494		 * If you used auth_type 'form' in the servers list, you can adjust how long the cookie will last
495		 * (default is 0 seconds, which expires when you close the browser)
496		 */
497		$this->default->session['cookie_time'] = array(
498			'desc'=>'Time in seconds for the life of cookies',
499			'default'=>0);
500
501		$this->default->session['http_realm'] = array(
502			'desc'=>'HTTP Authentication Realm',
503			'default'=>sprintf('%s %s',app_name(),_('login')));
504
505		$this->default->session['memorylimit'] = array(
506			'desc'=>'Set the PHP memorylimit warning threshold.',
507			'default'=>24);
508
509		$this->default->session['timelimit'] = array(
510			'desc'=>'Set the PHP timelimit.',
511			'default'=>30);
512
513		/**
514		 * Session Menu
515		 */
516		$this->default->menu['session'] = array(
517			'desc'=>'Menu items when logged in.',
518			'default'=>array(
519				'schema'=>true,
520				'search'=>true,
521				'refresh'=>true,
522				'server_info'=>true,
523				'monitor'=>true,
524				'import'=>true,
525				'export'=>true
526			));
527
528		## Password Generation
529		$this->default->password['length'] = array(
530			'desc'=>'Length of autogenerated password',
531			'default'=>8);
532
533		$this->default->password['numbers'] = array(
534			'desc'=>'Number of numbers required in the password',
535			'default'=>2);
536
537		$this->default->password['lowercase'] = array(
538			'desc'=>'Number of lowercase letters required in the password',
539			'default'=>2);
540
541		$this->default->password['uppercase'] = array(
542			'desc'=>'Number of uppercase letters required in the password',
543			'default'=>2);
544
545		$this->default->password['punctuation'] = array(
546			'desc'=>'Number of punctuation letters required in the password',
547			'default'=>2);
548
549		$this->default->password['use_similar'] = array(
550			'desc'=>'Whether to use similiar characters',
551			'default'=>true);
552
553		$this->default->password['no_random_crypt_salt'] = array(
554			'desc'=>'Disable random salt for crypt()',
555			'default'=>false);
556
557		$this->default->password['available_types'] = array(
558			'desc'=>'List of available password types used for encryption',
559			'default'=>array(
560				''=>'clear',
561				'bcrypt'=>'bcrypt',
562				'blowfish'=>'blowfish',
563				'crypt'=>'crypt',
564				'ext_des'=>'ext_des',
565				'md5'=>'md5',
566				'k5key'=>'k5key',
567				'md5crypt'=>'md5crypt',
568				'sha'=>'sha',
569				'smd5'=>'smd5',
570				'ssha'=>'ssha',
571				'sha256'=>'sha256',
572				'ssha256'=>'ssha256',
573				'sha384'=>'sha384',
574				'ssha384'=>'ssha384',
575				'sha512'=>'sha512',
576				'ssha512'=>'ssha512',
577				'sha256crypt'=>'sha256crypt',
578				'sha512crypt'=>'sha512crypt',
579			));
580
581		/** Search display
582		 * By default, when searching you may display a list or a table of results.
583		 * Set this to 'table' to see table formatted results.
584		 * Set this to 'list' to see "Google" style formatted search results.
585		 */
586		$this->default->search['display'] = array(
587			'desc'=>'Display a list or table of search results',
588			'default'=>'list');
589
590		$this->default->search['size_limit'] = array(
591			'desc'=>'Limit the size of searchs on the search page',
592			'default'=>50);
593
594		/**
595		 * The list of attributes to display in each search result entry.
596		 * Note that you can add * to the list to display all attributes
597		 */
598		$this->default->search['result_attributes'] = array(
599			'desc'=>'List of attributes to display in each search result entry',
600			'default'=>array('cn','sn','uid','postalAddress','telephoneNumber'));
601
602		$this->default->search['time_limit'] = array(
603			'desc'=>'Maximum time to allow unlimited size_limit searches to the ldap server',
604			'default'=>120);
605
606		/* reCAPTCHA Login */
607
608		$this->default->session['reCAPTCHA-enable'] = array(
609			'desc'=>'Status reCAPTCHA (true | false)',
610			'default'=>false);
611
612		$this->default->session['reCAPTCHA-key-site'] = array(
613			'desc'=>'Site Key',
614			'default'=>"<put-here-key-site>");
615
616		$this->default->session['reCAPTCHA-key-server'] = array(
617			'desc'=>'Server key',
618			'default'=>"<put-here-key-server>");
619	}
620
621	/**
622	 * Access the configuration, taking into account the defaults and the customisations
623	 */
624	private function getConfigArray($usecache=true) {
625		static $CACHE = array();
626
627		if ($usecache && count($CACHE))
628			return $CACHE;
629
630		foreach ($this->default as $key => $vals)
631			$CACHE[$key] = $vals;
632
633		foreach ($this->custom as $key => $vals)
634			foreach ($vals as $index => $val)
635				$CACHE[$key][$index]['value'] = $val;
636
637		return $CACHE;
638	}
639
640	/**
641	 * Get a configuration value.
642	 */
643	public function getValue($key,$index,$fatal=true) {
644		$config = $this->getConfigArray();
645
646		if (! isset($config[$key]))
647			if ($fatal)
648				error(sprintf('A call was made in [%s] to getValue requesting [%s] that isnt predefined.',
649					basename($_SERVER['PHP_SELF']),$key),'error',null,true);
650			else
651				return '';
652
653		if (! isset($config[$key][$index]))
654			if ($fatal)
655				error(sprintf('Requesting an index [%s] in key [%s] that isnt predefined.',$index,$key),'error',null,true);
656			else
657				return '';
658
659		return isset($config[$key][$index]['value']) ? $config[$key][$index]['value'] : $config[$key][$index]['default'];
660	}
661
662	/**
663	 * Return the untested config items
664	 */
665	public function untested() {
666		$result = array();
667
668		foreach ($this->default as $option => $details)
669			foreach ($details as $param => $values)
670				if (isset($values['untested']) && $values['untested'])
671					array_push($result,sprintf('%s.%s',$option,$param));
672
673		return $result;
674	}
675
676	/**
677	 * Function to check and warn about any unusual defined variables.
678	 */
679	public function CheckCustom() {
680		if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
681			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
682
683		if (isset($this->custom)) {
684			foreach ($this->custom as $masterkey => $masterdetails) {
685
686				if (isset($this->default->$masterkey)) {
687
688					if (! is_array($masterdetails))
689						error(sprintf('Error in configuration file, [%s] should be an ARRAY.',$masterdetails),'error',null,true);
690
691					foreach ($masterdetails as $key => $value) {
692						# Test that the key is correct.
693						if (! in_array($key,array_keys($this->default->$masterkey)))
694							error(sprintf('Error in configuration file, [%s] has not been defined as a configurable variable.',$key),'error',null,true);
695
696						# Test if its should be an array or not.
697						if (is_array($this->default->{$masterkey}[$key]['default']) && ! is_array($value))
698							error(sprintf('Error in configuration file, %s[\'%s\'] SHOULD be an array of values.',$masterkey,$key),'error',null,true);
699
700						if (! is_array($this->default->{$masterkey}[$key]['default']) && is_array($value))
701							error(sprintf('Error in configuration file, %s[\'%s\'] should NOT be an array of values.',$masterkey,$key),'error',null,true);
702					}
703
704				} else {
705					error(sprintf('Error in configuration file, [%s] has not been defined as a MASTER configurable variable.',$masterkey),'error',null,true);
706				}
707			}
708		}
709	}
710
711	/**
712	 * Get a list of available commands.
713	 */
714	public function getCommandList() {
715		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
716			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
717
718		$config = $this->getConfigArray(false);
719
720		masort($config['command'],'summary');
721
722		if (isset($config['command']) && is_array($config['command']))
723			return $config['command'];
724		else
725			return array();
726	}
727
728	/**
729	 * Simple ACL to see if commands can be run
730	 */
731	public function isCommandAvailable($index='cmd') {
732		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
733			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
734
735		$a = func_get_args();
736		array_shift($a);
737		$a = $a[0];
738
739		# Command availability list
740		$cmd = $this->getValue('commands',$index);
741
742		if (! is_string($a) || ! isset($cmd[$a]))
743			return false;
744		else
745			return $cmd[$a];
746	}
747
748	public function configDefinition($key,$index,$config) {
749		if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
750			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
751
752		if (! is_array($config) || ! array_key_exists('desc',$config) || ! array_key_exists('default',$config))
753			return;
754
755		if (isset($this->default->$key))
756			$definition = $this->default->$key;
757
758		$definition[$index] = $config;
759		$this->default->$key = $definition;
760	}
761
762	/**
763	 * Return the friendly attributes names
764	 */
765	private function getFriendlyAttrs() {
766		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
767			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
768
769		return array_change_key_case($this->getValue('appearance','friendly_attrs'));
770	}
771
772	/**
773	 * This function will return the friendly name of an attribute, if it exists.
774	 * If the friendly name doesnt exist, the attribute name will be returned.
775 	 *
776	 * @param attribute
777	 * @return string friendly name|attribute
778	 */
779	public function getFriendlyName($attr) {
780		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
781			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
782
783		static $friendly_attrs;
784
785		if (! $friendly_attrs)
786			$friendly_attrs = $this->getFriendlyAttrs();
787
788		if (! is_object($attr))
789			if (isset($friendly_attrs[$attr]))
790				return $friendly_attrs[$attr];
791			else
792				return $attr;
793
794		if (isset($friendly_attrs[$attr->getName()]))
795			return $friendly_attrs[$attr->getName()];
796		else
797			return $attr->getName(false);
798	}
799
800	/**
801	 * This function will return true if a friendly name exists for an attribute.
802	 * If the friendly name doesnt exist, it will return false.
803 	 *
804	 * @param attribute
805	 * @return boolean true|false
806	 */
807	public function haveFriendlyName($attr) {
808		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
809			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
810
811		return $attr->getName(false) != $this->getFriendlyName($attr);
812	}
813
814	/**
815	 * This function will return the <ancronym> html for a friendly name attribute.
816 	 *
817	 * @param attribute
818	 * @return string html for the friendly name.
819	 */
820	public function getFriendlyHTML($attr) {
821		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
822			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
823
824		if ($this->haveFriendlyName($attr))
825			return sprintf('<acronym title="%s %s">%s</acronym>',
826				_('Alias for'),$attr->getName(false),$this->getFriendlyName($attr));
827		else
828			return $attr->getName(false);
829	}
830
831	public function setServers($servers) {
832		$this->servers = $servers;
833	}
834
835	public function getServer($index=null) {
836		return $this->servers->Instance($index);
837	}
838
839	/**
840	 * Return a list of our servers
841	 * @param boolean $visible - Only return visible servers
842	 */
843	public function getServerList($visible=true) {
844		if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
845			debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
846
847		return $this->servers->getServerList($visible);
848	}
849}
850?>
851