1<?php
2/*
3* e107 website system
4*
5* Copyright (C) 2008-2017 e107 Inc (e107.org)
6* Released under the terms and conditions of the
7* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
8*
9* Administration Area - Users
10*
11*/
12
13if(!empty($_POST) && !isset($_POST['e-token']))
14{
15	$_POST['e-token'] = ''; // make sure e-token hasn't been deliberately removed.
16}
17
18if (!defined('e107_INIT'))
19{
20	require_once("../class2.php");
21}
22
23if (!getperms('4|U0|U1|U2|U3'))
24{
25	e107::redirect('admin');
26	exit;
27}
28
29e107::coreLan('user');
30e107::coreLan('users', true);
31e107::coreLan('date');
32
33// TODO List of permissions to be implemented
34// "options" - getperms('4|U2')
35// "create" - getperms('4|U1|U0')
36// "ranks" - getperms('4|U3')
37// "default" - getperms('4|U1|U0')
38
39e107::css('inline', "
40
41 .label-status, .label-password { width:100%; display:block; padding-bottom:5px; padding-top:5px }
42");
43
44class users_admin extends e_admin_dispatcher
45{
46	protected $modes = array(
47		'main'		=> array(
48			'controller' 	=> 'users_admin_ui',
49			'path' 			=> null,
50			'ui' 			=> 'users_admin_form_ui',
51			'uipath' 		=> null,
52			//'perm'			=> '0',
53		),
54		'ranks'		=> array(
55			'controller' 	=> 'users_ranks_ui',
56			'path' 			=> null,
57			'ui' 			=> 'users_ranks_ui_form',
58			'uipath' 		=> null,
59			//'perm'			=> '0',
60		)
61	);
62
63
64	protected $adminMenu = array(
65		'main/list'		=> array('caption'=> LAN_MANAGE, 'perm' => '0|4'),
66		'main/add' 		=> array('caption'=> LAN_USER_QUICKADD, 'perm' => '4|U0|U1'),
67		'main/prefs' 	=> array('caption'=> LAN_OPTIONS, 'perm' => '4|U2'),
68		'ranks/list'	=> array('caption'=> LAN_USER_RANKS, 'perm' => '4|U3'),
69		'main/maintenance'  => array('caption'=> LAN_MAINTENANCE, 'perm' => '4')
70	//	'ranks/list'	=> array('caption'=> LAN_USER_RANKS, 'perm' => '4|U3')
71	);
72
73	/*
74		FIXME - move user prune to Schedule tasks (cron)
75		$var ['prune']['text'] = LAN_USER_PRUNE;
76		$var ['prune']['link'] = e_ADMIN.'users.php?action=prune';// Will be moved to "Schedule tasks"
77		$var ['prune']['perm'] = '4';
78
79*/
80	protected $adminMenuAliases = array(
81		'main/edit'		=> 'main/list',
82		'main/admin'	=> 'main/list',
83		'main/userclass'=> 'main/list',
84		'main/test'		=> 'main/list',
85	);
86
87	protected $menuTitle = ADLAN_36;  // 'Users'
88
89	protected $adminMenuIcon = 'e-users-24';
90
91
92	function init()
93	{
94
95		$JS = <<<JS
96
97			//	$('#user-action-indicator-'+user).html('<i class="fa fa-cog"></i>'); //
98
99			$(document).on('click', ".user-action", function(e){
100				// e.stopPropagation();
101
102				var action = $(this).attr('data-action-type');
103				var user = $(this).attr('data-action-user');
104
105			//	$('#user-action-indicator-'+user).html('<i class="fa fa-spin fa-spinner"></i>'); //
106
107				$('.user-action-hidden').val(''); // clear all, incase of back-button or auto-fill.
108				$('#user-action-'+ user).val(action);
109				$('#core-user-list-form').submit();
110
111
112				});
113JS;
114
115		e107::js('footer-inline', $JS);
116		e107::css('inline', '
117			.user-action { cursor: pointer }
118			.btn-user-action { margin-right:15px}
119
120		');
121
122	}
123
124	/**
125	 * Run observers/headers override
126	 *
127	 * @return users_admin
128	 */
129	public function runObservers($run_header = true)
130	{
131		// Catch useraction
132		if (isset($_POST['useraction']))
133		{
134			if(is_array($_POST['useraction']))
135			{
136				foreach ($_POST['useraction'] as $key => $val)
137				{
138					if ($val)
139					{
140						$_POST['useraction'] = $val;
141						$_POST['userip'] = $_POST['userip'][$key];
142						$_POST['userid'] = (int) $key;
143						break;
144					}
145				}
146			}
147
148			// FIXME IMPORTANT - permissions per action/trigger
149
150			// map useraction to UI trigger
151			switch ($_POST['useraction'])
152			{
153				### etrigger_delete
154				case 'deluser':
155					if($_POST['userid'])
156					{
157						$id = (int) $_POST['userid'];
158						$_POST['etrigger_delete'] = array($id => $id);
159						$user = e107::getDb()->retrieve('user', 'user_email, user_name', 'user_id='.$id);
160						$rplc_from = array('[x]', '[y]', '[z]');
161						$rplc_to = array($user['user_name'], $user['user_email'], $id);
162						$message = str_replace($rplc_from, $rplc_to, USRLAN_222);
163						$this->getController()->deleteConfirmMessage = $message;
164					}
165				break;
166
167				// map to List{USERACTION}Trigger()
168				case 'unban':
169				case 'ban':
170				case 'verify':
171				case 'reqverify':
172				case 'resend':
173				case 'loginas':
174				case 'unadmin':
175					$_POST['etrigger_'.$_POST['useraction']] = intval($_POST['userid']);
176				break;
177
178
179				case 'logoutas':
180					$this->getRequest()
181						->setQuery(array())
182						->setMode('main')
183						->setAction('logoutas');
184				break;
185
186				// redirect to AdminObserver/AdminPage()
187				case 'admin':
188				case 'adminperms':
189					$this->getRequest()
190						->setQuery(array())
191						->setMode('main')
192						->setAction('admin')
193						->setId($_POST['userid']);
194
195					$this->getController()->redirect();
196				break;
197
198				// redirect to UserclassObserver/UserclassPage()
199				case 'userclass':
200					$this->getRequest()
201						->setQuery(array())
202						->setMode('main')
203						->setAction('userclass')
204						->setId($_POST['userid']);
205
206					$this->getController()->redirect();
207				break;
208
209				// redirect to TestObserver/TestPage
210				case 'test':
211					$this->getRequest()
212						->setQuery(array())
213						->setMode('main')
214						->setAction('test')
215						->setId($_POST['userid']);
216
217					$this->getController()->redirect();
218				break;
219
220				// redirect to TestObserver/TestPage
221				case 'usersettings':
222					$this->getRequest()
223						->setQuery(array())
224						->setMode('main')
225						->setAction('edit')
226						->setId($_POST['userid']);
227					$this->getController()->redirect();
228
229
230					//XXX Broken to the point of being unusable. //header('location:'.e107::getUrl()->create('user/profile/edit', 'id='.(int) $_POST['userid'], 'full=1&encode=0'));
231					// exit;
232				break;
233			}
234
235		}
236
237		return parent::runObservers($run_header);
238	}
239}
240
241
242class users_admin_ui extends e_admin_ui
243{
244
245	protected $pluginTitle = ADLAN_36;
246	protected $pluginName = 'core';
247	protected $eventName = 'user';
248	protected $table = "user";
249
250//	protected $listQry = "SELECT SQL_CALC_FOUND_ROWS * FROM #users"; // without any Order or Limit.
251	protected $listQry = "SELECT SQL_CALC_FOUND_ROWS u.*,ue.* from #user AS u LEFT JOIN #user_extended AS ue ON u.user_id = ue.user_extended_id  "; // without any Order or Limit.
252
253	protected $editQry = "SELECT u.*,ue.* FROM #user AS u left join #user_extended AS ue ON u.user_id = ue.user_extended_id  WHERE user_id = {ID}";
254
255	protected $pid 			= "user_id";
256	protected $perPage 		= 10;
257	protected $batchDelete 	= true;
258	protected $batchExport	= true;
259	protected $listOrder 	= 'user_id DESC';
260
261	/**
262	 * Show confirm screen before (batch/single) delete
263	 * @var boolean
264	 */
265	public $deleteConfirmScreen = true;
266
267	/**
268	 * @var boolean
269	 */
270	protected $batchCopy = false;
271
272	/**
273	 * List (numerical array) of only disallowed for this controller actions
274	 */
275	protected $disallow = array('create');
276
277	protected $tabs		= array(LAN_BASIC, LAN_EXTENDED);
278
279	  protected $url          = array(
280    	'route'=>'user/profile/view',
281    	'name' => 'user_name',
282    	'description' => 'user_name',
283    	'vars'=> array('user_id' => true, 'user_name' => true)
284	);
285
286	//TODO - finish 'user' type, set 'data' to all editable fields, set 'noedit' for all non-editable fields
287	protected $fields = array(
288		'checkboxes'		=> array('title'=> '',				'type' => null, 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'),
289
290		'user_id' 			=> array('title' => LAN_ID,			'tab'=>0, 'type' =>'text',	'data'=>'int',	'width' => '5%','forced' => true, 'readParms'=>'link=sef&target=blank'),
291//		'user_status' 		=> array('title' => LAN_STATUS,		'type' => 'method',	'alias'=>'user_status', 'width' => 'auto','forced' => true, 'nosort'=>TRUE),
292		'user_ban' 			=> array('title' => LAN_STATUS,		'tab'=>0, 'type' => 'method', 'width' => 'auto', 'filter'=>true, 'batch'=>true,'thclass'=>'center', 'class'=>'center'),
293
294		'user_name' 		=> array('title' => LAN_USER_01,	'tab'=>0, 'type' => 'text',	'inline'=>true, 'data'=>'safestr', 'width' => 'auto','thclass' => 'left first'), // Display name
295 		'user_loginname' 	=> array('title' => LAN_USER_02,	'tab'=>0, 'type' => 'text',	'data'=>'safestr', 'width' => 'auto'), // User name
296 		'user_login' 		=> array('title' => LAN_USER_03,	'tab'=>0, 'type' => 'text',	'inline'=>true, 'data'=>'safestr', 'width' => 'auto'), // Real name (no real vetting)
297 		'user_customtitle' 	=> array('title' => LAN_USER_04,	'tab'=>0, 'type' => 'text',	'inline'=>true, 'data'=>'safestr', 'width' => 'auto'), // No real vetting
298 		'user_password' 	=> array('title' => LAN_PASSWORD,	'tab'=>0, 'type' => 'method',	'data'=>'safestr', 'width' => 'auto'), //TODO add md5 option to form handler?
299		'user_sess' 		=> array('title' => LAN_SESSION,	'tab'=>0, 'noedit'=>true, 'type' => 'text',	'width' => 'auto'), // Photo
300 		'user_image' 		=> array('title' => LAN_USER_07,	'tab'=>0, 'type' => 'dropdown',	'data'=>'str', 'width' => 'auto'), // Avatar
301 		'user_email' 		=> array('title' => LAN_EMAIL,		'tab'=>0, 'type' => 'text', 'inline'=>true, 'data'=>'safestr',	'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge')),
302		'user_hideemail' 	=> array('title' => LAN_USER_10,	'tab'=>0, 'type' => 'boolean', 'data'=>'int',	'width' => 'auto', 'thclass'=>'center', 'class'=>'center', 'filter'=>true, 'batch'=>true, 'readParms'=>'trueonly=1'),
303		'user_xup' 			=> array('title' => 'Xup',			'tab'=>0, 'noedit'=>true, 'type' => 'text', 'data'=>'str',	'width' => 'auto'),
304		'user_class' 		=> array('title' => LAN_USER_12,	'tab'=>0, 'type' => 'userclasses' , 'data'=>'safestr', 'inline'=>true, 'writeParms' => 'classlist=classes,new', 'readParms'=>'classlist=classes,new&defaultLabel=--', 'filter'=>true, 'batch'=>true),
305		'user_join' 		=> array('title' => LAN_USER_14,	'tab'=>0, 'noedit'=>true, 'type' => 'datestamp', 	'width' => 'auto', 'writeParms'=>'readonly=1'),
306		'user_lastvisit' 	=> array('title' => LAN_USER_15,	'tab'=>0, 'noedit'=>true, 'type' => 'datestamp', 	'width' => 'auto'),
307		'user_currentvisit' => array('title' => LAN_USER_16,	'tab'=>0, 'noedit'=>true, 'type' => 'datestamp', 	'width' => 'auto'),
308		'user_comments' 	=> array('title' => LAN_COMMENTS,	'tab'=>0, 'noedit'=>true, 'type' => 'int', 	'width' => 'auto','thclass'=>'right','class'=>'right'),
309		'user_lastpost' 	=> array('title' => USRLAN_195,	'tab'=>0, 'noedit'=>true, 'type' => 'datestamp', 	'width' => 'auto'),
310		'user_ip' 			=> array('title' => LAN_USER_18,	'tab'=>0, 'noedit'=>true, 'type' => 'ip',	'data'=>'str',	'width' => 'auto'),
311		//	'user_prefs' 		=> array('title' => LAN_USER_20,	'type' => 'text', 	'width' => 'auto'),
312		'user_visits' 		=> array('title' => LAN_USER_21,	'tab'=>0, 'noedit'=>true, 'type' => 'int', 'width' => 'auto','thclass'=>'right','class'=>'right'),
313		'user_admin' 		=> array('title' => LAN_USER_22,	'tab'=>0, 'type' => 'method', 'width' => 'auto', 'thclass'=>'center', 'class'=>'center', 'filter'=>true, 'batch'=>true, 'readParms'=>'trueonly=1'),
314		'user_perms' 		=> array('title' => LAN_USER_23,	'tab'=>0, 'type' => 'method', 'data'=>'str',	'width' => 'auto'),
315		'user_pwchange'		=> array('title' => LAN_USER_24,	'tab'=>0, 'noedit'=>true, 'type'=>'datestamp' , 'width' => 'auto'),
316
317	);
318
319	protected $fieldpref = array('user_ban','user_name','user_loginname','user_login','user_email','user_class','user_admin');
320
321	protected $prefs = array(
322	//	'anon_post'				=> array('title'=>PRFLAN_32, 	'type'=>'boolean'),
323		'avatar_upload'				=> array('title' => USRLAN_44,  'type' => 'boolean', 'writeParms' => 'label=yesno', 'data' => 'int',),
324		'photo_upload'				=> array('title' => USRLAN_53,  'type' => 'boolean', 'writeParms' => 'label=yesno', 'data' => 'int',),
325		'im_width'					=> array('title' => USRLAN_47,  'type' => 'number',  'writeParms' => array('maxlength' => 4), 'help' => USRLAN_48, 'data' => 'int', ),
326		'im_height'					=> array('title' => USRLAN_49,  'type' => 'number',  'writeParms' => array('maxlength' => 4), 'help' => USRLAN_50, 'data' => 'int', ),
327		'profile_rate'				=> array('title' => USRLAN_126, 'type' => 'boolean', 'writeParms' => 'label=yesno', 'data' => 'int',),
328		'profile_comments'			=> array('title' => USRLAN_127, 'type' => 'boolean', 'writeParms' => 'label=yesno', 'data' => 'int',),
329		'force_userupdate'			=> array('title' => USRLAN_133, 'type' => 'boolean', 'writeParms' => 'label=yesno', 'help' => USRLAN_134, 'data' => 'int',),
330		'del_unv'					=> array('title' => USRLAN_93,  'type' => 'number',  'writeParms' => array('maxlength' => 5, 'post' => USRLAN_95), 'help' => USRLAN_94, 'data' => 'int',),
331		'del_accu'					=> array('title' => USRLAN_257, 'type' => 'boolean', 'writeParms' => 'label=yesno', 'data' => 'int',),
332		'track_online'				=> array('title' => USRLAN_130, 'type' => 'boolean', 'writeParms' => 'label=yesno', 'help' => USRLAN_131, 'data' => 'int',),
333		'memberlist_access'			=> array('title' => USRLAN_146, 'type' => 'userclass', 'writeParms' => 'classlist=public,member,guest,admin,main,classes,nobody', 'data' => 'int',),
334		'signature_access'			=> array('title' => USRLAN_194, 'type' => 'userclass', 'writeParms' => 'classlist=member,admin,main,classes,nobody', 'data' => 'int',),
335		'user_new_period'			=> array('title' => USRLAN_190,  'type' => 'number',  'writeParms' => array('maxlength' => 3, 'post' => LANDT_04s), 'help' => USRLAN_191, 'data' => 'int',),
336	);
337
338	public $extended = array();
339	public $extendedData = array();
340
341
342
343	function getExtended()
344	{
345		return $this->extendedData;
346	}
347
348	function init()
349	{
350
351		$sql = e107::getDb();
352		$tp = e107::getParser();
353
354
355		if(!empty($_POST['resendToAll']))
356		{
357			$resetPasswords = !empty($_POST['resetPasswords']);
358			$age = vartrue($_POST['resendAge'], 24);
359			$class = vartrue($_POST['resendClass'], false);
360			$this->resend_to_all($resetPasswords, $age, $class);
361		}
362
363
364		if($this->getAction() == 'edit')
365		{
366			$this->fields['user_class']['noedit'] = true;
367		}
368
369
370
371
372
373
374
375		// Extended fields - FIXME - better field types
376
377		if($rows = $sql->retrieve('user_extended_struct', '*', "user_extended_struct_type > 0 AND user_extended_struct_text != '_system_' ORDER BY user_extended_struct_parent ASC",true))
378		{
379			// TODO FIXME use the handler to build fields and field attributes
380			// FIXME a way to load 3rd party language files for extended user fields
381			e107::coreLan('user_extended');
382
383			$dataMode = ($this->getAction() === 'list') ? 'str' : false;  // allow for search of extended fields.
384
385			foreach ($rows as $row)
386			{
387				$field = "user_".$row['user_extended_struct_name'];
388				// $title = ucfirst(str_replace("user_","",$field));
389				$label = $tp->toHTML($row['user_extended_struct_text'],false,'defs');
390				$this->fields[$field] = array('__tableField'=>'ue.'.$field, 'title' => $label,'width' => 'auto', 'type'=>'method', 'readParms'=>array('ueType'=>$row['user_extended_struct_type']), 'method'=>'user_extended', 'data'=>$dataMode, 'tab'=>1, 'noedit'=>false);
391
392				$this->extended[] = $field;
393				$this->extendedData[$field] = $row;
394			}
395		}
396
397
398		if(empty($this->extended))
399		{
400			$this->tabs = false;
401		}
402
403
404
405		$this->fields['user_signature']['writeParms']['data'] = e107::getUserClass()->uc_required_class_list("classes");
406
407		$this->fields['user_signature'] = array('title' => LAN_USER_09,	'type' => 'textarea', 'data'=>'str',	'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge'));
408		$this->fields['options'] = array('title'=> LAN_OPTIONS."&nbsp;",	'type' => 'method',	'forced'=>TRUE, 'width' => '10%', 'thclass' => 'right last', 'class' => 'left');
409
410
411		if(!getperms('4|U0')) // Quick Add User Access Only.
412		{
413			unset($this->fields['checkboxes']);
414			unset($this->fields['options']);
415		}
416
417		$this->fields['user_image']['writeParms'] = $this->getAvatarList();
418
419		if(!empty($_GET['readonly']))
420		{
421			foreach($this->fields as $key=>$v)
422			{
423				if($key == 'options' || $key == 'checkboxes')
424				{
425					continue;
426				}
427
428				$this->fields[$key]['readonly'] = 2;
429
430			}
431		}
432	//	print_a($this->fields);
433		if(!empty($_GET['iframe']))
434		{
435			define('e_IFRAME', true);
436		}
437
438
439
440	}
441
442
443
444	protected function getAvatarList()
445	{
446		$avs = array(''=>LAN_NONE);
447		$upload = array();
448		$sys = array();
449		$uploaded = e107::getFile()->get_files(e_AVATAR_UPLOAD);
450		foreach($uploaded as $f)
451		{
452			$id = '-upload-'.$f['fname'];
453			$upload[$id] = $f['fname'];
454		}
455		$system = e107::getFile()->get_files(e_AVATAR_DEFAULT);
456		foreach($system as $f)
457		{
458			$id = $f['fname'];
459			$sys[$id] = $f['fname'];
460		}
461
462		$avs['uploaded'] = $upload;
463		$avs['system'] = $sys;
464
465		return $avs;
466	}
467
468
469	public function afterDelete($deletedData, $id=null, $deleted_check)
470	{
471		if(!empty($id))
472		{
473			$sql = e107::getDb();
474			$sql->delete('user_extended',"user_extended_id = ".$id);
475
476			e107::getCache()->clear('online_menu_member_newest');
477			e107::getCache()->clear('online_menu_member_total');
478
479			// Trigger admin_user_delete
480			e107::getEvent()->trigger('admin_user_delete', $deletedData);
481		}
482
483	}
484
485
486
487
488	public function beforeUpdate($new_data, $old_data, $id)
489	{
490		$tp = e107::getParser();
491
492		$pwdField = 'user_password_'.$id;
493
494		if(!empty($new_data[$pwdField]))
495		{
496			$new_data['user_password'] = $new_data[$pwdField];
497			unset($new_data[$pwdField]);
498		}
499
500	//	e107::getMessage()->addInfo(print_a($new_data,true));
501
502		if(empty($new_data['user_password']))
503		{
504			$new_data['user_password'] = $old_data['user_password'];
505		}
506		else
507		{
508
509			// issues #3126, #3143: Login not working after admin set a new password using the backend
510			// Backend used user_login instead of user_loginname (used in usersettings) and did't escape the password.
511			$savePassword = $new_data['user_password'];
512			$loginname = $new_data['user_loginname'] ? $new_data['user_loginname'] : $old_data['user_loginname'];
513			$email = (isset($new_data['user_email']) && $new_data['user_email']) ? $new_data['user_email'] : $old_data['user_email'];
514			$new_data['user_password'] = e107::getDb()->escape(e107::getUserSession()->HashPassword($savePassword, $loginname), false);
515
516			e107::getMessage()->addDebug("Password Hash: ".$new_data['user_password']);
517		}
518
519		if(!empty($new_data['perms']))
520		{
521			$new_data['user_perms']	= implode(".",$new_data['perms']);
522		}
523
524		// Handle the Extended Fields.
525		$this->saveExtended($new_data);
526
527
528
529
530		return $new_data;
531	}
532
533
534	function saveExtended($new_data)
535	{
536		$update = array();
537		$fieldtype = array();
538		foreach($this->extended as $key) // Grab Extended field data.
539		{
540			$update['data'][$key] = vartrue($new_data['ue'][$key],'_NULL_');
541		}
542
543		e107::getMessage()->addDebug(print_a($update,true));
544
545		if(!empty($update))
546		{
547			e107::getUserExt()->addFieldTypes($update);
548
549			if(!e107::getDb()->count('user_extended', '(user_extended_id)', "user_extended_id=".intval($new_data['submit_value'])))
550			{
551				$update['data']['user_extended_id'] = intval($new_data['submit_value']);
552				if(e107::getDb()->insert('user_extended', $update))
553				{
554					// e107::getMessage()->addSuccess(LAN_UPDATED.': '.ADLAN_78); // not needed see pull/1816
555					e107::getMessage()->addDebug(LAN_UPDATED.': '.ADLAN_78); // let's put it in debug instead
556				}
557				else
558				{
559					e107::getMessage()->addError(LAN_UPDATED_FAILED.': '.ADLAN_78);
560					$error = e107::getDb()->getLastErrorText();
561					e107::getMessage()->addDebug($error);
562					e107::getMessage()->addDebug(print_a($update,true));
563
564
565					e107::getDb()->getLastErrorText();
566				}
567			}
568			else
569			{
570				$update['WHERE'] = 'user_extended_id='. intval($new_data['submit_value']);
571
572				if(e107::getDb()->update('user_extended',$update)===false)
573				{
574					e107::getMessage()->addError(LAN_UPDATED_FAILED.': '.ADLAN_78);
575					$error = e107::getDb()->getLastErrorText();
576					e107::getMessage()->addDebug($error);
577					e107::getMessage()->addDebug(print_a($update,true));
578
579				}
580				else
581				{
582					 e107::getMessage()->reset(E_MESSAGE_SUCCESS)->addSuccess(LAN_UPDATED);
583					e107::getMessage()->addDebug(LAN_UPDATED.': '.ADLAN_78); // let's put it in debug instead
584				}
585			}
586		}
587
588
589	}
590
591
592	/**
593	 * Unban user trigger
594	 * @param int $userid
595	 * @return void
596	 */
597	public function ListUnbanTrigger($userid)
598	{
599		$sql = e107::getDb();
600		$tp = e107::getParser();
601		$sysuser = e107::getSystemUser($userid, false);
602
603		if(!$sysuser->getId())
604		{
605			e107::getMessage()->addError(USRLAN_223);
606			return;
607		}
608
609		$row = e107::user($userid);
610
611		$sql->update("user", "user_ban='0' WHERE user_id='".$userid."' ");
612		$sql->delete("banlist"," banlist_ip='{$row['user_ip']}' ");
613
614		$vars = array('x'=>$sysuser->getId(), 'y'=> $sysuser->getName(), 'z'=> $sysuser->getValue('email'));
615
616		e107::getAdminLog()->log_event('USET_06', $tp->lanVars( USRLAN_162, $vars), E_LOG_INFORMATIVE);
617		e107::getMessage()->addSuccess("(".$sysuser->getId().".".$sysuser->getName()." - ".$sysuser->getValue('email').") ".USRLAN_9);
618
619		// List data reload
620		$this->getTreeModel()->loadBatch(true);
621	}
622
623	/**
624	 * Ban user trigger
625	 * @param int $userid
626	 * @return void
627	 */
628	public function ListBanTrigger($userid)
629	{
630		$sql = e107::getDb();
631		$mes = e107::getMessage();
632		$admin_log = e107::getAdminLog();
633		$iph = e107::getIPHandler();
634		$tp = e107::getParser();
635
636		$sysuser = e107::getSystemUser($userid, false);
637		if(!$sysuser->getId())
638		{
639			$mes->addError(USRLAN_223);
640			return;
641		}
642		$row = $sysuser->getData();
643
644		if (($row['user_perms'] == "0") || ($row['user_perms'] == "0."))
645		{
646			$mes->addWarning(USRLAN_7);
647		}
648		else
649		{
650			if ($sql->update("user","user_ban='1' WHERE user_id='".$userid."' "))
651			{
652				$vars = array('x'=>$row['user_id'], 'y'=> $row['user_name']);
653				e107::getLog()->add('USET_05',$tp->lanVars(USRLAN_161, $vars), E_LOG_INFORMATIVE);
654				$mes->addSuccess("(".$userid.".".$row['user_name']." - {$row['user_email']}) ".USRLAN_8);
655			}
656			if (trim($row['user_ip']) == "")
657			{
658				$mes->addInfo(USRLAN_135);
659			}
660			else
661			{
662				if($sql->count('user', '(*)', "user_ip = '{$row['user_ip']}' AND user_ban=0 AND user_id <> {$userid}") > 0)
663				{
664					// Other unbanned users have same IP address
665					$mes->addWarning(str_replace("{IP}", $iph->ipDecode($row['user_ip']), USRLAN_136));
666				}
667				else
668				{
669					if ($iph->add_ban(6, USRLAN_149.$row['user_name'].'/'.$row['user_loginname'], $row['user_ip'], USERID))
670					{
671						// Successful IP ban
672						$mes->addSuccess(str_replace("{IP}", $iph->ipDecode($row['user_ip']), USRLAN_137));
673					}
674					else
675					{
676						// IP address on whitelist
677						$mes->addWarning(str_replace("{IP}", $iph->ipDecode($row['user_ip']), USRLAN_150));
678					}
679				}
680			}
681		}
682
683		// List data reload
684		$this->getTreeModel()->loadBatch(true);
685	}
686
687	/**
688	 * Activate user trigger
689	 */
690	public function ListVerifyTrigger($userid)
691	{
692		$e_event = e107::getEvent();
693		$admin_log = e107::getAdminLog();
694		$sysuser = e107::getSystemUser($userid, false);
695		$userMethods = e107::getUserSession();
696		$mes = e107::getMessage();
697		$tp = e107::getParser();
698
699		$uid = intval($userid);
700		if ($sysuser->getId())
701		{
702			$sysuser->set('user_ban', '0')
703				->set('user_sess', '');
704
705			$row = $sysuser->getData();
706
707			if ($initUserclasses = $userMethods->userClassUpdate($row, 'userall'))
708			{
709				$row['user_class'] = $initUserclasses;
710			}
711
712			$userMethods->addNonDefaulted($row);
713			$sysuser->setData($row);
714
715		//	$res = $sysuser->getData();
716		//	e107::getDebug()->log($res);
717
718			$sysuser->save();
719
720			$vars = array(
721				'x' => $sysuser->getId(),
722				'y' => $sysuser->getName(),
723				'z' => $sysuser->getValue('email')
724			);
725
726			e107::getLog()->add('USET_10', $tp->lanVars( USRLAN_166, $vars), E_LOG_INFORMATIVE);
727			e107::getEvent()->trigger('userfull', $row); //BC
728			e107::getEvent()->trigger('admin_user_activated', $row);
729
730			$mes->addSuccess(USRLAN_86." (#".$sysuser->getId()." : ".$sysuser->getName().' - '.$sysuser->getValue('email').")");
731
732			$this->getTreeModel()->loadBatch(true);
733
734			if ((int) e107::pref('core', 'user_reg_veri') == 2)
735			{
736				$message = USRLAN_114." ".$row['user_name'].",\n\n".USRLAN_122." ".SITENAME.".\n\n".USRLAN_123."\n\n";
737				$message .= str_replace("{SITEURL}", SITEURL, USRLAN_139);
738
739				$options = array(
740					'mail_subject' => USRLAN_113.' '.SITENAME,
741					'mail_body' => nl2br($message),
742				);
743
744			//	$options['debug'] = 1;
745
746				if($ret =$sysuser->email('email', $options))
747				{
748					$mes->addSuccess(USRLAN_224." ".$sysuser->getName().' ('.$sysuser->getValue('email').')');
749				}
750				else
751				{
752					$mes->addError(USRLAN_225." ".$sysuser->getName().' ('.$sysuser->getValue('email').')');
753				}
754			}
755		}
756		else
757		{
758			$mes->addError(USRLAN_223);
759			return;
760		}
761	}
762
763	/**
764	 * Main admin login as system user trigger
765	 */
766	public function ListLoginasTrigger($userid)
767	{
768		$mes = e107::getMessage();
769
770		if(e107::getUser()->getSessionDataAs())
771		{
772			$mes->addWarning(USRLAN_AS_3);
773		}
774	  	elseif(e107::getUser()->loginAs($userid))
775	  	{
776	  		$sysuser = e107::getSystemUser($userid);
777			$user = e107::getUser();
778
779			// TODO - lan
780			$mes->addSuccess('Successfully logged in as '.$sysuser->getName().' <a href="'.e_ADMIN_ABS.'users.php?mode=main&amp;action=logoutas">[logout]</a>')
781				->addSuccess('Please, <a href="'.SITEURL.'" rel="external">Leave Admin</a> to browse the system as this user. Use &quot;Logout&quot; option in Administration to end front-end session');
782
783			$search = array('--UID--', '--NAME--', '--EMAIL--', '--ADMIN_UID--', '--ADMIN_NAME--', '--ADMIN_EMAIL--');
784			$replace = array($sysuser->getId(), $sysuser->getName(), $sysuser->getValue('email'), $user->getId(), $user->getName(), $user->getValue('email'));
785
786			 // TODO - lan
787			$lan = 'Administrator --ADMIN_EMAIL-- (#--ADMIN_UID--, --ADMIN_NAME--) has logged in as the user --EMAIL-- (#--UID--, --NAME--)';
788
789			e107::getLog()->log_event('USET_100', str_replace($search, $replace, $lan), E_LOG_INFORMATIVE);
790
791			$eventData = array('user_id' => $sysuser->getId(), 'admin_id' => $user->getId());
792			e107::getEvent()->trigger('loginas', $eventData); // BC
793			e107::getEvent()->trigger('admin_user_loginas', $eventData);
794
795	  	}
796	}
797
798	/**
799	 * Main admin logout as a system user trigger
800	 */
801	public function LogoutasObserver()
802	{
803		$user = e107::getUser();
804		$sysuser = e107::getSystemUser($user->getSessionDataAs(), false);
805
806	  	if(e107::getUser()->logoutAs() && $sysuser && $sysuser->getId())
807	  	{
808	  		 // TODO - lan
809			e107::getMessage()->addSuccess('Successfully logged out from '.$sysuser->getName().' ('.$sysuser->getValue('email').') account', 'default', true);
810
811			$search = array('--UID--', '--NAME--', '--EMAIL--', '--ADMIN_UID--', '--ADMIN_NAME--', '--ADMIN_EMAIL--');
812			$replace = array($sysuser->getId(), $sysuser->getName(), $sysuser->getValue('email'), $user->getId(), $user->getName(), $user->getValue('email'));
813
814			 // TODO - lan
815			$lan = 'Administrator --ADMIN_EMAIL-- (#--ADMIN_UID--, --ADMIN_NAME--) has logged out as the user --EMAIL-- (#--UID--, --NAME--)';
816
817			e107::getAdminLog()->log_event('USET_101', str_replace($search, $replace, $lan), E_LOG_INFORMATIVE);
818
819			$eventData = array('user_id' => $sysuser->getId(), 'admin_id' => $user->getId());
820			e107::getEvent()->trigger('logoutas', $eventData); //BC
821			e107::getEvent()->trigger('admin_user_logoutas', $eventData);
822			$this->redirect('list', 'main', true);
823	  	}
824
825
826  		 if(!$sysuser->getId()) e107::getMessage()->addError(LAN_USER_NOT_FOUND);
827	}
828
829	public function LogoutasPage()
830	{
831		// System Message only on non-successful logout as another user
832	}
833
834	/**
835	 * Remove admin status trigger
836	 */
837	public function ListUnadminTrigger($userid)
838	{
839		$user = e107::getUser();
840		$sysuser = e107::getSystemUser($userid, false);
841		$mes = e107::getMessage();
842		$tp = e107::getParser();
843
844		if(!$user->checkAdminPerms('3'))
845		{
846			$mes->addError(USRLAN_226, 'default', true);
847
848			//$search = array('--UID--', '--NAME--', '--EMAIL--', '--ADMIN_UID--', '--ADMIN_NAME--', '--ADMIN_EMAIL--');
849			$vars = array(
850				'u' => $sysuser->getId(),
851				'v' => $sysuser->getName(),
852				'w' => $sysuser->getValue('email'),
853				'x' => $user->getId(),
854				'y' => $user->getName(),
855				'z' => $user->getValue('email')
856			);
857
858			e107::getAdminLog()->log_event('USET_08', $tp->lanVars(USRLAN_244,$vars), E_LOG_INFORMATIVE);
859			$this->redirect('list', 'main', true);
860		}
861
862		if ($sysuser->isMainAdmin())
863		{
864			$mes->addError(USRLAN_5);
865		}
866		else
867		{
868			if($sysuser->set('user_admin', '0')->set('user_perms', '')->save())
869			{
870				$vars = array('x'=>$sysuser->getId(), 'y'=>$sysuser->getName(), 'z'=>$sysuser->getValue('email'));
871
872				e107::getAdminLog()->log_event('USET_09',$tp->lanVars(USRLAN_165, $vars), E_LOG_INFORMATIVE);
873				$mes->addSuccess($sysuser->getName()." (".$sysuser->getValue('email').") ".USRLAN_6);
874				$this->getTreeModel()->loadBatch(true);
875			}
876			else
877			{
878				$mes->addError(USRLAN_227);
879			}
880		}
881	}
882
883	/**
884	 * Admin manage observer
885	 * @return void
886	 */
887	public function AdminObserver()
888	{
889		if($this->getPosted('go_back'))
890		{
891			$this->redirect('list', 'main', true);
892		}
893
894		$userid = $this->getId();
895		$sql = e107::getDb();
896		$user = e107::getUser();
897		$sysuser = e107::getSystemUser($userid, false);
898		$admin_log = e107::getAdminLog();
899		$mes = e107::getMessage();
900		$tp = e107::getParser();
901
902		if(!$user->checkAdminPerms('3'))
903		{
904			$mes->addError(USRLAN_226, 'default', true);
905		//	$search = array('--UID--', '--NAME--', '--EMAIL--', '--ADMIN_UID--', '--ADMIN_NAME--', '--ADMIN_EMAIL--');
906
907			$vars = array(
908				'u' => $sysuser->getId(),
909				'v' => $sysuser->getName(),
910				'w' => $sysuser->getValue('email'),
911				'x' => $user->getId(),
912				'y' => $user->getName(),
913				'z' => $user->getValue('email')
914			);
915
916		//	$replace = array($sysuser->getId(), $sysuser->getName(), $sysuser->getValue('email'), $user->getId(), $user->getName(), $user->getValue('email'));
917
918			e107::getLog()->add('USET_08', $tp->lanVars( USRLAN_245,$vars), E_LOG_INFORMATIVE);
919
920			$this->redirect('list', 'main', true);
921		}
922
923		if(!$sysuser->getId())
924		{
925			$mes->addError(USRLAN_223, 'default', true);
926			$this->redirect('list', 'main', true);
927		}
928
929
930		if($this->getPosted('update_admin'))
931		{
932			 e107::getUserPerms()->updatePerms($userid, $_POST['perms']);
933			 $this->redirect('list', 'main', true);
934		}
935
936		if(!$sysuser->isAdmin()) // Security Check Only. Admin status check is added during 'updatePerms'.
937		{
938		//	$sysuser->set('user_admin', 1)->save(); //"user","user_admin='1' WHERE user_id={$userid}"
939		//	$lan = str_replace(array('--UID--', '--NAME--', '--EMAIL--'), array($sysuser->getId(), $sysuser->getName(), $sysuser->getValue('email')), USRLAN_164);
940		//	e107::getLog()->add('USET_08', $lan, E_LOG_INFORMATIVE);
941		//	$mes->addSuccess($lan);
942			$rplc_from = array('[x]', '[y]', '[z]');
943			$rplc_to = array($sysuser->getId(), $sysuser->getName(), $sysuser->getValue('email'));
944			$message = str_replace($rplc_from, $rplc_to, USRLAN_228);
945			$message = e107::getParser()->toHTML($message,true);
946			$mes->addWarning($message);
947			$mes->addWarning(e107::getParser()->toHTML(USRLAN_229,true));
948		}
949
950	}
951
952	/**
953	 * Admin manage page
954	 */
955	public function AdminPage()
956	{
957		$request = $this->getRequest();
958		$response = $this->getResponse();
959		$sysuser = e107::getSystemUser($request->getId(), false);
960		//$sysuser->load($request->getId(), true);
961		$prm = e107::getUserPerms();
962		$frm = e107::getForm();
963
964		$response->appendBody($frm->open('adminperms'))
965			->appendBody($prm->renderPermTable('grouped', $sysuser->getValue('perms')))
966			->appendBody($prm->renderCheckAllButtons())
967			->appendBody($prm->renderSubmitButtons().$frm->token())
968			->appendBody($frm->close());
969
970		$this->addTitle(str_replace(array('[x]', '[y]'), array($sysuser->getName(), $sysuser->getValue('email')), USRLAN_230));
971	}
972
973	protected function checkAllowed($class_id) // check userclass change is permitted.
974	{
975		$e_userclass = e107::getUserClass();
976		if (!isset ($e_userclass->class_tree[$class_id]))
977		{
978			return false;
979		}
980		if (!getperms("0") && !check_class($e_userclass->class_tree[$class_id]['userclass_editclass']))
981		{
982			return false;
983		}
984		return true;
985	}
986
987	protected function manageUserclass($userid, $uclass, $mode = false)
988	{
989		$request = $this->getRequest();
990		$response = $this->getResponse();
991		$sysuser = e107::getSystemUser($userid, false);
992
993		$admin_log = e107::getAdminLog();
994		$e_userclass = e107::getUserClass();
995		$sql = e107::getDb();
996
997		$remuser = true;
998        $mes = e107::getMessage();
999
1000		if(!$sysuser->getId())
1001		{
1002			$mes->addError(USRLAN_223);
1003			return false;
1004		}
1005
1006		$curClass = array();
1007		if($mode !== 'update')
1008		{
1009			$curClass = $sysuser->getValue('class') ? explode(',', $sysuser->getValue('class')) : array();
1010        }
1011
1012    	foreach ($uclass as $a)
1013		{
1014			$a = intval($a);
1015			if(!$this->checkAllowed($a))
1016			{
1017				$mes->addError(USRLAN_231);
1018				return false;
1019			}
1020
1021			if($a != 0) // if 0 - then do not add.
1022			{
1023				$curClass[] = $a;
1024			}
1025		}
1026
1027		if($mode == "remove") // remove selected classes
1028		{
1029			$curClass = array_diff($curClass, $uclass);
1030		}
1031		elseif($mode == "clear") // clear all classes
1032		{
1033			$curClass = array();
1034		}
1035
1036        $curClass = array_unique($curClass);
1037
1038        $svar = is_array($curClass) ? implode(",", $curClass) : "";
1039		$check = $sysuser->set('user_class', $svar)->save();
1040
1041		if($check)
1042		{
1043			$message = UCSLAN_9;
1044			if ($this->getPosted('notifyuser'))
1045			{
1046				$options = array();
1047				$message .= "<br />".UCSLAN_1.":</b> ".$sysuser->getName()."<br />";
1048
1049				$messaccess = '';
1050				foreach ($curClass as $a)
1051				{
1052					if (!isset ($e_userclass->fixed_classes[$a]))
1053					{
1054						$messaccess .= $e_userclass->class_tree[$a]['userclass_name']." - ".$e_userclass->class_tree[$a]['userclass_description']."\n";
1055					}
1056				}
1057				if ($messaccess == '') $messaccess = UCSLAN_12."\n";
1058
1059				$message = USRLAN_256." ".$sysuser->getName().",\n\n".UCSLAN_4." ".SITENAME."\n( ".SITEURL." )\n\n".UCSLAN_5.": \n\n".$messaccess."\n".UCSLAN_10."\n".SITEADMIN;
1060				//    $admin_log->e_log_event(4,__FILE__."|".__FUNCTION__."@".__LINE__,"DBG","User class change",str_replace("\n","<br />",$message),FALSE,LOG_TO_ROLLING);
1061
1062				$options['mail_subject'] = UCSLAN_2;
1063				$options['mail_body'] = nl2br($message);
1064
1065				$sysuser->email('email', $options);
1066				//sendemail($send_to,$subject,$message);
1067			}
1068			e107::getLog()->add('USET_14', str_replace(array('[x]','[y]'), array($userid, $svar), UCSLAN_11), E_LOG_INFORMATIVE);
1069
1070            $mes->addSuccess(nl2br($message));
1071		}
1072		else
1073		{
1074           	//	$mes->add("Update Failed", E_MESSAGE_ERROR);
1075        	if($check === false)
1076			{
1077				$sysuser->setMessages(); // move messages to the default stack
1078			}
1079			else
1080			{
1081				$mes->addInfo(LAN_NO_CHANGE);
1082			}
1083		}
1084	}
1085
1086	/**
1087	 * Update user class trigger
1088	 */
1089	public function UserclassUpdateclassTrigger()
1090	{
1091		$this->manageUserclass($this->getId(), $this->getPosted('userclass'), 'update');
1092	}
1093
1094	/**
1095	 * Back to user list trigger (userclass page)
1096	 */
1097	public function UserclassBackTrigger()
1098	{
1099		$this->redirect('list', 'main', true);
1100	}
1101
1102	/**
1103	 * Manage userclasses page
1104	 */
1105	public function UserclassPage()
1106	{
1107		$request = $this->getRequest();
1108		$response = $this->getResponse();
1109		$sysuser = e107::getSystemUser($request->getId(), false);
1110		$e_userclass = e107::getUserClass();
1111		$userid = $this->getId();
1112		$frm = e107::getForm();
1113
1114		$caption = UCSLAN_6." <b>".$sysuser->getName().' - '.$sysuser->getValue('email')."</b> (".$sysuser->getClassList(true).")";
1115		$this->addTitle($caption);
1116
1117		$text = "	<div>
1118					<form method='post' action='".e_REQUEST_URI."'>
1119					<fieldset id='core-user-userclass'>
1120
1121                    <table class='table adminform'>
1122					<colgroup>
1123						<col class='col-label' />
1124						<col class='col-control' />
1125					</colgroup>
1126					<tbody>
1127					<tr>
1128						<td>";
1129		$text .= $e_userclass->vetted_tree('userclass', array($e_userclass,'checkbox_desc'), $sysuser->getValue('class'), 'classes, no-excludes');
1130		$text .= '
1131						</td>
1132					</tr>
1133					</tbody>
1134					</table>
1135		';
1136
1137		$text .= "	<div class='buttons-bar center'>
1138	 					".$frm->hidden('userid', $userid)."
1139						".$frm->checkbox_label(USRLAN_255.'&nbsp;&nbsp;', 'notifyuser', 1)."
1140						".$frm->admin_button('etrigger_updateclass', LAN_NO_RECORDS_FOUND, 'update')."
1141						".$frm->admin_button('etrigger_back', LAN_BACK, 'cancel')."
1142					</div>
1143					</fieldset>
1144					</form>
1145					</div>";
1146
1147		$response->appendBody($text);
1148	}
1149
1150	/**
1151	 * Resend user activation email trigger
1152	 */
1153	public function ListResendTrigger($userid)
1154	{
1155		$this->resendActivation($userid);
1156	}
1157
1158	/**
1159	 * Resend user activation email helper
1160	 * FIXME - better Subject/Content for the activation email when user is bounced/deactivated.
1161	 */
1162	protected function resendActivation($id, $lfile = '')
1163	{
1164
1165		$sysuser = e107::getSystemUser($id, false);
1166		$key = $sysuser->getValue('sess');
1167		$mes = e107::getMessage();
1168
1169		if(!$sysuser->getId())
1170		{
1171			$mes->addError(USRLAN_223);
1172			return false;
1173		}
1174
1175		if(!$key || !$sysuser->getValue('ban'))
1176		{
1177			$mes->addError(USRLAN_232);
1178			$mes->addDebug("key: ".$key." ban: ".$sysuser->getValue('ban'));
1179			return false;
1180		}
1181
1182		// Check for a Language field, and if present, send the email in the user's language.
1183		// FIXME - make all system emails to be created from HTML email templates, this should fix the multi-lingual issue when sending multiple emails
1184		if ($lfile == "")
1185		{
1186			$lan = $sysuser->getValue('language');
1187			if ($lan)
1188			{
1189				$lfile = e_LANGUAGEDIR.$lan.'/lan_signup.php';
1190			}
1191		}
1192		if ($lfile && is_readable($lfile))
1193		{
1194			require_once($lfile);
1195		}
1196		else
1197		{
1198			//@FIXME use email templates by Language
1199			require_once (e_LANGUAGEDIR.e_LANGUAGE."/lan_signup.php");
1200		}
1201		if(!$lan) $lan = e_LANGUAGE;
1202
1203		// FIXME switch to e107::getUrl()->create(), use email content templates
1204		//$return_address = (substr(SITEURL,- 1) == "/") ? SITEURL."signup.php?activate.".$sysuser->getId().".".$key : SITEURL."/signup.php?activate.".$sysuser->getId().".".$key;
1205		$return_address = SITEURL."signup.php?activate.".$sysuser->getId().".".$key;
1206	//	$message = LAN_EMAIL_01." ".$sysuser->getName()."\n\n".LAN_SIGNUP_24." ".SITENAME.".\n".LAN_SIGNUP_21."\n\n";
1207	//	$message .= "<a href='".$return_address."'>".$return_address."</a>";
1208
1209
1210		$userInfo = array(
1211			'user_id'       =>  $sysuser->getId(),
1212			'user_name'     => $sysuser->getName(),
1213			'user_email'    =>  $sysuser->getValue('email'),
1214			'user_sess'     =>  $key,
1215			'user_loginname' =>  $sysuser->getValue('loginname'),
1216			);
1217
1218
1219		$passwordInput = e107::getPref('signup_option_password', 2);
1220
1221		if(empty($passwordInput)) // auto-generated password at signup.
1222		{
1223			$newPwd = e107::getUserSession()->resetPassword($userInfo['user_id']);
1224		}
1225		else
1226		{
1227			$newPwd = '**********';
1228		}
1229
1230		$message = 'null';
1231
1232		$check = $sysuser->email('signup', array(
1233			'mail_subject' => LAN_SIGNUP_98,
1234			'mail_body' => nl2br($message),
1235			'user_password' => $newPwd
1236		), $userInfo);
1237
1238		if ($check)
1239		{
1240			$vars = array('x'=> $sysuser->getId(), 'y'=>$sysuser->getName(), 'z'=> $sysuser->getValue('email'));
1241			$message = e107::getParser()->lanVars(USRLAN_167,$vars);
1242			e107::getLog()->add('USET_11', $message, E_LOG_INFORMATIVE);
1243			$mes->addSuccess(USRLAN_140.": <a href='mailto:".$sysuser->getValue('email')."?body=".$return_address."' title=\"".LAN_USER_08."\" >".$sysuser->getName()." (".$sysuser->getValue('email').")</a> ({$lan}) ");
1244		}
1245		else
1246		{
1247			$mes->addError(USRLAN_141.": ".$sysuser->getName().' ('.$sysuser->getValue('email').')');
1248		}
1249		return $check;
1250	}
1251
1252	/**
1253	 * Test user email observer
1254	 */
1255	public function TestObserver()
1256	{
1257		$sysuser = e107::getSystemUser($this->getId(), false);
1258		$mes = e107::getMessage();
1259		$email = $sysuser->getValue('email');
1260
1261		if(!$sysuser->getId())
1262		{
1263			$mes->addError(USRLAN_223, 'default', true);
1264			$this->redirect('list', 'main', true);
1265		}
1266
1267		$result = $this->testEmail($email);
1268		if($result)
1269		{
1270			$this->setParam('testSucces', $result);
1271			$mes->addSuccess($email.' - '.USRLAN_233);
1272		}
1273		else
1274		{
1275			$mes->addError($email.' - '.USRLAN_234, 'default', true); // Invalid.
1276			$this->redirect('list', 'main', true);
1277		}
1278
1279	}
1280
1281	public function TestCancelTrigger()
1282	{
1283		$this->redirect('list', 'main', true);
1284	}
1285
1286	/**
1287	 * Resend activation email page - only if tested email is valid
1288	 */
1289	public function TestPage()
1290	{
1291		$response = $this->getResponse();
1292		$sysuser = e107::getSystemUser($this->getId(), false);
1293		$userid = $this->getId();
1294		$email = $sysuser->getValue('email');
1295		$frm = e107::getForm();
1296
1297		$caption = str_replace('[x]', $email, USRLAN_119);
1298		$this->addTitle($caption);
1299
1300		$text = "<a href='".e_REQUEST_HTTP."?mode=main&amp;action=list'>".LAN_BACK."</a>";
1301		$text .= '<pre>'.htmlspecialchars($this->getParam('testSucces')).'</pre>';
1302		$text .= "	<div>
1303					<form method='post' action='".e_REQUEST_HTTP."?mode=main&amp;action=list'>
1304					<fieldset id='core-user-testemail'>
1305						<div class='buttons-bar center'>
1306		 					".$frm->hidden('useraction', 'resend')."
1307							".$frm->hidden('userid', $userid)."
1308							".$frm->hidden('userip', $sysuser->getValue('ip'))."
1309							".$frm->admin_button('resend', USRLAN_112, 'update')."
1310						</div>
1311					</fieldset>
1312					</form>
1313					</div>";
1314
1315		$response->appendBody($text);
1316	}
1317
1318	/**
1319	 * Test user email helper
1320	 */
1321	protected function testEmail($email)
1322	{
1323		list($adminuser,$adminhost) = explode('@',SITEADMINEMAIL, 2);
1324
1325		$validator = new email_validation_class;
1326		$validator->localuser = $adminuser;
1327		$validator->localhost = $adminhost;
1328		$validator->timeout = 5;
1329		$validator->debug = 1;
1330		$validator->html_debug = 0;
1331
1332		ob_start();
1333		$email_status = $validator->ValidateEmailBox($email);
1334		$text = ob_get_contents();
1335		ob_end_clean();
1336
1337		if ($email_status == 1)
1338		{
1339			return $text;
1340		}
1341
1342		return false;
1343	}
1344
1345	/**
1346	 * Set user status to require verification - available for bounced users
1347	 */
1348	public function ListReqverifyTrigger($userid)
1349	{
1350		$sysuser = e107::getSystemUser($userid, false);
1351
1352		if(!$sysuser->getId())
1353		{
1354			e107::getMessage()->addError(USRLAN_223, 'default', true);
1355			return;
1356		}
1357
1358		$sysuser->set('user_ban', 2)
1359			->set('user_sess', e_user_model::randomKey());
1360
1361		if($sysuser->save())
1362		{
1363			e107::getMessage()->addSuccess(USRLAN_235);
1364
1365			// TODO - auto-send email or not - discuss
1366			$this->resendActivation($userid);
1367
1368			//FIXME admin log
1369
1370			// Reload tree
1371			$this->getTreeModel()->loadBatch(true);
1372			return;
1373		}
1374
1375		e107::getMessage()->addError(USRLAN_236);
1376	}
1377
1378	public function EditSubmitTrigger()
1379	{
1380		$this->_manageSubmit('beforeUpdate', 'afterUpdate', 'onUpdateError', 'edit', true); // force update.
1381	}
1382
1383
1384
1385	/**
1386	 * Quick Add user submit trigger
1387	 */
1388	public function AddSubmitTrigger()
1389	{
1390		$e107cache 		= e107::getCache();
1391		$userMethods 	= e107::getUserSession();
1392		$mes 			= e107::getMessage();
1393		$sql 			= e107::getDb();
1394		$e_event 		= e107::getEvent();
1395		$admin_log		= e107::getAdminLog();
1396		$pref = e107::getPref();
1397
1398		if (!$_POST['ac'] == md5(ADMINPWCHANGE))
1399		{
1400			exit;
1401		}
1402
1403		$e107cache->clear('online_menu_member_total');
1404		$e107cache->clear('online_menu_member_newest');
1405		$error = false;
1406
1407		if (isset ($_POST['generateloginname']))
1408		{
1409			$_POST['loginname'] = $userMethods->generateUserLogin($pref['predefinedLoginName']);
1410		}
1411
1412		$_POST['password2'] = $_POST['password1'] = $_POST['password'];
1413
1414		// #1728 - Default value, because user will always be part of 'Members'
1415		$_POST['class'][] =  e_UC_MEMBER;
1416
1417		// Now validate everything
1418		$allData = validatorClass::validateFields($_POST, $userMethods->userVettingInfo, true);
1419
1420		// Fix Display and user name
1421		if (!check_class($pref['displayname_class'], $allData['data']['user_class']))
1422		{
1423			if ($allData['data']['user_name'] != $allData['data']['user_loginname'])
1424			{
1425				$allData['data']['user_name'] = $allData['data']['user_loginname'];
1426				$message = str_replace('[x]', $allData['data']['user_loginname'], USRLAN_237);
1427				$message = e107::getParser()->toHTML($message,true);
1428				$mes->addWarning($message);
1429				//$allData['errors']['user_name'] = ERR_FIELDS_DIFFERENT;
1430			}
1431		}
1432
1433		// Do basic validation
1434		validatorClass::checkMandatory('user_name, user_loginname', $allData);
1435
1436		// Check for missing fields (email done in userValidation() )
1437		validatorClass::dbValidateArray($allData, $userMethods->userVettingInfo, 'user', 0);
1438
1439		// Do basic DB-related checks
1440		$userMethods->userValidation($allData);
1441
1442		// Do user-specific DB checks
1443		if (!isset($allData['errors']['user_password']))
1444		{
1445			// No errors in password - keep it outside the main data array
1446			$savePassword = $allData['data']['user_password'];
1447			// Delete the password value in the output array
1448			unset ($allData['data']['user_password']);
1449		}
1450
1451		// Restrict the scope of this
1452		unset($_POST['password2'], $_POST['password1']);
1453
1454		if (count($allData['errors']))
1455		{
1456			$temp = validatorClass::makeErrorList($allData, 'USER_ERR_','%n - %x - %t: %v', '<br />', $userMethods->userVettingInfo);
1457			$mes->addError($temp);
1458			$error = true;
1459		}
1460
1461		// Always save some of the entered data - then we can redisplay on error
1462		$user_data = & $allData['data'];
1463
1464		if($error)
1465		{
1466			$this->setParam('user_data', $user_data);
1467			return;
1468		}
1469
1470		if(varset($_POST['perms']))
1471		{
1472			$allData['data']['user_admin'] = 1;
1473			$allData['data']['user_perms'] = implode('.',$_POST['perms']);
1474		}
1475
1476
1477
1478		$user_data['user_password'] = $userMethods->HashPassword($savePassword, $user_data['user_loginname']);
1479		$user_data['user_join'] = time();
1480
1481		e107::getMessage()->addDebug("Password Hash: ".$user_data['user_password']);
1482
1483		if ($userMethods->needEmailPassword())
1484		{
1485			// Save separate password encryption for use with email address
1486            $user_prefs = e107::getArrayStorage()->unserialize($user_data['user_prefs']);
1487            $user_prefs['email_password'] = $userMethods->HashPassword($savePassword, $user_data['user_email']);
1488			$user_data['user_prefs'] = e107::getArrayStorage()->serialize($user_prefs);
1489            unset($user_prefs);
1490		}
1491
1492		$userMethods->userClassUpdate($allData['data'], 'userall');
1493
1494		//FIXME - (SecretR) there is a better way to fix this (missing default value, sql error in strict mode - user_realm is to be deleted from DB later)
1495		$allData['data']['user_realm'] = '';
1496
1497		// Set any initial classes
1498		$userMethods->addNonDefaulted($user_data);
1499		validatorClass::addFieldTypes($userMethods->userVettingInfo, $allData);
1500
1501		$userid = $sql->insert('user', $allData);
1502		if ($userid)
1503		{
1504			$this->saveExtended(array('submit_value'=>$userid));
1505
1506			$sysuser = e107::getSystemUser(false, false);
1507			$sysuser->setData($allData['data']);
1508			$sysuser->setId($userid);
1509			$user_data['user_id'] = $userid;
1510
1511			// Add to admin log
1512			e107::getLog()->add('USET_02',"UName: {$user_data['user_name']}; Email: {$user_data['user_email']}", E_LOG_INFORMATIVE);
1513
1514			// Add to user audit trail
1515			e107::getLog()->user_audit(USER_AUDIT_ADD_ADMIN, $user_data, 0, $user_data['user_loginname']);
1516			e107::getEvent()->trigger('userfull', $user_data);
1517			e107::getEvent()->trigger('admin_user_created', $user_data);
1518
1519			// send everything available for user data - bit sparse compared with user-generated signup
1520			if(isset($_POST['sendconfemail']))
1521			{
1522				$check = false;
1523
1524				// Send confirmation email to user
1525				switch ((int) $_POST['sendconfemail'])
1526				{
1527					case 0:
1528						// activate, don't notify
1529						$check = -1;
1530					break;
1531
1532					case 1:
1533						// activate and send password
1534						$check = $sysuser->email('quickadd', array(
1535							'user_password' => $savePassword,
1536							'mail_subject' => USRLAN_187,
1537							'activation_url' => USRLAN_246,
1538						));
1539					break;
1540
1541					case 2:
1542						// require activation and send password and activation link
1543						$sysuser->set('user_ban', 2)
1544							->set('user_sess', e_user_model::randomKey())
1545							->save();
1546
1547						$check = $sysuser->email('quickadd', array(
1548							'user_password' => $savePassword,
1549							'mail_subject' => USRLAN_187,
1550							'activation_url' => SITEURL."signup.php?activate.".$sysuser->getId().".".$sysuser->getValue('sess'),
1551						));
1552					break;
1553				}
1554
1555				if($check && $check !== -1)
1556				{
1557					$mes->addSuccess(USRLAN_188);
1558				}
1559				elseif(!$check)
1560				{
1561					$mes->addError(USRLAN_189);
1562				}
1563			}
1564
1565		//	$message = str_replace('--NAME--', htmlspecialchars($user_data['user_name'], ENT_QUOTES, CHARSET), USRLAN_174);
1566			$message = USRLAN_172; // "User account has been created with the following:" ie. keep it simple so it can easily be copied and pasted.
1567
1568			// Always show Login name and password
1569			//if (isset($_POST['generateloginname']))
1570			{
1571				$mes->addSuccess($message)
1572					->addSuccess(USRLAN_128.': <strong>'.htmlspecialchars($user_data['user_loginname'], ENT_QUOTES, CHARSET).'</strong>');
1573			}
1574
1575			//if (isset($_POST['generatepassword']))
1576			{
1577				$mes->addSuccess(LAN_PASSWORD.': <strong>'.htmlspecialchars($savePassword, ENT_QUOTES, CHARSET).'</strong>');
1578			}
1579			return;
1580		}
1581		else
1582		{
1583			$mes->addError(LAN_CREATED_FAILED);
1584			$mes->addError($sql->getLastErrorText());
1585		}
1586	}
1587
1588	/**
1589	 * Quick add user page
1590	 */
1591	function AddPage()
1592	{
1593		$prm = e107::getUserPerms();
1594		//$list = $prm->getPermList();
1595		$frm = e107::getForm();
1596		$e_userclass = e107::getUserClass();
1597		$pref = e107::getPref();
1598		$user_data = $this->getParam('user_data');
1599
1600	// 	$this->addTitle(LAN_USER_QUICKADD);
1601
1602		$text = "<div>".$frm->open("core-user-adduser-form",null,null,'autocomplete=0')."
1603		<div style='display:none'><input type='password' id='_no_autocomplete_' /></div>
1604		<fieldset id='core-user-adduser'>
1605        <table class='table adminform'>
1606		<colgroup>
1607		<col class='col-label' />
1608		<col class='col-control' />
1609		</colgroup>
1610		<tr>
1611			<td>".USRLAN_61."</td>
1612			<td>
1613			".$frm->text('username', varset($user_data['user_name']), varset($pref['displayname_maxlength'], 15), array('size'=>'xlarge'))."
1614			</td>
1615		</tr>
1616
1617		<tr>
1618			<td>".USRLAN_128."</td>
1619			<td ><div class='form-inline'>
1620			".$frm->text('loginname', varset($user_data['user_loginname']), varset($pref['loginname_maxlength'], 30), array('size'=>'xlarge'))."&nbsp;&nbsp;
1621			".$frm->checkbox_label(USRLAN_170, 'generateloginname', 1, varset($pref['predefinedLoginName'], false))."
1622			</div></td>
1623		</tr>
1624
1625		<tr>
1626			<td>".USRLAN_129."</td>
1627			<td>
1628			".$frm->text('realname', varset($user_data['user_login']), 30, array('size'=>'xlarge'))."
1629			</td>
1630		</tr>
1631
1632		<tr>
1633			<td>".LAN_PASSWORD."</td>
1634			<td>".$frm->password('password', '', 128, array('size' => 'xlarge', 'class' => 'tbox e-password', 'generate' => 1, 'strength' => 1, 'autocomplete' => 'new-password'))."
1635 			</td>
1636		</tr>";
1637
1638
1639
1640		$text .= "
1641			<tr>
1642				<td>".USRLAN_64."</td>
1643				<td>
1644				".$frm->text('email', varset($user_data['user_email']), 100, array('size'=>'xlarge'))."
1645				</td>
1646			</tr>
1647
1648			<tr>
1649				<td>".USRLAN_239."</td>
1650				<td>
1651					".$frm->select('sendconfemail', array('0' => USRLAN_240, '1' => USRLAN_241, '2' => USRLAN_242), (int) varset($_POST['sendconfemail'], 0), array('size'=>'xlarge'))."
1652					<div class='field-help'>".USRLAN_181."</div>
1653				</td>
1654			</tr>";
1655
1656		if (!isset ($user_data['user_class'])) $user_data['user_class'] = varset($pref['initial_user_classes']);
1657		$temp = $e_userclass->vetted_tree('class', array($e_userclass, 'checkbox_desc'), $user_data['user_class'], 'classes, no-excludes');
1658
1659		if ($temp)
1660		{
1661			$text .= "<tr style='vertical-align:top'>
1662			<td>
1663				".USRLAN_120."
1664			</td>
1665			<td>
1666				<a href='#set_class' class='btn btn-default btn-secondary e-expandit'>".USRLAN_120."</a>
1667				<div class='e-hideme' id='set_class'>
1668				{$temp}
1669				</div>
1670			</td>
1671			</tr>\n";
1672		}
1673
1674		// Make Admin.
1675		$text .= "
1676		<tr>
1677			<td>".USRLAN_35."</td>
1678			<td>
1679				<a href='#set_perms' class='btn btn-default btn-secondary e-expandit'>".USRLAN_243."</a>
1680				<div class='e-hideme' id='set_perms'>
1681		";
1682
1683		$text .= $prm->renderPermTable('grouped');
1684
1685		$text .= "
1686				</div>
1687			</td>
1688		</tr>
1689		";
1690
1691
1692		$text .= "
1693
1694		</table>
1695		<div class='buttons-bar center'>
1696			".$frm->admin_trigger('submit', USRLAN_60, 'create')."
1697			".$frm->token()."
1698			<input type='hidden' name='ac' value='".md5(ADMINPWCHANGE)."' />
1699		</div>
1700		</fieldset>
1701		</form>
1702		</div>
1703		";
1704
1705
1706		return $text;
1707		//$ns->tablerender(USRLAN_59,$mes->render().$text);
1708	}
1709
1710	public function RanksUpdateTrigger()
1711	{
1712		$fg = array();
1713		$ranks_calc = '';
1714		$ranks_flist = '';
1715		$config = e107::getConfig();
1716		foreach ($_POST['op'] as $f => $o)
1717		{
1718			$cfg[$f]['op'] = $o;
1719			$cfg[$f]['val'] = varset($_POST['val'][$f],'');
1720			if ($_POST['val'][$f])
1721			{
1722				$ranks_calc .= ($ranks_calc ? ' + ' : '').'({'.$f.'} '." $o {$_POST['val'][$f]}".' )';
1723				$ranks_flist .= ($ranks_flist ? ',' : '').$f;
1724			}
1725		}
1726
1727		//Delete existing rank config
1728		e107::getDb()->delete('generic', "gen_type = 'user_rank_config'");
1729
1730		$tmp = array();
1731		$tmp['data']['gen_type'] = 'user_rank_config';
1732		$tmp['data']['gen_chardata'] = serialize($cfg);
1733		$tmp['_FIELD_TYPES']['gen_type'] = 'string';
1734		$tmp['_FIELD_TYPES']['gen_chardata'] = 'escape';
1735
1736		//Add the new rank config
1737		e107::getDb()->insert('generic', $tmp);
1738
1739		// save prefs
1740		$config->set('ranks_calc', $ranks_calc);
1741		$config->set('ranks_flist', $ranks_flist);
1742		$config->save();
1743		$config->resetMessages();
1744
1745		//Delete existing rank data
1746		e107::getDb()->delete('generic',"gen_type = 'user_rank_data'");
1747
1748		//Add main site admin info
1749		$tmp = array();
1750		$tmp['_FIELD_TYPES']['gen_datestamp'] = 'int';
1751		$tmp['_FIELD_TYPES']['gen_ip'] = 'todb';
1752		$tmp['_FIELD_TYPES']['gen_user_id'] = 'int';
1753		$tmp['_FIELD_TYPES']['gen_chardata'] = 'todb';
1754		$tmp['_FIELD_TYPES']['gen_intdata'] = 'int';
1755		$tmp['data']['gen_datestamp'] = 1;
1756		$tmp['data']['gen_type'] = 'user_rank_data';
1757		$tmp['data']['gen_ip'] = $_POST['calc_name']['main_admin'];
1758		$tmp['data']['gen_user_id'] = varset($_POST['calc_pfx']['main_admin'],0);
1759		$tmp['data']['gen_chardata'] = $_POST['calc_img']['main_admin'];
1760		e107::getDb()->insert('generic',$tmp);
1761
1762		//Add site admin info
1763		unset ($tmp['data']);
1764		$tmp['data']['gen_type'] = 'user_rank_data';
1765		$tmp['data']['gen_datestamp'] = 2;
1766		$tmp['data']['gen_ip'] = $_POST['calc_name']['admin'];
1767		$tmp['data']['gen_user_id'] = varset($_POST['calc_pfx']['admin'],0);
1768		$tmp['data']['gen_chardata'] = $_POST['calc_img']['admin'];
1769		e107::getDb()->insert('generic', $tmp);
1770
1771		//Add all current site defined ranks
1772		if (isset ($_POST['field_id']))
1773		{
1774			foreach ($_POST['field_id'] as $fid => $x)
1775			{
1776				unset ($tmp['data']);
1777				$tmp['data']['gen_type'] = 'user_rank_data';
1778				$tmp['data']['gen_ip'] = varset($_POST['calc_name'][$fid],'');
1779				$tmp['data']['gen_user_id'] = varset($_POST['calc_pfx'][$fid],0);
1780				$tmp['data']['gen_chardata'] = varset($_POST['calc_img'][$fid],'');
1781				$tmp['data']['gen_intdata'] = varset($_POST['calc_lower'][$fid],'_NULL_');
1782				e107::getDb()->insert('generic', $tmp);
1783			}
1784		}
1785
1786		//Add new rank, if posted
1787		if (varset($_POST['new_calc_lower']))
1788		{
1789			unset ($tmp['data']);
1790			$tmp['data']['gen_type'] = 'user_rank_data';
1791			$tmp['data']['gen_datestamp'] = 0;
1792			$tmp['data']['gen_ip'] = varset($_POST['new_calc_name']);
1793			$tmp['data']['gen_user_id'] = varset($_POST['new_calc_pfx'],0);
1794			$tmp['data']['gen_chardata'] = varset($_POST['new_calc_img']);
1795			$tmp['data']['gen_intdata'] = varset($_POST['new_calc_lower']);
1796			e107::getDb()->insert('generic', $tmp);
1797		}
1798
1799		e107::getMessage()->addSuccess(LAN_UPDATED); //XXX maybe not needed see pull/1816
1800		e107::getCache()->clear_sys('nomd5_user_ranks');
1801	}
1802
1803	function RanksDeleteTrigger($posted)
1804	{
1805		$rankId = (int) key($posted);
1806
1807		e107::getCache()->clear_sys('nomd5_user_ranks');
1808		if (e107::getDb()->delete('generic',"gen_id='{$rankId}'"))
1809		{
1810			e107::getMessage()->addSuccess(LAN_DELETED);
1811		}
1812		else
1813		{
1814			e107::getMessage()->addError(LAN_DELETED_FAILED);
1815		}
1816	}
1817
1818	function RanksPage()
1819	{
1820		$frm = e107::getForm();
1821		$e107 = e107::getInstance();
1822		$pref = e107::getPref();
1823		$mes = e107::getMessage();
1824		/** @var users_admin_form_ui $ui */
1825		$ui = $this->getUI();
1826		$tp = e107::getParser();
1827
1828		$ranks = e107::getRank()->getRankData();
1829		$tmp = e107::getFile()->get_files(e_IMAGE.'ranks', '.*?\.(png|gif|jpg)');
1830
1831	//	$this->addTitle(LAN_USER_RANKS);
1832
1833		foreach($tmp as $k => $v)
1834		{
1835			$imageList[] = $v['fname'];
1836		}
1837		unset($tmp);
1838		natsort($imageList);
1839
1840		$text = $frm->open('core-user-ranks-form');
1841
1842
1843		$fields = array(
1844			'type' => array('title' => USRLAN_207, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left', 'class' => 'left'),
1845			'rankName' => array('title' => USRLAN_208, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left', 'class' => 'left'),
1846			'lowThresh' => array('title' => USRLAN_209, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left', 'class' => 'left'),
1847			'langPrefix' => array('title' => USRLAN_210, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left', 'class' => 'left'),
1848			'rankImage' => array('title' => USRLAN_211, 'type' => 'text', 'width' => 'auto', 'thclass' => 'left', 'class' => 'left'),
1849		);
1850
1851
1852		$text .= "
1853		<table class='table adminlist'>".
1854		$frm->colGroup($fields, array_keys($fields)).
1855		$frm->thead($fields, array_keys($fields));
1856
1857		$info = $ranks['special'][1];
1858		$val = $tp->toForm($info['name']);
1859		$text .= "
1860		<tr>
1861			<td>".LAN_MAINADMIN."</td>
1862			<td>
1863				".$frm->text('calc_name[main_admin]', $val)."
1864			</td>
1865			<td>N/A</td>
1866			<td>".$frm->checkbox('calc_pfx[main_admin]', 1, $info['lan_pfx'] ? true : false)."</td>
1867			<td>".$ui->RankImageDropdown($imageList,'calc_img[main_admin]',$info['image'])."</td>
1868		</tr>
1869		";
1870		$info = $ranks['special'][2];
1871		$val = $tp->toForm($info['name']);
1872		$text .= "
1873		<tr>
1874			<td>".LAN_ADMIN."</td>
1875			<td>
1876				".$frm->text('calc_name[admin]', $val)."
1877			</td>
1878			<td>N/A</td>
1879			<td>".$frm->checkbox('calc_pfx[admin]', 1, $info['lan_pfx'] ? true : false)."</td>
1880			<td>".$ui->RankImageDropdown($imageList, 'calc_img[admin]', $info['image'])."</td>
1881		</tr>
1882		<tr>
1883			<td colspan='5'>&nbsp;</td>
1884		</tr>
1885		";
1886
1887		foreach ($ranks['data'] as $k => $r)
1888		{
1889			$pfx_checked = ($r['lan_pfx'] ? "checked='checked'" : '');
1890			$text .= "
1891			<tr>
1892				<td>".USRLAN_212."</td>
1893				<td>
1894					<input type='hidden' name='field_id[{$k}]' value='1' />
1895					<input class='tbox' type='text' name='calc_name[$k]' value='{$r['name']}' />
1896				</td>
1897				<td>".$frm->number("calc_lower[{$k}]", $r['thresh'])."</td>
1898				<td>".$frm->checkbox("calc_pfx[{$k}]", 1, $r['lan_pfx'] ? true : false)."</td>
1899				<td>".$ui->RankImageDropdown($imageList, "calc_img[$k]", $r['image'])."&nbsp;".
1900				$frm->submit_image("etrigger_delete[{$r['id']}]", LAN_DELETE, 'delete', LAN_CONFIRMDEL.": [{$r['name']}]?")."
1901				</td>
1902			</tr>
1903			";
1904		}
1905
1906		$text .= "
1907
1908		<tr>
1909			<td colspan='5'>&nbsp;</td>
1910		</tr>
1911		<tr>
1912			<td>".USRLAN_214."</td>
1913			<td>".$frm->text('new_calc_name', '')."</td>
1914			<td>".$frm->number('new_calc_lower', '')."</td>
1915			<td>".$frm->checkbox('new_calc_pfx', 1, false)."</td>
1916			<td>".$ui->RankImageDropdown($imageList, 'new_calc_img')."</td>
1917		</tr>";
1918
1919		$text .= '</table>
1920		<div class="buttons-bar center">
1921		'.$frm->admin_trigger('update', 'no-value', 'update', LAN_UPDATE).'
1922		</div>
1923		</form>';
1924
1925		return $text;
1926	}
1927
1928	// ================== OLD CODE backup =============>
1929
1930	// It might be rewritten with user info option (ui trigger)
1931	// Old trigger code
1932	// if ((isset ($_POST['useraction']) && $_POST['useraction'] == "userinfo") || $_GET['userinfo'])
1933	// {
1934		// $ip = ($_POST['userip']) ? $_POST['userip'] : $_GET['userinfo'];
1935		// $user->user_info($ip);
1936	// }
1937	function user_info($ipd)
1938	{
1939		global $ns, $sql, $e107;
1940
1941		if (isset($ipd))
1942		{
1943			$bullet = '';
1944			if(defined('BULLET'))
1945			{
1946				$bullet = '<img src="'.THEME.'images/'.BULLET.'" alt="" class="icon" />';
1947			}
1948			elseif(file_exists(THEME.'images/bullet2.gif'))
1949			{
1950				$bullet = '<img src="'.THEME.'images/bullet2.gif" alt="" class="icon" />';
1951			}
1952            // TODO - move to e_userinfo.php
1953			$obj = new convert;
1954			$sql->db_Select("chatbox", "*", "cb_ip='$ipd' LIMIT 0,20");
1955			$host = $e107->get_host_name($ipd);
1956			$text = USFLAN_3." <b>".$ipd."</b> [ ".USFLAN_4.": $host ]<br />
1957				<i><a href=\"banlist.php?".$ipd."\">".USFLAN_5."</a></i>
1958
1959				<br /><br />";
1960			while (list($cb_id, $cb_nick, $cb_message, $cb_datestamp, $cb_blocked, $cb_ip ) = $sql->fetch())
1961			{
1962				$datestamp = $obj->convert_date($cb_datestamp, "short");
1963				$post_author_id = substr($cb_nick, 0, strpos($cb_nick, "."));
1964				$post_author_name = substr($cb_nick, (strpos($cb_nick, ".")+1));
1965				$text .= $bullet."
1966					<span class=\"defaulttext\"><i>".$post_author_name." (".USFLAN_6.": ".$post_author_id.")</i></span>
1967					<div class=\"mediumtext\">
1968					".$datestamp."
1969					<br />
1970					". $cb_message."
1971					</div>
1972					<br />";
1973			}
1974
1975			$text .= "<hr />";
1976
1977			$sql->db_Select("comments", "*", "comment_ip='$ipd' LIMIT 0,20");
1978			while (list($comment_id, $comment_item_id, $comment_author, $comment_author_email, $comment_datestamp, $comment_comment, $comment_blocked, $comment_ip) = $sql->fetch())
1979			{
1980				$datestamp = $obj->convert_date($comment_datestamp, "short");
1981				$post_author_id = substr($comment_author, 0, strpos($comment_author, "."));
1982				$post_author_name = substr($comment_author, (strpos($comment_author, ".")+1));
1983				$text .= $bullet."
1984					<span class=\"defaulttext\"><i>".$post_author_name." (".USFLAN_6.": ".$post_author_id.")</i></span>
1985					<div class=\"mediumtext\">
1986					".$datestamp."
1987					<br />". $comment_comment."
1988					</div>
1989					<br />";
1990			}
1991
1992		}
1993
1994		$ns->tablerender(USFLAN_7, $text);
1995	}
1996
1997
1998
1999
2000	function maintenancePage()
2001	{
2002		$frm = e107::getForm();
2003		$ns = e107::getRender();
2004		$sql = e107::getDb();
2005		$tp = e107::getParser();
2006
2007		$age = array(
2008			1=> LAN_UI_1_HOUR, 3=> LAN_UI_3_HOURS, 6=> LAN_UI_6_HOURS, 12=> LAN_UI_12_HOURS, 24 => LAN_UI_24_HOURS, 48 => LAN_UI_48_HOURS, 72 => LAN_UI_3_DAYS);
2009
2010		$count = $sql->count('user','(*)',"user_ban = 2 ");
2011		$caption = $tp->lanVars(USRLAN_252,$count);
2012
2013		$text = $frm->open('userMaintenance','post');
2014
2015		$text .= "
2016        <table class='table adminform'>
2017		<colgroup>
2018		<col class='col-label' />
2019		<col class='col-control' />
2020		</colgroup>
2021		<tr><td>".$caption."<td>
2022		<td>
2023		<div class='form-inline'>".USRLAN_253." ".$frm->select('resendAge', $age, 24).$frm->checkbox('resetPasswords',1,false,USRLAN_254).
2024		" <div class='input-group'>".$frm->userclass('resendClass',false, null )."<span class='input-group-btn'>".
2025		$frm->button('resendToAll', 1, 'warning', LAN_GO)."
2026
2027
2028		</span></div></div></td></tr>
2029		</table>";
2030
2031		$text .= $frm->close();
2032
2033		return $text;
2034
2035
2036
2037
2038	}
2039
2040
2041	/**
2042	 * Send an activation email to all unactivated users older than so many hours.
2043	 * @param bool $resetPasswords
2044	 * @param int $age in hours. ie. older than 24 hours will be sent an email.
2045	 */
2046	function resend_to_all($resetPasswords=false, $age=24, $class='')
2047	{
2048		global $sql,$pref;
2049		$tp = e107::getParser();
2050		$sql = e107::getDb();
2051		$sql2 = e107::getDb('toall');
2052
2053		$emailLogin = e107::getPref('allowEmailLogin');
2054
2055		e107::lan('core','signup');
2056
2057		$ageOpt = intval($age)." hours ago";
2058		$age = strtotime($ageOpt);
2059
2060	//	$query = "SELECT u.*, ue.* FROM `#user` AS u LEFT JOIN `#user_extended` AS ue ON ue.user_extended_id = u.user_id WHERE u.user_ban = 2 AND u.user_email != '' AND u.user_join < ".$age." ORDER BY u.user_id DESC";
2061
2062
2063		$query = "SELECT u.* FROM `#user` AS u WHERE u.user_ban = 2 AND u.user_email != '' AND u.user_join < ".$age." ";
2064
2065		if(!empty($class))
2066		{
2067			$query .= " AND FIND_IN_SET( ".intval($class).", u.user_class) ";
2068		}
2069
2070		$query .= " ORDER BY u.user_id DESC";
2071
2072		$sql->gen($query);
2073
2074		$recipients = array();
2075
2076		$usr = e107::getUserSession();
2077
2078		while ($row = $sql->fetch())
2079		{
2080
2081			if($resetPasswords === true)
2082			{
2083				$rawPassword    = $usr->generateRandomString('********');
2084				$sessKey        = e_user_model::randomKey();
2085
2086				$updateQry = array(
2087					'user_sess'     => $sessKey,
2088					'user_password' => $usr->HashPassword($rawPassword, $row['user_loginname']),
2089					'WHERE'         => 'user_id = '.$row['user_id']." LIMIT 1"
2090				);
2091
2092				if(!$sql2->update('user',$updateQry))
2093				{
2094
2095					e107::getMessage()->addError("Error updating user's password. #".$row['user_id']." : ".$row['user_email']);
2096					e107::getMessage()->addDebug(print_a($updateQry,true));
2097
2098				//	break;
2099				}
2100				else
2101				{
2102					e107::getMessage()->addInfo("Updated ".$row['user_id']." : ".$row['user_email']);
2103				}
2104
2105
2106				$row['user_sess'] = $sessKey;
2107
2108			}
2109			else
2110			{
2111				$rawPassword = '(*** hidden ***)';
2112			}
2113
2114			$activationUrl = SITEURL."signup.php?activate.".$row['user_id'].".".$row['user_sess'];
2115
2116
2117
2118			$recipients[] = array(
2119				'mail_recipient_id'     => $row['user_id'],
2120				'mail_recipient_name'   => $row['user_name'],		// Should this use realname?
2121				'mail_recipient_email'  => $row['user_email'],
2122				'mail_target_info'		=> array(
2123					'USERID'		        => $row['user_id'],
2124					'LOGINNAME'             => (intval($emailLogin) === 1) ? $row['user_email'] : $row['user_loginname'],
2125					'PASSWORD'              => $rawPassword,
2126					'DISPLAYNAME' 	        => $tp->toDB($row['user_name']),
2127					'SUBJECT'               => LAN_SIGNUP_98,
2128					'USERNAME' 		        => $row['user_name'],
2129					'USERLASTVISIT'         => $row['user_lastvisit'],
2130					'ACTIVATION_LINK'       => '<a href="'.$activationUrl.'">'.$activationUrl.'</a>', // Warning: switching the quotes on this will break the template.
2131					'ACTIVATION_URL'        => $activationUrl,
2132					'DATE_SHORT'            => $tp->toDate(time(),'short'),
2133					'DATE_LONG'             => $tp->toDate(time(),'long'),
2134					'SITEURL'               => SITEURL
2135				)
2136			);
2137
2138		//	echo $row['user_id']." ".$row['user_sess']." ".$row['user_name']." ".$row['user_email']."<br />";
2139
2140		}
2141
2142		$siteadminemail = e107::getPref('siteadminemail');
2143		$siteadmin = e107::getPref('siteadmin');
2144
2145		$mailer = e107::getBulkEmail();
2146
2147		// Create the mail body
2148		$mailData = array(
2149			'mail_total_count'      => count($recipients),
2150			'mail_content_status' 	=> MAIL_STATUS_TEMP,
2151			'mail_create_app' 		=> 'core',
2152			'mail_title' 			=> 'RESEND ACTIVATION',
2153			'mail_subject' 			=> LAN_SIGNUP_98,
2154			'mail_sender_email' 	=> e107::getPref('replyto_email',$siteadminemail),
2155			'mail_sender_name'		=> e107::getPref('replyto_name',$siteadmin),
2156			'mail_notify_complete' 	=> 0,			// NEVER notify when this email sent!!!!!
2157			'mail_body' 			=> 'null',
2158			'template'				=> 'signup',
2159			'mail_send_style'       => 'signup'
2160		);
2161
2162
2163		$mailer->sendEmails('signup', $mailData, $recipients, array('mail_force_queue'=>1));
2164		$totalMails = count($recipients);
2165
2166		$url = e_ADMIN."mailout.php?mode=pending&action=list";
2167
2168		e107::getMessage()->addSuccess("Total emails added to <a href='".$url."'>mail queue</a>: ".$totalMails);
2169
2170	}
2171
2172	// ---------------------------------------------------------------------
2173	//		Bounce handling - FIXME convert to cron job
2174	// ---------------------------------------------------------------------
2175	// $bounce_act has the task to perform:
2176	//	'first_check' - initial read of list of bounces
2177	//	'delnonbounce' - delete any emails that aren't bounces
2178	//  'clearemailbounce' - delete email address for any user whose emails bounced
2179	//	'delchecked' - delete the emails whose comma-separated IDs are in $bounce_arr
2180	//	'delall' - delete all bounced emails
2181
2182	/*
2183	function check_bounces($bounce_act = 'first_check',$bounce_arr = '')
2184	{
2185		### old Trigger code for bounce check
2186		// $bounce_act = '';
2187		// if (isset ($_POST['check_bounces']))
2188			// $bounce_act = 'first_check';
2189		// if (isset ($_POST['delnonbouncesubmit']))
2190			// $bounce_act = 'delnonbounce';
2191		// if (isset ($_POST['clearemailbouncesubmit']))
2192			// $bounce_act = 'clearemailbounce';
2193		// if (isset ($_POST['delcheckedsubmit']))
2194			// $bounce_act = 'delchecked';
2195		// if (isset ($_POST['delallsubmit']))
2196			// $bounce_act = 'delall';
2197		// if ($bounce_act)
2198		// {
2199			// $user->check_bounces($bounce_act,implode(',',$_POST['delete_email']));
2200			// require_once ("footer.php");
2201			// exit;
2202		// }
2203
2204		global $sql,$pref;
2205		include (e_HANDLER.'pop3_class.php');
2206		if (!trim($bounce_act))
2207		{
2208			$bounce_act = 'first_check';
2209		}
2210		//	  echo "Check bounces. Action: {$bounce_act}; Entries: {$bounce_arr}<br />";
2211		$obj = new receiveMail($pref['mail_bounce_user'],$pref['mail_bounce_pass'],$pref['mail_bounce_email'],$pref['mail_bounce_pop3'],varset($pref['mail_bounce_type'],'pop3'));
2212		$del_count = 0;
2213		if ($bounce_act != 'first_check')
2214		{
2215		// Must do some deleting
2216			$obj->connect();
2217			$tot = $obj->getTotalMails();
2218			$del_array = explode(',',$bounce_arr);
2219			for ($i = 1; $i <= $tot; $i++)
2220			{
2221			// Scan all emails; delete current one if meets the criteria
2222				$dodel = false;
2223				switch ($bounce_act)
2224				{
2225					case 'delnonbounce' :
2226						$head = $obj->getHeaders($i);
2227						$dodel = (!$head['bounce']);
2228						break;
2229					case 'clearemailbounce' :
2230						if (!in_array($i,$del_array))
2231							break;
2232						$head = $obj->getHeaders($i);
2233						if ($head['bounce'])
2234						{
2235							if (preg_match("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i",$obj->getBody($i),$result))
2236							{
2237								$usr_email = trim($result[0]);
2238							}
2239							if ($sql->db_Select('user','user_id, user_name, user_email',"user_email='".$usr_email."' "))
2240							{
2241								$row = $sql->fetch();
2242								if ($sql->db_Update('user',"`user_email`='' WHERE `user_id` = '".$row['user_id']."' ") !== false)
2243								{
2244								// echo "Deleting user email {$row['user_email']} for user {$row['user_name']}, id={$row['user_id']}<br />";
2245									$dodel = true;
2246								}
2247							}
2248						}
2249						break;
2250					case 'delall' :
2251						$dodel = true;
2252						break;
2253					case 'delchecked' :
2254						$dodel = in_array($i,$del_array);
2255						break;
2256				}
2257				if ($dodel)
2258				{
2259				//			  echo "Delete email ID {$i}<br />";
2260					$obj->deleteMails($i);
2261					$del_count++;
2262					// Keep track of number of emails deleted
2263				}
2264			}
2265			// End - Delete one email
2266			$obj->close_mailbox();
2267			// This actually deletes the emails
2268		}
2269		// End of email deletion
2270		// Now list the emails that are left
2271		$obj->connect();
2272		$tot = $obj->getTotalMails();
2273		$found = false;
2274		$DEL = ($pref['mail_bounce_delete']) ? true : false;
2275		$text = "<br /><div><form  method='post' action='".e_REQUEST_URI."'><table>
2276		<tr><td style='width:5%'>#</td><td>e107-id</td><td>email</td><td>Subject</td><td>Bounce</td></tr>\n";
2277
2278		$identifier = deftrue('MAIL_IDENTIFIER', 'X-e107-id');
2279
2280		for ($i = 1; $i <= $tot; $i++)
2281		{
2282			$head = $obj->getHeaders($i);
2283			if ($head['bounce'])
2284			{
2285			// Its a 'bounce' email
2286				if (preg_match('/.*'.$identifier.':(.*)MIME/',$obj->getBody($i),$result))
2287				{
2288					if ($result[1])
2289					{
2290						$id[$i] = intval($result[1]);
2291						// This should be a user ID - but not on special mailers!
2292						//	Try and pull out an email address from body - should be the one that failed
2293						if (preg_match("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i",$obj->getBody($i),$result))
2294						{
2295							$emails[$i] = "'".$result[0]."'";
2296						}
2297						$found = true;
2298					}
2299				}
2300				elseif (preg_match("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i",$obj->getBody($i),$result))
2301				{
2302					if ($result[0] && $result[0] != $pref['mail_bounce_email'])
2303					{
2304						$emails[$i] = "'".$result[0]."'";
2305						$found = true;
2306					}
2307					elseif ($result[1] && $result[1] != $pref['mail_bounce_email'])
2308					{
2309						$emails[$i] = "'".$result[1]."'";
2310						$found = true;
2311					}
2312				}
2313				if ($DEL && $found)
2314				{
2315				// Auto-delete bounced emails once noticed (if option set)
2316					$obj->deleteMails($i);
2317					$del_count++;
2318				}
2319			}
2320			else
2321			{
2322			// Its a warning message or similar
2323			//			  $id[$i] = '';			// Don't worry about an ID for now
2324			//				Try and pull out an email address from body - should be the one that failed
2325				if (preg_match("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i",$obj->getBody($i),$result))
2326				{
2327					$wmails[$i] = "'".$result[0]."'";
2328				}
2329			}
2330			$text .= "<tr><td>".$i."</td><td>".$id[$i]."</td><td>".(isset ($emails[$i]) ? $emails[$i] : $wmails[$i])."</td><td>".$head['subject']."</td><td>".($head['bounce'] ? ADMIN_TRUE_ICON : ADMIN_FALSE_ICON);
2331			$text .= "<input type='checkbox' name='delete_email[]' value='{$i}' /></td></tr>\n";
2332		}
2333		if ($del_count)
2334		{
2335			e107::getLog()->add('USET_13', e107::getParser()->lanVars(USRLAN_169, $del_count),E_LOG_INFORMATIVE);
2336		}
2337		if ($tot)
2338		{
2339		// Option to delete emails - only if there are some in the list
2340			$text .= "</table><table style='".ADMIN_WIDTH."'><tr>
2341			<td style='text-align: center;'><input class='btn btn-default btn-secondary button' type='submit' name='delnonbouncesubmit' value='".USRLAN_183."' /></td>\n
2342			<td style='text-align: center;'><input class='btn btn-default btn-secondary button' type='submit' name='clearemailbouncesubmit' value='".USRLAN_184."' /></td>\n
2343			<td style='text-align: center;'><input class='btn btn-default btn-secondary button' type='submit' name='delcheckedsubmit' value='".USRLAN_179."' /></td>\n
2344			<td style='text-align: center;'><input class='btn btn-default btn-secondary button' type='submit' name='delallsubmit' value='".USRLAN_180."' /></td>\n
2345			</td></tr>";
2346		}
2347		$text .= "</table></form></div>";
2348		array_unique($id);
2349		array_unique($emails);
2350		$all_ids = implode(',',$id);
2351		$all_emails = implode(',',$emails);
2352		$obj->close_mailbox();
2353		// This will actually delete emails
2354		// $tot has total number of emails in the mailbox
2355		$found = count($emails);
2356		// $found - Number of bounce emails found
2357		// $del_count has number of emails deleted
2358		// Update bounce status for users
2359		$ed = $sql->db_Update('user',"user_ban=3 WHERE (`user_id` IN (".$all_ids.") OR `user_email` IN (".$all_emails.")) AND user_sess !='' ");
2360		if (!$ed)
2361			$ed = '0';
2362		$this->show_message(str_replace(array('[w]','[x]','[y]','[z]'),array($tot,$del_count,$ed,$found),USRLAN_155).$text);
2363	}
2364	*/
2365// ------- FIXME  Prune Users move to cron --------------
2366// if (isset ($_POST['prune']))
2367// {
2368	// $e107cache->clear('online_menu_member_total');
2369	// $e107cache->clear('online_menu_member_newest');
2370	// $text = USRLAN_56.' ';
2371	// $bantype = $_POST['prune_type'];
2372	// if ($bantype == 30)
2373		// // older than 30 days.
2374	// {
2375		// $bantype = 2;
2376		// $ins = " AND user_join < ".strtotime("-30 days");
2377	// }
2378	// if ($sql->db_Select("user","user_id, user_name","user_ban= {$bantype}".$ins))
2379	// {
2380		// $uList = $sql->db_getList();
2381		// foreach ($uList as $u)
2382		// {
2383			// $text .= $u['user_name']." ";
2384			// $sql->db_Delete("user","user_id='{$u['user_id']}' ");
2385			// $sql->db_Delete("user_extended","user_extended_id='{$u['user_id']}' ");
2386		// }
2387		// e107::getLog()->add('USET_04',str_replace(array('[x]','--TYPE--'),array(count($uList),$bantype),USRLAN_160),E_LOG_INFORMATIVE);
2388	// }
2389	// $ns->tablerender(USRLAN_57,"<div style='text-align:center'><b>".$text."</b></div>");
2390	// unset ($text);
2391// }
2392}
2393
2394
2395class users_admin_form_ui extends e_admin_form_ui
2396{
2397
2398
2399	function user_admin($curval,$mode, $att)
2400	{
2401		$att['type'] = 'boolean';
2402
2403//		$uid = $this->getController()->getModel()->get('user_id');
2404		$perms = $this->getController()->getModel()->get('user_perms');
2405
2406		if($mode == 'filter' && getperms('3'))
2407		{
2408			return array(0=>LAN_NO, '1'=>LAN_YES);
2409		}
2410
2411		if($mode == 'read'  || (str_replace(".","",$perms) == '0') || !getperms('3'))
2412		{
2413			return $this->renderValue('user_admin',$curval,$att);
2414		}
2415
2416		if($mode == 'write')
2417		{
2418			return $this->renderElement('user_admin',$curval,$att);
2419		}
2420
2421
2422
2423	}
2424
2425
2426	function user_extended($curval,$mode, $att)
2427	{
2428		if($mode == 'read')
2429		{
2430			$field = $att['field'];
2431
2432			if($this->getController()->getAction() == 'list')
2433			{
2434				$data =  $this->getController()->getListModel()->get($field); // ($att['field']);
2435			}
2436			else
2437			{
2438				$data =  $this->getController()->getModel()->get($field); // ($att['field']);
2439			}
2440
2441
2442
2443			return e107::getUserExt()->renderValue($data, $att['ueType']);
2444
2445
2446		}
2447		if($mode == 'write')
2448		{
2449			// e107::getUserExt()->user_extended_edit
2450		//	return 'hello';
2451			$field = $att['field'];
2452			/** @var users_admin_ui $controller */
2453			$controller = $this->getController();
2454			$extData = $controller->getExtended();
2455			$extData[$field]['user_extended_struct_required'] = 0;
2456
2457			return e107::getUserExt()->user_extended_edit($extData[$field],$curval);
2458
2459		//	return print_a($att,true);
2460		}
2461
2462
2463	}
2464
2465
2466
2467
2468
2469	function user_perms($curval,$mode)
2470	{
2471		$perms = $this->getController()->getModel()->get('user_perms');
2472		$uid = $this->getController()->getModel()->get('user_id');
2473
2474		if($mode == 'read' || (str_replace(".","",$perms) == '0' && $uid == USERID) || !getperms('3'))
2475		{
2476			return e107::getUserPerms()->renderPerms($curval,$uid);
2477		}
2478		if($mode == 'write')
2479		{
2480			$prm = e107::getUserPerms();
2481			$text = "<a class='e-expandit' href='#perms'>".USRLAN_221."</a>";
2482			$text .= "<div id='perms' style='display:none'>". $prm->renderPermTable('grouped',$curval).'</div>';
2483			return $text;
2484		}
2485
2486
2487	}
2488
2489	function user_password($curval,$mode)
2490	{
2491		if($mode == 'read')
2492		{
2493			if(empty($curval))
2494			{
2495				return "No password!";
2496			}
2497
2498			// if(getperms('0'))
2499			{
2500
2501				$type = e107::getUserSession()->getHashType($curval, 'array');
2502				$num = $type[0];
2503
2504				$styles= array(0=>'label-danger',1=>'label-warning', 3=>'label-success');
2505
2506				return "<span class='label label-password ".$styles[$num]."'>".$type[1]."</span>";
2507			}
2508		}
2509		if($mode == 'write')
2510		{
2511			$fieldName = 'user_password_'. $this->getController()->getId();
2512
2513			return $this->password($fieldName, '', 128, array('size' => 50, 'class' => 'tbox e-password', 'placeholder' => USRLAN_251, 'generate' => 1, 'strength' => 1, 'required'=>0, 'autocomplete'=>'new-password'));
2514		}
2515
2516
2517	}
2518
2519
2520
2521
2522
2523
2524	function user_ban($curval,$mode)
2525	{
2526		$bo = array(
2527			'<span class="label label-success label-status">'.LAN_ACTIVE.'</span>',
2528			"<span class='label label-important label-danger label-status'>".LAN_BANNED."</span>",
2529			"<span class='label label-default label-status'>".LAN_NOTVERIFIED."</span>",
2530			"<span class='label label-info label-status'>".LAN_BOUNCED."</span>",
2531			"<span class='label label-important label-danger label-status'>".USRLAN_56."</span>", // Deleted
2532		);
2533
2534		if($mode == 'filter' || $mode == 'batch')
2535		{
2536			return 	$bo;
2537		}
2538
2539		$perms = $this->getController()->getModel()->get('user_perms');
2540
2541		if($mode == 'write')
2542		{
2543
2544			if(str_replace(".","",$perms) == '0')
2545			{
2546				return "<div style='width:120px'>".vartrue($bo[$curval],' ')."</div>";
2547			}
2548
2549			return $this->select('user_ban',$bo,$curval);
2550		}
2551
2552		return vartrue($bo[$curval],' '); // ($curval == 1) ? ADMIN_TRUE_ICON : '';
2553	}
2554
2555
2556	/*
2557	function user_class($curval,$mode)
2558		{
2559
2560			$e_userclass 	= new user_class;
2561			$frm 			= e107::getForm();
2562			$list 			= $e_userclass->uc_required_class_list("classes");
2563							 if($mode == 'filter')
2564			{
2565				return $list;
2566			}
2567
2568			if($mode == 'write') //FIXME userclasses are NOT be saved since they are an array.
2569			{
2570				return $frm->select('user_class', $list, $curval, 'description=1&multiple=1');
2571				// return $frm->uc_select('user_class[]', $curval, 'admin,classes', 'description=1&multiple=1');// doesn't work correctly.
2572			}
2573
2574
2575			//FIXME TODO - option to append userclass to existing value.
2576			if($mode == 'batch')
2577			{
2578				//$list['#delete'] = "(clear userclass)"; // special
2579				return $list;
2580			}
2581						  $tmp = explode(",",$curval);
2582			$text = array();
2583			foreach($tmp as $v)
2584			{
2585				$text[] = $list[$v];
2586			}
2587			return implode("<br />",$text); // $list[$curval];
2588
2589		}*/
2590
2591
2592	/*
2593	function user_status($curval,$mode)
2594	{
2595
2596		$row = $this->getController()->getListModel()->getData();
2597
2598		$text = "";
2599			if ($row['user_perms'] == "0")
2600			{
2601				$text .= "<div style='padding-left:3px;padding-right:3px;text-align:center;white-space:nowrap'>".LAN_MAINADMIN."</div>";
2602			}
2603			else
2604				if ($row['user_admin'])
2605				{
2606					$text .= "<div style='padding-left:3px;padding-right:3px;;text-align:center'><a href='".e_SELF."?main.user_admin.".($id == "desc" ? "asc" : "desc")."'>".LAN_ADMIN."</a></div>";
2607				}
2608				else
2609					if ($row['user_ban'] == 1)
2610					{
2611						$text .= "<div style='padding-left:3px;padding-right:3px;text-align:center;white-space:nowrap'><a href='".e_SELF."?main.user_ban.".($id == "desc" ? "asc" : "desc")."'>".LAN_BANNED."</a></div>";
2612					}
2613					else
2614						if ($row['user_ban'] == 2)
2615						{
2616							$text .= "<div class='label' style='padding-left:3px;padding-right:3px;text-align:center;white-space:nowrap' >".LAN_NOTVERIFIED."</div>";
2617						}
2618						else
2619							if ($row['user_ban'] == 3)
2620							{
2621								$text .= "<div style='padding-left:3px;padding-right:3px;text-align:center;white-space:nowrap' >".LAN_BOUNCED."</div>";
2622							}
2623							else
2624							{
2625								$text .= "&nbsp;";
2626							}
2627
2628		return $text;
2629
2630
2631	}
2632	*/
2633
2634	//TODO Reduce to simple edit/delete buttons only Other options included on edit page or available via inline or batch editing.
2635	function options($val, $mode) // old drop-down options.
2636	{
2637		$controller = $this->getController();
2638
2639		if($controller->getMode() != 'main' || $controller->getAction() != 'list') return;
2640		$row = $controller->getListModel()->getData();
2641
2642		if(!getperms('4'))
2643		{
2644		//	return;
2645		}
2646
2647
2648	//	extract($row);
2649
2650		$user_id = intval($row['user_id']);
2651		$user_ip = $row['user_ip'];
2652		$user_admin = $row['user_admin'];
2653
2654		$head = "<div>
2655
2656				<input type='hidden' name='userid[{$user_id}]' value='{$user_id}' />
2657				<input type='hidden' name='userip[{$user_id}]' value='{$user_ip}' />
2658				<input type='hidden'  class='user-action-hidden' id='user-action-".$user_id."' name='useraction[{$user_id}]' value='' />
2659				";
2660
2661		//		<select name='useraction[{$user_id}]' onchange='this.form.submit()' class='e-select tbox' data-placement='left' title='Modify' style='text-align:left;width:75%'>
2662		//		<option selected='selected' value=''>&nbsp;</option>";
2663
2664
2665		$opts = array();
2666
2667
2668
2669		if ($row['user_perms'] != "0")
2670		{
2671			// disabled user info <option value='userinfo'>".USRLAN_80."</option>
2672		//	$text .= "<option value='usersettings'>".LAN_EDIT."</option>";
2673			$opts['usersettings'] = LAN_EDIT;
2674
2675
2676
2677			// login/logout As
2678			if(getperms('0') && !($row['user_admin'] && getperms('0', $row['user_perms'])))
2679			{
2680				if(e107::getUser()->getSessionDataAs() == $row['user_id'])
2681				{
2682		//		    $text .= "<option value='logoutas'>".sprintf(USRLAN_AS_2, $row['user_name'])."</option>";
2683				    $opts['logoutas'] = e107::getParser()->lanVars(USRLAN_AS_2, $row['user_name']);
2684				}
2685				else
2686				{
2687		//		    $text .= "<option value='loginas'>".sprintf(USRLAN_AS_1, $row['user_name'])."</option>";
2688				    $opts['loginas'] = e107::getParser()->lanVars(USRLAN_AS_1, $row['user_name']);
2689				}
2690			}
2691			switch ($row['user_ban'])
2692			{
2693				case 0 :
2694		//			$text .= "<option value='ban'>".USRLAN_30."</option>\n";
2695					$opts['ban'] = USRLAN_30;
2696					break;
2697				case 1 :
2698					// Banned user
2699			//		$text .= "<option value='unban'>".USRLAN_33."</option>\n";
2700					$opts['unban'] = USRLAN_33;
2701					break;
2702				case 2 :
2703					// Unverified
2704			/*		$text .= "<option value='ban'>".USRLAN_30."</option>
2705						<option value='verify'>".USRLAN_32."</option>
2706						<option value='resend'>".USRLAN_112."</option>
2707						<option value='test'>".USRLAN_118."</option>";*/
2708
2709						$opts['ban'] = USRLAN_30;
2710						$opts['verify'] = USRLAN_32;
2711						$opts['resend'] = USRLAN_112;
2712						$opts['test'] = USRLAN_118;
2713					break;
2714				case 3 :
2715					// Bounced
2716					// FIXME wrong lan for 'reqverify' - USRLAN_181, wrong lan for 'verify' (USRLAN_182), changed to USRLAN_32
2717				/*	$text .= "<option value='ban'>".USRLAN_30."</option>
2718						<option value='reqverify'>Make not verified</option>
2719						<option value='verify'>".USRLAN_32."</option>
2720						<option value='test'>".USRLAN_118."</option>";
2721						*/
2722
2723						$opts['ban']        = USRLAN_30;
2724						$opts['reqverify'] = "Make not verified";
2725						$opts['verify']     = USRLAN_32;
2726						$opts['test']       = USRLAN_118;
2727
2728
2729					break;
2730				default :
2731			}
2732			if (!$user_admin && !$row['user_ban'] && $row['user_ban'] != 2 && getperms('3'))
2733			{
2734		//		$text .= "<option value='admin'>".USRLAN_35."</option>\n";
2735				$opts['admin'] = USRLAN_35;
2736			}
2737			else
2738				if ($user_admin && $row['user_perms'] != "0" && getperms('3'))
2739				{
2740			//		$text .= "<option value='adminperms'>".USRLAN_221."</option>\n";
2741			//		$text .= "<option value='unadmin'>".USRLAN_34."</option>\n";
2742
2743					$opts['adminperms'] = USRLAN_221;
2744					$opts['unadmin']     = USRLAN_34;
2745				}
2746		}
2747		elseif(USERID ===  $user_id ||  $user_id > USERID)
2748		{
2749			$opts['usersettings'] = LAN_EDIT;
2750		}
2751
2752		if ($row['user_perms'] == "0" && !getperms("0"))
2753		{
2754		//	$text .= "";
2755		}
2756		elseif ($user_id != USERID || getperms("0"))
2757		{
2758		//	$text .= "<option value='userclass'>".USRLAN_36."</option>\n"; // DEPRECATED. inline & batch should be enough.
2759		}
2760		if ($row['user_perms'] != "0")
2761		{
2762		//	$text .= "<option value='deluser'>".LAN_DELETE."</option>\n";
2763			$opts['deldiv'] = 'divider';
2764			$opts['deluser'] = LAN_DELETE;
2765		}
2766
2767	//	$foot = "</select>";
2768	//	$foot = "</div>";
2769
2770		$btn =  '<div class="btn-group pull-right">
2771
2772		<button aria-expanded="false" class="btn btn-default btn-secondary btn-user-action dropdown-toggle" data-toggle="dropdown">
2773		<span class="user-action-indicators" id="user-action-indicator-'.$user_id.'">'.e107::getParser()->toGlyph('fa-cog').'</span>
2774		<span class="caret"></span>
2775		</button>
2776		<ul class="dropdown-menu">
2777
2778		<!-- dropdown menu links -->
2779		';
2780		//<li class="dropdown-header text-right"><strong>'.$row['user_name'].'</strong></li>
2781		foreach($opts as $k=>$v)
2782		{
2783			if($v == 'divider')
2784			{
2785				$btn .= '<li class="divider" ></li>';
2786			}
2787			else
2788			{
2789				$btn .= '<li class="user-action-'.$k.'"><a class="user-action text-right"  data-action-user="'.$user_id.'" data-action-type="'.$k.'" >'.$v.'</a></li>';
2790			}
2791		}
2792
2793
2794
2795		$btn .= '
2796		</ul></div>';
2797
2798		if(!empty($opts))
2799		{
2800			return $head.$btn;
2801		}
2802		else
2803		{
2804			return '';
2805		}
2806
2807		// return ($text) ? $head.$text.$foot . $btn : "";
2808	}
2809
2810
2811	function RankImageDropdown(&$imgList, $field, $curVal = '')
2812	{
2813		$ret = "
2814		<select class='tbox' name='{$field}'>
2815		<option value=''>".USRLAN_216."</option>
2816		";
2817		foreach ($imgList as $img)
2818		{
2819			$sel = ($img == $curVal ? "selected='selected'" : '');
2820			$ret .= "\n<option {$sel}>{$img}</option>";
2821		}
2822		$ret .= '</select>';
2823		return $ret;
2824	}
2825
2826
2827}
2828
2829
2830	class users_ranks_ui extends e_admin_ui
2831	{
2832		protected $pluginTitle		= ADLAN_36;
2833		protected $pluginName		= 'user_ranks';
2834		protected $table			= 'generic';
2835		protected $pid				= 'gen_id';
2836		protected $perPage 			= 15;
2837		protected $listQry			= "SELECT * FROM `#generic` WHERE gen_type='user_rank_data' ";
2838		protected $listOrder     = " CASE gen_datestamp WHEN 1 THEN 1 WHEN 2 THEN 2 WHEN 3 THEN 3  WHEN 0 THEN 4 END, gen_intdata ";
2839
2840		protected $fields 		= array (
2841		    'checkboxes'        =>   array ( 'title' => '', 'type' => null, 'data' => null, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',  ),
2842		    'gen_id' 			=> array ( 'title' => LAN_ID,	 'nolist'=>true,	'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',  ),
2843		    'gen_type' 			=> array ( 'title' => LAN_BAN, 	'type' => 'hidden', 'data' => 'str', 'width' => 'auto', 'batch' => true, 'filter' => true, 'inline' => true, 'help' => '', 'readParms' => '', 'writeParms' => 'value=user_rank_data', 'class' => 'left', 'thclass' => 'left',  ),
2844		    'gen_ip' 			=> array ( 'title' => USRLAN_208, 'type' => 'text', 'data' => 'str', 'inline'=>true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',  ),
2845		    'gen_intdata' 		=> array ( 'title' => USRLAN_209, 'type' => 'text', 'batch'=>false, 'data' => 'int', 'inline'=>true, 'width' => 'auto', 'help' => '', 'readParms' => 'default=-', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center',  ),
2846
2847		    'gen_datestamp' 	=> array ( 'title' => 'Special', 'type' => 'hidden', 'nolist'=>true, 'data' => 'int', 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',  ),
2848		    'gen_user_id' 		=> array ( 'title' => USRLAN_210, 'type' => 'boolean', 'batch'=>true, 'data' => 'int', 'inline'=>true, 'width' => '15%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center',  ),
2849		    //'gen_chardata' 		=> array ( 'title' => LAN_ICON, 'type' => 'dropdown', 'data' => 'str', 'inline'=>true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => array(), 'class' => 'left', 'thclass' => 'left',  ),
2850		    'gen_chardata' 		=> array ( 'title' => LAN_ICON, 'type' => 'method', 'data' => 'str', 'inline'=>true, 'width' => 'auto', 'help' => '', 'readParms' => array(), 'writeParms' => array(), 'class' => 'left', 'thclass' => 'left',  ),
2851
2852
2853		    'options'			=> array ( 'title' => LAN_OPTIONS, 'type' =>'method', 'data' => null, 'width' => '10%', 'thclass' => 'center last', 'class' => 'right last', 'forced' => '1', 'readParms'=>'edit=0'  ),
2854		);
2855
2856		protected $fieldpref = array('gen_datestamp', 'gen_type', 'gen_ip', 'gen_intdata', 'gen_user_id', 'gen_chardata');
2857
2858
2859		// optional
2860		public function init()
2861		{
2862			$tmp = e107::getFile()->get_files(e_IMAGE.'ranks', '.*?\.(png|gif|jpg)');
2863
2864			$mode = $this->getMode();
2865			$action = $this->getAction();
2866
2867			$existing = e107::getDb()->gen("SELECT gen_id FROM #generic WHERE gen_type='user_rank_data' LIMIT 1 ");
2868
2869			if($mode == 'ranks' && ($action == 'list') && !$existing)
2870			{
2871				$this->createDefaultRecords();
2872			}
2873
2874			//	$this->addTitle(LAN_USER_RANKS);
2875
2876			foreach($tmp as $k => $v)
2877			{
2878				$id = $v['fname'];
2879				$this->fields['gen_chardata']['writeParms']['optArray'][$id] = $v['fname'];
2880			}
2881
2882			unset($tmp);
2883		//	natsort($imageList);
2884		}
2885
2886		public function afterDelete($data, $id, $deleted_check)
2887		{
2888			e107::getCache()->clear_sys('nomd5_user_ranks');
2889		}
2890
2891		public function afterUpdate($new_data, $old_data, $id)
2892		{
2893			e107::getCache()->clear_sys('nomd5_user_ranks');
2894		}
2895
2896		private function createDefaultRecords()
2897		{
2898
2899			$tmp = array();
2900			$tmp['_FIELD_TYPES']['gen_datestamp'] = 'int';
2901			$tmp['_FIELD_TYPES']['gen_ip'] = 'todb';
2902			$tmp['_FIELD_TYPES']['gen_user_id'] = 'int';
2903			$tmp['_FIELD_TYPES']['gen_chardata'] = 'todb';
2904			$tmp['_FIELD_TYPES']['gen_intdata'] = 'int';
2905
2906
2907			//Add main site admin info
2908			$tmp['data']['gen_datestamp']   = 1;
2909			$tmp['data']['gen_type']        = 'user_rank_data';
2910			$tmp['data']['gen_ip']          = LAN_MAINADMIN;
2911			$tmp['data']['gen_user_id']     = 1;
2912			$tmp['data']['gen_chardata']    = 'English_main_admin.png';
2913			$tmp['data']['gen_intdata']     = 0;
2914			e107::getDb()->insert('generic',$tmp);
2915			unset ($tmp['data']);
2916
2917
2918			//Add site admin info
2919			$tmp['data']['gen_type']        = 'user_rank_data';
2920			$tmp['data']['gen_datestamp']   = 2;
2921			$tmp['data']['gen_ip']          = LAN_ADMIN;
2922			$tmp['data']['gen_user_id']     = 1;
2923			$tmp['data']['gen_chardata']    = 'English_admin.png';
2924			$tmp['data']['gen_intdata']     = 0;
2925
2926
2927			e107::getDb()->insert('generic', $tmp);
2928
2929			for($i=1; $i < 11; $i++)
2930			{
2931				unset ($tmp['data']);
2932				$tmp['data']['gen_type']        = 'user_rank_data';
2933				$tmp['data']['gen_datestamp']   = 0;
2934				$tmp['data']['gen_ip']          = "Level ".$i;
2935				$tmp['data']['gen_user_id']     = 0;
2936				$tmp['data']['gen_chardata']    = "lev".$i.".png";
2937				$tmp['data']['gen_intdata']     = ($i * 150);
2938
2939				e107::getDb()->insert('generic', $tmp);
2940			}
2941
2942
2943
2944		}
2945
2946	}
2947
2948
2949
2950	class users_ranks_ui_form extends e_admin_form_ui
2951	{
2952		// Override the default Options field.
2953		function options($parms, $value, $id, $attributes)
2954		{
2955
2956			if($attributes['mode'] == 'read')
2957			{
2958				parse_str(str_replace('&amp;', '&', e_QUERY), $query);
2959				$query['action'] = 'edit';
2960				$query['id'] = $id;
2961				$query = http_build_query($query, null, '&amp;');
2962
2963				$text = "<a href='".e_SELF."?{$query}' class='btn btn-default' title='".LAN_EDIT."' data-toggle='tooltip' data-placement='left'>
2964						".ADMIN_EDIT_ICON."</a>";
2965
2966				$special = $this->getController()->getListModel()->get('gen_datestamp');
2967
2968				if($special == 0)
2969				{
2970					$text .= $this->submit_image('menu_delete['.$id.']', $id, 'delete', LAN_DELETE.' [ ID: '.$id.' ]', array('class' => 'action delete btn btn-default'));
2971				}
2972
2973				return $text;
2974			}
2975		}
2976
2977		function gen_chardata($curVal, $mode, $parms=null)
2978		{
2979			switch($mode)
2980			{
2981				case 'read':
2982					return '<img src="'.e_IMAGE.'ranks/'.$curVal.'"/><br/>'.$curVal;
2983					break;
2984
2985				case 'write':
2986					$opts = $this->getController()->getFields()['gen_chardata']['writeParms']['optArray'];
2987					return e107::getForm()->select('gen_chardata', $opts, $curVal);
2988
2989				case 'filter':
2990				case 'batch':
2991					return null;
2992					break;
2993
2994			}
2995		}
2996
2997
2998	}
2999
3000
3001
3002new users_admin();
3003require_once ('auth.php');
3004
3005e107::getAdminUI()->runPage();
3006
3007require_once ("footer.php");
3008