Index: branches/5.0.x/admin/system_presets/simple/users_u.php =================================================================== --- branches/5.0.x/admin/system_presets/simple/users_u.php (revision 13120) +++ branches/5.0.x/admin/system_presets/simple/users_u.php (revision 13121) @@ -1,121 +1,121 @@ <?php defined('FULL_PATH') or die('restricted access!'); // section removal $remove_sections = Array ( // 'in-portal:user_list', // 'in-portal:admins', // 'in-portal:user_setting_folder', // 'in-portal:configure_users', 'in-portal:user_email', 'in-portal:user_custom' ); // sections shown with debug on $debug_only_sections = Array ( // 'in-portal:user_list', // 'in-portal:admins', 'in-portal:user_setting_folder', 'in-portal:configure_users', // 'in-portal:user_email', // 'in-portal:user_custom' ); // toolbar buttons $remove_buttons = Array ( // list of users; section: Users Management -> Users 'users_list' => Array (/*'new_item', 'edit', 'delete', 'approve', 'decline', 'e-mail',*/ 'export', /*'view', 'dbl-click'*/), // "General" tab during user adding/editing // 'users_edit' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), // "Images" tab during user adding/editing // 'user_edit_images' => Array ('select', 'cancel', 'prev', 'next', 'new_item', 'edit', 'delete', 'move_up', 'move_down', 'setprimary', 'view', 'dbl-click'), // "Groups" tab during user/admin adding/editing // 'user_edit_groups' => Array ('select', 'cancel', 'prev', 'next', 'selec_user', 'edit', 'delete', 'primary_group', 'view', 'dbl-click'), // "Items" tab during user/admin adding/editing // 'user_edit_items' => Array ('select', 'cancel', 'prev', 'next', 'edit', 'delete', 'view', 'dbl-click'), // "Custom" tab during user/admin adding/editing // 'user_edit_custom' => Array ('select', 'cancel', 'prev', 'next'), // list of administrators; section: Users Managements -> Administrators 'admin_list' => Array (/*'new_item', 'edit', 'delete', */'clone', 'refresh',/* 'view', 'dbl-click'*/), // "General" tab during admin adding/editing AND separate password change form for non-"root" users (in top frame) 'admins_edit' => Array (/*'select', 'cancel', */'reset_edit', /*'prev', 'next'*/), // 'regular_users_list' => Array (), // not used // separate password change form for "root" user (in top frame) // 'root_edit' => Array ('select', 'cancel'), // user/admin group membership editing (used on "Groups" tab during user/admin adding/editing) // 'user_edit_group' => Array ('select', 'cancel'), // user image adding/editing (used on "Images" tab during user adding/editing) // 'user_image_edit' => Array ('select', 'cancel'), // user selector // 'user_select' => Array ('select', 'cancel', 'view', 'dbl-click'), // user selector when adding/editing user group // 'group_user_select' => Array ('select', 'cancel', 'view', 'dbl-click'), ); // fields to hide $hidden_fields = Array ( /* 'PortalUserId', 'Login', 'Password', 'FirstName','LastName', 'Company', 'Email', 'CreatedOn', 'Phone', 'Fax', 'Street', 'Street2', 'City', 'State' , 'Zip', 'Country', 'ResourceId', 'Status', 'Modified', 'dob', 'tz', 'ip', 'IsBanned', 'PassResetTime', 'PwResetConfirm', 'PwRequestTime', 'MinPwResetDelay', */ ); // virtual fields to hide $virtual_hidden_fields = Array ( /*'ValidateLogin', 'SubscribeEmail', 'PrimaryGroup', 'RootPassword', 'FullName', 'UserGroup'*/ ); // fields to make required $required_fields = Array ( /*'PortalUserId',*/ 'Login', /*'Password', 'FirstName', 'LastName', 'Company', */'Email', /*'CreatedOn', 'Phone', 'Fax', 'Street', 'Street2', 'City', 'State' , 'Zip', 'Country', 'ResourceId', 'Status', 'Modified', 'dob', 'tz', 'ip', 'IsBanned', 'PassResetTime', 'PwResetConfirm', 'PwRequestTime', 'MinPwResetDelay'*/ ); // virtual fields to make required $virtual_required_fields = Array ( /*'ValidateLogin', 'SubscribeEmail', 'PrimaryGroup', 'RootPassword', 'FullName', 'UserGroup'*/ ); // tabs during editing $hide_edit_tabs = Array ( // tabs during user editing, when In-Portal module is enabled 'Default' => Array ('general', 'groups', 'images', 'items', 'custom'), // tabs during user editing, when In-Portal module isn't enabled 'RegularUsers' => Array ('general', 'groups'), // tabs during admin editing 'Admins' => Array ('general', 'groups'), ); // hide columns in grids $hide_columns = Array ( // currently not in user // 'Default' => Array ('Login', 'LastName', 'FirstName', 'Email', 'PrimaryGroup', 'CreatedOn'), // user selector // 'UserSelector' => Array ('Login', 'LastName', 'FirstName', 'Email', 'PrimaryGroup', 'CreatedOn'), // admins list; section: Users Management -> Administrators // 'Admins' => Array ('PortalUserId', 'Login', 'FirstName', 'LastName', 'Email'), // users list; section: Users Management -> Users -// 'RegularUsers' => Array ('PortalUserId', 'Login', 'FirstName', 'LastName', 'Email', 'Status'), + 'RegularUsers' => Array (/*'PortalUserId', 'Login', 'FirstName', 'LastName', 'Email',*/ 'PrimaryGroup', 'CreatedOn', /* 'Status'*/), ); Index: branches/5.0.x/core/units/users/users_event_handler.php =================================================================== --- branches/5.0.x/core/units/users/users_event_handler.php (revision 13120) +++ branches/5.0.x/core/units/users/users_event_handler.php (revision 13121) @@ -1,1928 +1,1928 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.org/license for copyright notices and details. */ defined('FULL_PATH') or die('restricted access!'); class UsersEventHandler extends kDBEventHandler { /** * Allows to override standart permission mapping * */ function mapPermissions() { parent::mapPermissions(); $permissions = Array ( // admin 'OnSetPersistantVariable' => Array('self' => 'view'), // because setting to logged in user only 'OnUpdateRootPassword' => Array('self' => true), 'OnUpdatePassword' => Array('self' => true), // front 'OnRefreshForm' => Array('self' => true), 'OnForgotPassword' => Array('self' => true), 'OnResetPassword' => Array('self' => true), 'OnResetPasswordConfirmed' => Array('self' => true), 'OnSubscribeQuery' => Array('self' => true), 'OnSubscribeUser' => Array('self' => true), 'OnRecommend' => Array('self' => true), 'OnItemBuild' => Array('self' => true), 'OnMassResetSettings' => Array('self' => 'edit'), 'OnMassCloneUsers' => Array('self' => 'add'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Shows only admins when required * * @param kEvent $event */ function SetCustomQuery(&$event) { $object =& $event->getObject(); /* @var $object kDBList */ if ($event->Special == 'admins') { $object->addFilter('primary_filter', 'ug.GroupId = 11'); } if ($event->Special == 'regular') { - $object->addFilter('primary_filter', 'ug.GroupId <> 11'); + $object->addFilter('primary_filter', 'ug.GroupId <> 11 OR ug.GroupId IS NULL '); } if (!$this->Application->isAdminUser) { $object->addFilter('status_filter', '%1$s.Status = '.STATUS_ACTIVE); } if ($event->Special == 'online') { $object->addFilter('online_users_filter', 's.PortalUserId IS NOT NULL'); } if ($event->Special == 'group') { $group_id = $this->Application->GetVar('g_id'); if ($group_id !== false) { // show only users, that user doesn't belong to current group $table_name = $this->Application->GetTempName(TABLE_PREFIX.'UserGroup', 'prefix:g'); $sql = 'SELECT PortalUserId FROM ' . $table_name . ' WHERE GroupId = ' . (int)$group_id; $user_ids = $this->Conn->GetCol($sql); // array_push($user_ids); // Guest & Everyone groups are set dynamically if ($user_ids) { $object->addFilter('already_member_filter', '%1$s.PortalUserId NOT IN ('.implode(',', $user_ids).')'); } } } } /** * Checks permissions of user * * @param kEvent $event */ function CheckPermission(&$event) { if ($event->Name == 'OnLogin' || $event->Name == 'OnLogout') { // permission is checked in OnLogin event directly return true; } if (!$this->Application->isAdminUser) { $user_id = $this->Application->RecallVar('user_id'); $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); if ($event->Name == 'OnCreate' && $user_id == -2) { // "Guest" can create new users return true; } if ($event->Name == 'OnUpdate' && $user_id > 0) { $user_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); foreach ($items_info as $id => $field_values) { if ($id != $user_id) { // registered users can update their record only return false; } $user_dummy->Load($id); $status_field = array_shift($this->Application->getUnitOption($event->Prefix, 'StatusField')); if ($user_dummy->GetDBField($status_field) != STATUS_ACTIVE) { // not active user is not allowed to update his record (he could not activate himself manually) return false; } if (isset($field_values[$status_field]) && $user_dummy->GetDBField($status_field) != $field_values[$status_field]) { // user can't change status by himself return false; } } return true; } if ($event->Name == 'OnUpdate' && $user_id <= 0) { // guests are not allowed to update their record, because they don't have it :) return false; } } return parent::CheckPermission($event); } /** * Handles session expiration (redirects to valid template) * * @param kEvent $event */ function OnSessionExpire(&$event) { $this->Application->resetCounters('UserSession'); // place 2 of 2 (also in kHTTPQuery::getRedirectParams) $admin_url_params = Array ( 'm_cat_id' => 0, // category means nothing on admin login screen 'm_wid' => '', // remove wid, otherwise parent window may add wid to its name breaking all the frameset (for <a> targets) 'pass' => 'm', // don't pass any other (except "m") prefixes to admin session expiration template 'expired' => 1, // expiration mark to show special error on login screen 'no_pass_through' => 1, // this way kApplication::HREF won't add them again ); if ($this->Application->isAdmin) { $this->Application->Redirect('index', $admin_url_params, '', 'index.php'); } if ($this->Application->GetVar('admin') == 1) { // Front-End showed in admin's right frame $session_admin =& $this->Application->recallObject('Session.admin'); /* @var $session_admin Session */ if (!$session_admin->LoggedIn()) { // front-end session created from admin session & both expired $this->Application->DeleteVar('admin'); $this->Application->Redirect('index', $admin_url_params, '', 'admin/index.php'); } } // Front-End session expiration $get = $this->Application->HttpQuery->getRedirectParams(); $t = $this->Application->GetVar('t'); $get['js_redirect'] = $this->Application->ConfigValue('UseJSRedirect'); $this->Application->Redirect($t ? $t : 'index', $get); } /** * Checks user data and logs it in if allowed * * OnLogin is called from u:autoLoginUser and password is supplied * OnLogin is called from u:OnAutoLoginUser supplying cookie with encoded username & password * * @param kEvent $event */ function OnLogin(&$event) { // persistent session data after login is not refreshed, because redirect will follow in any case $prefix_special = $this->Application->isAdmin ? 'u.current' : 'u'; // "u" used on front not to change theme $object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true)); $password = $this->Application->GetVar('password'); $invalid_pseudo = $this->Application->isAdmin ? 'la_invalid_password' : 'lu_invalid_password'; $remember_login_cookie = $this->Application->GetVar('remember_login'); if (!$password && !$remember_login_cookie) { $object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo); $event->status = erFAIL; return false; } $email_as_login = $this->Application->ConfigValue('Email_As_Login'); list ($login_field, $submit_field) = $email_as_login && !$this->Application->isAdmin ? Array('Email', 'email') : Array('Login', 'login'); $login_value = $this->Application->GetVar($submit_field); // process "Save Username" checkbox if ($this->Application->isAdmin) { $save_username = $this->Application->GetVar('cb_save_username') ? $login_value : ''; $this->Application->Session->SetCookie('save_username', $save_username, adodb_mktime() + 31104000); // 1 year expiration $this->Application->SetVar('save_username', $save_username); // cookie will be set on next refresh, but refresh won't occur if login error present, so duplicate cookie in HTTPQuery } $super_admin = ($login_value == 'super-root') && $this->verifySuperAdmin(); if ($this->Application->isAdmin && ($login_value == 'root') || ($super_admin && $login_value == 'super-root')) { // logging in "root" (admin only) $login_value = 'root'; $root_password = $this->Application->ConfigValue('RootPass'); $password_formatter =& $this->Application->recallObject('kPasswordFormatter'); $test = $password_formatter->EncryptPassword($password, 'b38'); if ($root_password != $test) { $object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo); $event->status = erFAIL; return false; } elseif ($this->checkLoginPermission($login_value)) { $user_id = -1; $object->Load($user_id); $object->SetDBField('Login', $login_value); $session =& $this->Application->recallObject('Session'); $session->SetField('PortalUserId', $user_id); // $session->SetField('GroupList', implode(',', $groups) ); $this->Application->SetVar('u.current_id', $user_id); $this->Application->StoreVar('user_id', $user_id); $this->Application->LoadPersistentVars(); if ($super_admin) { $this->Application->StoreVar('super_admin', 1); } $this->Application->HandleEvent($dummy, 'session-log:OnStartSession'); $this->processLoginRedirect($event, $password); $this->_processInterfaceLanguage($event); return true; } else { $object->SetError('ValidateLogin', 'invalid_license', 'la_invalid_license'); $event->status = erFAIL; return false; } } /*$sql = 'SELECT PortalUserId FROM '.$object->TableName.' WHERE (%s = %s) AND (Password = MD5(%s))'; $user_id = $this->Conn->GetOne( sprintf($sql, $login_field, $this->Conn->qstr($login_value), $this->Conn->qstr($password) ) );*/ if ($remember_login_cookie) { $user_info = explode('|', $remember_login_cookie); // 0 - username, 1 - md5(password) $sql = 'SELECT PortalUserId FROM '.$object->TableName.' WHERE (Email = %1$s OR Login = %1$s) AND (Password = %2$s)'; $user_id = $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr($user_info[0]), $this->Conn->qstr($user_info[1]) ) ); } else { $sql = 'SELECT PortalUserId FROM '.$object->TableName.' WHERE (Email = %1$s OR Login = %1$s) AND (Password = MD5(%2$s))'; $user_id = $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr($login_value), $this->Conn->qstr($password) ) ); } if ($user_id) { $object->Load($user_id); if (!$this->checkBanRules($object)) { $event->status = erFAIL; return false; } if ($object->GetDBField('Status') == STATUS_ACTIVE) { $groups = $object->getMembershipGroups(true); if(!$groups) $groups = Array(); array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') ); $this->Application->StoreVar( 'UserGroups', implode(',', $groups) ); if ($this->checkLoginPermission($login_value)) { $session =& $this->Application->recallObject('Session'); $session->SetField('PortalUserId', $user_id); $session->SetField('GroupList', implode(',', $groups) ); $this->Application->SetVar('u.current_id', $user_id); $this->Application->StoreVar('user_id', $user_id); $this->Application->LoadPersistentVars(); if (!$remember_login_cookie) { // don't change last login time when auto-login is used $this_login = (int)$this->Application->RecallPersistentVar('ThisLogin'); $this->Application->StorePersistentVar('LastLogin', $this_login); $this->Application->StorePersistentVar('ThisLogin', adodb_mktime()); } if ($this->Application->GetVar('cb_remember_login') == 1) { // remember username & password when "Remember Login" checkbox us checked (when user is using login form on Front-End) $remember_login_cookie = $login_value . '|' . md5($password); $this->Application->Session->SetCookie('remember_login', $remember_login_cookie, adodb_mktime() + 2592000); // 30 days } $this->Application->HandleEvent($dummy, 'session-log:OnStartSession'); } else { $object->Load(-2); $object->SetError('ValidateLogin', 'no_permission', 'lu_no_permissions'); $event->status = erFAIL; } if (!$remember_login_cookie) { $this->processLoginRedirect($event, $password); $this->_processInterfaceLanguage($event); } } else { $event->redirect = $this->Application->GetVar('pending_disabled_template'); } } else { $object->SetID(-2); $object->SetError('ValidateLogin', 'invalid_password', $invalid_pseudo); $event->status = erFAIL; } $event->SetRedirectParam('pass', 'all'); // $event->SetRedirectParam('pass_category', 1); // to test } /** * Sets correct interface language after sucessful login, based on user settings * * @param kEvent $event */ function _processInterfaceLanguage(&$event) { if (($event->status != erSUCCESS) || !$this->Application->isAdmin) { return ; } $is_root = $this->Application->RecallVar('user_id') == -1; $object =& $this->Application->recallObject('u.current'); /* @var $object kDBItem */ $user_language_id = $is_root ? $this->Application->RecallPersistentVar('AdminLanguage') : $object->GetDBField('AdminLanguage'); $sql = 'SELECT LanguageId, IF(LanguageId = ' . (int)$user_language_id . ', 2, AdminInterfaceLang) AS SortKey FROM ' . TABLE_PREFIX . 'Language WHERE Enabled = 1 HAVING SortKey <> 0 ORDER BY SortKey DESC'; $language_info = $this->Conn->GetRow($sql); $language_id = $language_info && $language_info['LanguageId'] ? $language_info['LanguageId'] : $user_language_id; if ($user_language_id != $language_id) { // first admin login OR language was delelted or disabled if ($is_root) { $this->Application->StorePersistentVar('AdminLanguage', $language_id); } else { $object->SetDBField('AdminLanguage', $language_id); $object->Update(); } } $event->SetRedirectParam('m_lang', $language_id); // data $this->Application->Session->SetField('Language', $language_id); // interface } /** * [HOOK] Auto-Logins Front-End user when "Remember Login" cookie is found * * @param kEvent $event */ function OnAutoLoginUser(&$event) { $remember_login_cookie = $this->Application->GetVar('remember_login'); if (!$remember_login_cookie || $this->Application->isAdmin || $this->Application->LoggedIn()) { return ; } $event->CallSubEvent('OnLogin'); } /** * Checks that user is allowed to use super admin mode * * @return bool */ function verifySuperAdmin() { $sa_mode = ipMatch(defined('SA_IP') ? SA_IP : ''); return $sa_mode || $this->Application->isDebugMode(); } /** * Enter description here... * * @param string $user_name * @return bool */ function checkLoginPermission($user_name) { $ret = true; if ($this->Application->isAdmin) { $modules_helper =& $this->Application->recallObject('ModulesHelper'); if ($user_name != 'root') { // root is virtual user, so allow him to login to admin in any case $ret = $this->Application->CheckPermission('ADMIN', 1); } } else { $ret = $this->Application->CheckPermission('LOGIN', 1); } return $ret; } /** * Process all required data and redirect logged-in user * * @param kEvent $event */ function processLoginRedirect(&$event, $password) { $prefix_special = $this->Application->isAdmin ? 'u.current' : 'u'; // "u" used on front not to change theme $object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true)); $next_template = $this->Application->GetVar('next_template'); if ($next_template == '_ses_redirect') { $location = $this->Application->BaseURL().$this->Application->RecallVar($next_template); if( $this->Application->isDebugMode() && constOn('DBG_REDIRECT') ) { $this->Application->Debugger->appendTrace(); echo "<b>Debug output above!!!</b> Proceed to redirect: <a href=\"$location\">$location</a><br>"; } else { header('Location: '.$location); } $session =& $this->Application->recallObject('Session'); $session->SaveData(); exit; } if ($next_template) { $event->redirect = $next_template; } if ($this->Application->ConfigValue('UseJSRedirect')) { $event->SetRedirectParam('js_redirect', 1); } $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $object->GetDBField('Login'), $password); $this->Application->resetCounters('UserSession'); } /** * Called when user logs in using old in-portal * * @param kEvent $event */ function OnInpLogin(&$event) { $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $event->getEventParam('user'), $event->getEventParam('pass') ); if ($event->redirect && is_string($event->redirect)) { // some real template specified instead of true $this->Application->Redirect($event->redirect, $event->redirect_params); } } /** * Called when user logs in using old in-portal * * @param kEvent $event */ function OnInpLogout(&$event) { $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); } function OnLogout(&$event) { $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); $this->Application->HandleEvent($dummy, 'session-log:OnEndSession'); $this->Application->SetVar('u.current_id', -2); $object =& $this->Application->recallObject('u.current', null, Array('skip_autoload' => true)); $object->Load(-2); $this->Application->DestroySession(); $session =& $this->Application->recallObject('Session'); /* @var $session Session */ $group_list = $this->Application->ConfigValue('User_GuestGroup') . ',' . $this->Application->ConfigValue('User_LoggedInGroup'); $session->SetField('PortalUserId', -2); $session->SetField('GroupList', $group_list); $this->Application->StoreVar('user_id', -2, true); $this->Application->StoreVar('UserGroups', $group_list, true); if ($this->Application->ConfigValue('UseJSRedirect')) { $event->SetRedirectParam('js_redirect', 1); } $this->Application->resetCounters('UserSession'); $this->Application->Session->SetCookie('remember_login', '', adodb_mktime() - 3600); $event->SetRedirectParam('pass', 'all'); } /** * Prefill states dropdown with correct values * * @param kEvent $event * @access public */ function OnPrepareStates(&$event) { $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); $cs_helper->PopulateStates($event, 'State', 'Country'); $object =& $event->getObject(); if( $object->isRequired('Country') && $cs_helper->CountryHasStates( $object->GetDBField('Country') ) ) $object->setRequired('State', true); $object->setLogin(); } /** * Redirects user after succesfull registration to confirmation template (on Front only) * * @param kEvent $event */ function OnAfterItemCreate(&$event) { $this->saveUserImages($event); if ($this->Application->GetVar('skip_set_primary')) return; $is_subscriber = $this->Application->GetVar('IsSubscriber'); if(!$is_subscriber) { $object =& $event->getObject(); $ug_table = TABLE_PREFIX.'UserGroup'; if ($object->mode == 't') { $ug_table = $this->Application->GetTempName($ug_table, 'prefix:'.$event->Prefix); } $sql = 'UPDATE '.$ug_table.' SET PrimaryGroup = 0 WHERE PortalUserId = '.$object->GetDBField('PortalUserId'); $this->Conn->Query($sql); // set primary group to user if ($this->Application->isAdminUser && $this->Application->GetVar('user_group')) { // while in admin you can set any group for new users $group_id = $this->Application->GetVar('user_group'); } else { $group_id = $object->GetDBField('UserGroup'); if ($group_id) { // check, that group is allowed for Front-End $sql = 'SELECT GroupId FROM ' . TABLE_PREFIX . 'PortalGroup WHERE GroupId = ' . (int)$group_id . ' AND FrontRegistration = 1'; $group_id = $this->Conn->GetOne($sql); } if (!$group_id) { // when group not selected -> use default group $group_id = $this->Application->ConfigValue('User_NewGroup'); } } $sql = 'REPLACE INTO '.$ug_table.'(PortalUserId,GroupId,PrimaryGroup) VALUES (%s,%s,1)'; $this->Conn->Query( sprintf($sql, $object->GetID(), $group_id) ); } } /** * Login user if possible, if not then redirect to corresponding template * * @param kEvent $event */ function autoLoginUser(&$event) { $object =& $event->getObject(); $this->Application->SetVar('u.current_id', $object->GetID() ); if($object->GetDBField('Status') == STATUS_ACTIVE && !$this->Application->ConfigValue('User_Password_Auto')) { $email_as_login = $this->Application->ConfigValue('Email_As_Login'); list($login_field, $submit_field) = $email_as_login ? Array('Email', 'email') : Array('Login', 'login'); $this->Application->SetVar($submit_field, $object->GetDBField($login_field) ); $this->Application->SetVar('password', $object->GetDBField('Password_plain') ); $event->CallSubEvent('OnLogin'); } } /** * When creating user & user with such email exists then force to use OnUpdate insted of ? * * @param kEvent $event */ function OnSubstituteSubscriber(&$event) { $ret = false; $object =& $event->getObject( Array('skip_autoload' => true) ); $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if($items_info) { list($id, $field_values) = each($items_info); $user_email = isset($field_values['Email']) ? $field_values['Email'] : false; if($user_email) { // check if is subscriber $verify_user =& $this->Application->recallObject('u.verify', null, Array('skip_autoload' => true) ); $verify_user->Load($user_email, 'Email'); if( $verify_user->isLoaded() && $verify_user->isSubscriberOnly() ) { $items_info = Array( $verify_user->GetDBField('PortalUserId') => $field_values ); $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); $ret = true; } } } if( isset($event->MasterEvent) ) { $event->MasterEvent->setEventParam('is_subscriber_only', $ret); } else { $event->setEventParam('is_subscriber_only', $ret); } } /** * Enter description here... * * @param kEvent $event * @return bool */ function isSubscriberOnly(&$event) { $event->CallSubEvent('OnSubstituteSubscriber'); $is_subscriber = false; if( $event->getEventParam('is_subscriber_only') ) { $is_subscriber = true; $object =& $event->getObject( Array('skip_autoload' => true) ); $this->OnUpdate($event); if($event->status == erSUCCESS) { $this->OnAfterItemCreate($event); $object->SendEmailEvents(); if (!$this->Application->isAdmin && ($event->status == erSUCCESS) && $event->redirect) { $this->autoLoginUser($event); } } } return $is_subscriber; } /** * Creates new user * * @param kEvent $event */ function OnCreate(&$event) { if (!$this->Application->isAdminUser) { $this->setUserStatus($event); } if (!$this->isSubscriberOnly($event)) { $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); $cs_helper->CheckStateField($event, 'State', 'Country'); $object =& $event->getObject( Array('skip_autoload' => true) ); /* @var $object kDBItem */ if ($this->Application->ConfigValue('User_Password_Auto')) { $pass = makepassword4(rand(5,8)); $object->SetField('Password', $pass); $object->SetField('VerifyPassword', $pass); $this->Application->SetVar('user_password',$pass); } parent::OnCreate($event); $this->Application->SetVar('u.current_id', $object->getID() ); // for affil:OnRegisterAffiliate after hook $this->setNextTemplate($event); if (!$this->Application->isAdmin && ($event->status == erSUCCESS) && $event->redirect) { $object->SendEmailEvents(); $this->autoLoginUser($event); } } } /** * Set's new user status based on config options * * @param kEvent $event */ function setUserStatus(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); $new_users_allowed = $this->Application->ConfigValue('User_Allow_New'); switch ($new_users_allowed) { case 1: // Immediate $object->SetDBField('Status', STATUS_ACTIVE); $next_template = $this->Application->GetVar('registration_confirm_template'); if ($next_template) { $event->redirect = $next_template; } break; case 3: // Upon Approval case 4: // Email Activation $next_template = $this->Application->GetVar('registration_confirm_pending_template'); if ($next_template) { $event->redirect = $next_template; } $object->SetDBField('Status', STATUS_PENDING); break; case 2: // Not Allowed $object->SetDBField('Status', STATUS_DISABLED); break; } } /** * Set's new unique resource id to user * * @param kEvent $event */ function OnBeforeItemCreate(&$event) { $this->_makePasswordRequired($event); $email_as_login = $this->Application->ConfigValue('Email_As_Login'); $object =& $event->getObject(); if (!$this->checkBanRules($object)) { $event->status = erFAIL; return false; } if ($email_as_login) { $object->Fields['Email']['error_msgs']['unique'] = $this->Application->Phrase('lu_user_and_email_already_exist'); } } /** * Set's new unique resource id to user * * @param kEvent $event */ function OnAfterItemValidate(&$event) { $object =& $event->getObject(); $resource_id = $object->GetDBField('ResourceId'); if (!$resource_id) { $object->SetDBField('ResourceId', $this->Application->NextResourceId() ); } } /** * Enter description here... * * @param kEvent $event */ function OnRecommend(&$event) { $friend_email = $this->Application->GetVar('friend_email'); $friend_name = $this->Application->GetVar('friend_email'); // used for error reporting only -> rewrite code + theme (by Alex) $object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too /* @var $object UsersItem */ if (preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $friend_email)) { /*$cutoff = adodb_mktime() + (int)$this->Application->ConfigValue('Suggest_MinInterval'); $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'SuggestMail WHERE email = ' . $this->Conn->qstr($friend_email) . ' AND sent < ' . $cutoff; if ($this->Conn->GetRow($sql) !== false) { $object->SetError('Email', 'send_error', 'lu_email_already_suggested'); $event->status = erFAIL; return ; }*/ $send_params = Array (); $send_params['to_email'] = $friend_email; $send_params['to_name'] = $friend_name; $user_id = $this->Application->RecallVar('user_id'); $email_event =& $this->Application->EmailEventUser('USER.SUGGEST', $user_id, $send_params); $email_event =& $this->Application->EmailEventAdmin('USER.SUGGEST'); if ($email_event->status == erSUCCESS){ /*$fields_hash = Array ( 'email' => $friend_email, 'sent' => adodb_mktime(), ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'SuggestMail');*/ $event->redirect_params = array('opener' => 's', 'pass' => 'all'); $event->redirect = $this->Application->GetVar('template_success'); } else { // $event->redirect_params = array('opener' => 's', 'pass' => 'all'); // $event->redirect = $this->Application->GetVar('template_fail'); $object->SetError('Email', 'send_error', 'lu_email_send_error'); $event->status = erFAIL; } } else { $object->SetError('Email', 'invalid_email', 'lu_InvalidEmail'); $event->status = erFAIL; } } /** * Saves address changes and mades no redirect * * @param kEvent $event */ function OnUpdateAddress(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if($items_info) { list($id,$field_values) = each($items_info); if($id > 0) $object->Load($id); $object->SetFieldsFromHash($field_values); $object->setID($id); $object->Validate(); } $event->redirect = false; } /** * Validate subscriber's email & store it to session -> redirect to confirmation template * * @param kEvent $event */ function OnSubscribeQuery(&$event) { $user_email = $this->Application->GetVar('subscriber_email'); if (preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $user_email)) { $object =& $this->Application->recallObject($this->Prefix.'.subscriber', null, Array('skip_autoload' => true)); /* @var $object UsersItem */ $this->Application->StoreVar('SubscriberEmail', $user_email); $object->Load($user_email, 'Email'); if ($object->isLoaded()) { $group_info = $this->GetGroupInfo($object->GetID()); $event->redirect = $this->Application->GetVar($group_info ? 'unsubscribe_template' : 'subscribe_template'); } else { $event->redirect = $this->Application->GetVar('subscribe_template'); $this->Application->StoreVar('SubscriberEmail', $user_email); } } else { // used for error reporting only -> rewrite code + theme (by Alex) $object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too /* @var $object UsersItem */ $object->SetError('SubscribeEmail', 'invalid_email', 'lu_InvalidEmail'); $event->status = erFAIL; } } /** * Subscribe/Unsubscribe user based on email stored in previous step * * @param kEvent $event */ function OnSubscribeUser(&$event) { $object = &$this->Application->recallObject($this->Prefix.'.subscriber', null, Array('skip_autoload' => true)); /* @var $object UsersItem */ $user_email = $this->Application->RecallVar('SubscriberEmail'); if (preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $user_email)) { $this->RemoveRequiredFields($object); $object->Load($user_email, 'Email'); if ($object->isLoaded()) { $group_info = $this->GetGroupInfo($object->GetID()); if ($group_info){ if ($event->getEventParam('no_unsubscribe')) return; if ($group_info['PrimaryGroup']){ // delete user $object->Delete(); } else { $this->RemoveSubscriberGroup($object->GetID()); } $event->redirect = $this->Application->GetVar('unsubscribe_ok_template'); } else { $this->AddSubscriberGroup($object->GetID(), 0); $event->redirect = $this->Application->GetVar('subscribe_ok_template'); } } else { $object->SetField('Email', $user_email); $object->SetField('Login', $user_email); $object->SetDBField('dob', 1); $object->SetDBField('dob_date', 1); $object->SetDBField('dob_time', 1); $object->SetDBField('Status', STATUS_ACTIVE); // make user subscriber Active by default $ip = getenv('HTTP_X_FORWARDED_FOR')?getenv('HTTP_X_FORWARDED_FOR'):getenv('REMOTE_ADDR'); $object->SetDBField('ip', $ip); $this->Application->SetVar('IsSubscriber', 1); if ($object->Create()) { $this->AddSubscriberGroup($object->GetID(), 1); $event->redirect = $this->Application->GetVar('subscribe_ok_template'); } $this->Application->SetVar('IsSubscriber', 0); } } } function AddSubscriberGroup($user_id, $is_primary) { $group_id = $this->Application->ConfigValue('User_SubscriberGroup'); $sql = 'INSERT INTO ' . TABLE_PREFIX . 'UserGroup (PortalUserId, GroupId, PrimaryGroup) VALUES (%s, %s, ' . $is_primary . ')'; $this->Conn->Query( sprintf($sql, $user_id, $group_id) ); $this->Application->EmailEventAdmin('USER.SUBSCRIBE'); $this->Application->EmailEventUser('USER.SUBSCRIBE', $user_id); } function RemoveSubscriberGroup($user_id) { $group_id = $this->Application->ConfigValue('User_SubscriberGroup'); $sql = 'DELETE FROM ' . TABLE_PREFIX . 'UserGroup WHERE PortalUserId = ' . $user_id . ' AND GroupId = ' . $this->Application->ConfigValue('User_SubscriberGroup'); $this->Conn->Query($sql); $this->Application->EmailEventAdmin('USER.UNSUBSCRIBE'); $this->Application->EmailEventUser('USER.UNSUBSCRIBE', $user_id); } /** * Allows to detect user subscription status (subscribed or not) * * @param int $user_id * @return bool */ function GetGroupInfo($user_id) { $sql = 'SELECT * FROM ' . TABLE_PREFIX . 'UserGroup WHERE (PortalUserId = ' . $user_id . ') AND (GroupId = ' . $this->Application->ConfigValue('User_SubscriberGroup') . ')'; return $this->Conn->GetRow($sql); } function OnForgotPassword(&$event) { $user_object =& $this->Application->recallObject('u.forgot', null, Array('skip_autoload' => true)); /* @var $user_object UsersItem */ // used for error reporting only -> rewrite code + theme (by Alex) $user_current_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too /* @var $user_current_object UsersItem */ $username = $this->Application->GetVar('username'); $email = $this->Application->GetVar('email'); $found = false; $allow_reset = true; if (strlen($username)) { $user_object->Load($username, 'Login'); if ($user_object->isLoaded()) { $found = ($user_object->GetDBField("Login")==$username && $user_object->GetDBField("Status")==1) && strlen($user_object->GetDBField("Password")); } } else if(strlen($email)) { $user_object->Load($email, 'Email'); if ($user_object->isLoaded()) { $found = ($user_object->GetDBField("Email")==$email && $user_object->GetDBField("Status")==1) && strlen($user_object->GetDBField("Password")); } } if ($user_object->isLoaded()) { $PwResetConfirm = $user_object->GetDBField('PwResetConfirm'); $PwRequestTime = $user_object->GetDBField('PwRequestTime'); $PassResetTime = $user_object->GetDBField('PassResetTime'); //$MinPwResetDelay = $user_object->GetDBField('MinPwResetDelay'); $MinPwResetDelay = $this->Application->ConfigValue('Users_AllowReset'); $allow_reset = (strlen($PwResetConfirm) ? adodb_mktime() > $PwRequestTime + $MinPwResetDelay : adodb_mktime() > $PassResetTime + $MinPwResetDelay); } if ($found && $allow_reset) { $this->Application->StoreVar('tmp_user_id', $user_object->GetDBField("PortalUserId")); $this->Application->StoreVar('tmp_email', $user_object->GetDBField("Email")); $confirm_template = $this->Application->GetVar('reset_confirm_template'); if (!$confirm_template) { $this->Application->SetVar('reset_confirm_template', 'platform/login/forgotpass_reset'); } $this->Application->EmailEventUser('USER.PSWDC', $user_object->GetDBField('PortalUserId')); $event->redirect = $this->Application->GetVar('template_success'); } else { if (!strlen($username) && !strlen($email)) { $user_current_object->SetError('Login', 'forgotpw_nodata', 'lu_ferror_forgotpw_nodata'); $user_current_object->SetError('Email', 'forgotpw_nodata', 'lu_ferror_forgotpw_nodata'); } else { if ($allow_reset) { if (strlen($username)) { $user_current_object->SetError('Login', 'unknown_username', 'lu_ferror_unknown_username'); } if (strlen($email)) { $user_current_object->SetError('Email', 'unknown_email', 'lu_ferror_unknown_email'); } } else { if (strlen($username)) { $user_current_object->SetError('Login', 'reset_denied', 'lu_ferror_reset_denied'); } if (strlen($email)) { $user_current_object->SetError('Email', 'reset_denied', 'lu_ferror_reset_denied'); } } } if($user_current_object->FieldErrors){ $event->redirect = false; } } } /** * Enter description here... * * @param kEvent $event */ function OnResetPassword(&$event) { $user_object =& $this->Application->recallObject('u.forgot'); if($user_object->Load($this->Application->RecallVar('tmp_user_id'))){ $this->Application->EmailEventUser('USER.PSWDC', $user_object->GetDBField("PortalUserId")); $event->redirect = $this->Application->GetVar('template_success'); $m_cat_id = $this->Application->findModule('Name', 'In-Commerce', 'RootCat'); $this->Application->SetVar('m_cat_id', $m_cat_id); $event->SetRedirectParam('pass', 'm'); } } function OnResetPasswordConfirmed(&$event) { // used for error reporting only -> rewrite code + theme (by Alex) $user_current_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true));// TODO: change theme too /* @var $user_current_object UsersItem */ $passed_key = trim($this->Application->GetVar('user_key')); if (!$passed_key) { $event->redirect_params = Array('opener' => 's', 'pass' => 'all'); $event->redirect = false; $user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', 'lu_code_is_not_valid'); } $user_object =& $this->Application->recallObject('u.forgot', null, Array('skip_autoload' => true)); /* @var $user_object UsersItem */ $user_object->Load($passed_key, 'PwResetConfirm'); if ($user_object->isLoaded()) { $exp_time = $user_object->GetDBField('PwRequestTime') + 3600; $user_object->SetDBField('PwResetConfirm', ''); $user_object->SetDBField('PwRequestTime', 0); if ($exp_time > adodb_mktime()) { $newpw = makepassword4(); $this->Application->StoreVar('password', $newpw); $user_object->SetField('Password', $newpw); $user_object->SetField('VerifyPassword', $newpw); $user_object->SetDBField('PassResetTime', adodb_mktime()); $user_object->SetDBField('PwResetConfirm', ''); $user_object->SetDBField('PwRequestTime', 0); $user_object->Update(); $this->Application->SetVar('ForgottenPassword', $newpw); $email_event_user =& $this->Application->EmailEventUser('USER.PSWD', $user_object->GetDBField('PortalUserId')); $email_event_admin =& $this->Application->EmailEventAdmin('USER.PSWD'); $this->Application->DeleteVar('ForgottenPassword'); if ($email_event_user->status == erSUCCESS) { $event->redirect_params = array('opener' => 's', 'pass' => 'all'); $event->redirect = $this->Application->GetVar('template_success'); } } else { $user_current_object->SetError('PwResetConfirm', 'code_expired', 'lu_code_expired'); $event->redirect = false; } } else { $user_current_object->SetError('PwResetConfirm', 'code_is_not_valid', 'lu_code_is_not_valid'); $event->redirect = false; } } function OnUpdate(&$event) { $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); $cs_helper->CheckStateField($event, 'State', 'Country'); parent::OnUpdate($event); $this->setNextTemplate($event); } /** * Enter description here... * * @param kEvent $event */ function setNextTemplate(&$event) { if ($this->Application->isAdmin) { return ; } $event->redirect_params['opener'] = 's'; $object =& $event->getObject(); if ($object->GetDBField('Status') == STATUS_ACTIVE) { $next_template = $this->Application->GetVar('next_template'); if ($next_template) { $event->redirect = $next_template; } } } /** * Delete users from groups if their membership is expired * * @param kEvent $event */ function OnCheckExpiredMembership(&$event) { // send pre-expiration reminders: begin $pre_expiration = adodb_mktime() + $this->Application->ConfigValue('User_MembershipExpirationReminder') * 3600 * 24; $sql = 'SELECT PortalUserId, GroupId FROM '.TABLE_PREFIX.'UserGroup WHERE (MembershipExpires IS NOT NULL) AND (ExpirationReminderSent = 0) AND (MembershipExpires < '.$pre_expiration.')'; $skip_clause = $event->getEventParam('skip_clause'); if ($skip_clause) { $sql .= ' AND !('.implode(') AND !(', $skip_clause).')'; } $records = $this->Conn->Query($sql); if ($records) { $conditions = Array(); foreach ($records as $record) { $email_event_user =& $this->Application->EmailEventUser('USER.MEMBERSHIP.EXPIRATION.NOTICE', $record['PortalUserId']); $email_event_admin =& $this->Application->EmailEventAdmin('USER.MEMBERSHIP.EXPIRATION.NOTICE'); $conditions[] = '(PortalUserId = '.$record['PortalUserId'].' AND GroupId = '.$record['GroupId'].')'; } $sql = 'UPDATE '.TABLE_PREFIX.'UserGroup SET ExpirationReminderSent = 1 WHERE '.implode(' OR ', $conditions); $this->Conn->Query($sql); } // send pre-expiration reminders: end // remove users from groups with expired membership: begin $sql = 'SELECT PortalUserId FROM '.TABLE_PREFIX.'UserGroup WHERE (MembershipExpires IS NOT NULL) AND (MembershipExpires < '.adodb_mktime().')'; $user_ids = $this->Conn->GetCol($sql); if ($user_ids) { foreach ($user_ids as $id) { $email_event_user =& $this->Application->EmailEventUser('USER.MEMBERSHIP.EXPIRED', $id); $email_event_admin =& $this->Application->EmailEventAdmin('USER.MEMBERSHIP.EXPIRED'); } } $sql = 'DELETE FROM '.TABLE_PREFIX.'UserGroup WHERE (MembershipExpires IS NOT NULL) AND (MembershipExpires < '.adodb_mktime().')'; $this->Conn->Query($sql); // remove users from groups with expired membership: end } /** * Enter description here... * * @param kEvent $event */ function OnRefreshForm(&$event) { $event->redirect = false; $item_info = $this->Application->GetVar($event->Prefix_Special); list($id, $fields) = each($item_info); $object =& $event->getObject( Array('skip_autoload' => true) ); $object->setID($id); $object->IgnoreValidation = true; $object->SetFieldsFromHash($fields); } /** * Sets persistant variable * * @param kEvent $event */ function OnSetPersistantVariable(&$event) { $field = $this->Application->GetVar('field'); $value = $this->Application->GetVar('value'); $this->Application->StorePersistentVar($field, $value); $force_tab = $this->Application->GetVar('SetTab'); if ($force_tab) { $this->Application->StoreVar('force_tab', $force_tab); } } /** * Overwritten to return user from order by special .ord * * @param kEvent $event */ function getPassedID(&$event) { switch ($event->Special) { case 'ord': $order =& $this->Application->recallObject('ord'); /* @var $order OrdersItem */ $id = $order->GetDBField('PortalUserId'); break; case 'profile': $id = $this->Application->GetVar('user_id'); if (!$id) { // if none user_id given use current user id $id = $this->Application->RecallVar('user_id'); } break; default: $id = parent::getPassedID($event); break; } return $id; } /** * Allows to change root password * * @param kEvent $event */ function OnUpdateRootPassword(&$event) { return $this->OnUpdatePassword($event); } /** * Allows to change root password * * @param kEvent $event */ function OnUpdatePassword(&$event) { $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); if (!$items_info) return ; list ($id, $field_values) = each($items_info); $user_id = $this->Application->RecallVar('user_id'); if ($id == $user_id && ($user_id > 0 || $user_id == -1)) { $user_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); /* @var $user_dummy kDBItem */ $user_dummy->Load($id); $status_field = array_shift($this->Application->getUnitOption($event->Prefix, 'StatusField')); if ($user_dummy->GetDBField($status_field) != STATUS_ACTIVE) { // not active user is not allowed to update his record (he could not activate himself manually) return false; } } if ($user_id == -1) { $object =& $event->getObject( Array('skip_autoload' => true) ); /* @var $object UsersItem */ // put salt to user's config $field_options = $object->GetFieldOptions('RootPassword'); $field_options['salt'] = 'b38'; $object->SetFieldOptions('RootPassword', $field_options); $verify_options = $object->GetFieldOptions('VerifyRootPassword'); $verify_options['salt'] = 'b38'; $object->SetFieldOptions('VerifyRootPassword', $verify_options); // this is internal hack to allow root/root passwords for dev if ($this->Application->isDebugMode() && $field_values['RootPassword'] == 'root') { $this->Application->ConfigHash['Min_Password'] = 4; } $this->RemoveRequiredFields($object); $object->SetDBField('RootPassword', $this->Application->ConfigValue('RootPass')); $object->SetFieldsFromHash($field_values); $object->setID(-1); $status = $object->Validate(); if ($status) { // validation on, password match too $fields_hash = Array ( 'VariableValue' => $object->GetDBField('RootPassword') ); $conf_table = $this->Application->getUnitOption('conf', 'TableName'); $this->Conn->doUpdate($fields_hash, $conf_table, 'VariableName = "RootPass"'); $event->SetRedirectParam('opener', 'u'); } else { $event->status = erFAIL; $event->redirect = false; return; } } else { $object =& $event->getObject(); $object->SetFieldsFromHash($field_values); if (!$object->Update()) { $event->status = erFAIL; $event->redirect = false; } } $event->SetRedirectParam('opener', 'u'); $event->redirect == true; } /** * Apply custom processing to item * * @param kEvent $event */ function customProcessing(&$event, $type) { if ($event->Name == 'OnCreate' && $type == 'before') { $object =& $event->getObject(); /* @var $object kDBItem */ // if auto password has not been set already - store real one - to be used in email events if (!$this->Application->GetVar('user_password')) { $this->Application->SetVar('user_password', $object->GetDirtyField('Password')); $object->SetDBField('Password_plain', $object->GetDirtyField('Password')); } // validate here, because subscribing procedure should not validate captcha code if ($this->Application->ConfigValue('RegistrationCaptcha')) { $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); /* @var $captcha_helper kCaptchaHelper */ $captcha_helper->validateCode($event, false); } } } function OnMassResetSettings(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { $event->status = erFAIL; return; } $ids = $this->StoreSelectedIDs($event); $default_user_id = $this->Application->ConfigValue('DefaultSettingsUserId'); if (in_array($default_user_id, $ids)) { array_splice($ids, array_search($default_user_id, $ids), 1); } if ($ids) { $q = 'DELETE FROM '.TABLE_PREFIX.'PersistantSessionData WHERE PortalUserId IN ('.join(',', $ids).') AND (VariableName LIKE "%_columns_%" OR VariableName LIKE "%_filter%" OR VariableName LIKE "%_PerPage%")'; $this->Conn->Query($q); } $this->clearSelectedIDs($event); } /** * Checks, that currently loaded item is allowed for viewing (non permission-based) * * @param kEvent $event * @return bool */ function checkItemStatus(&$event) { $object =& $event->getObject(); if (!$object->isLoaded()) { return true; } $virtual_users = Array (-1, -2); // root, Guest return ($object->GetDBField('Status') == STATUS_ACTIVE) || in_array($object->GetID(), $virtual_users); } /** * Sends approved/declined email event on user status change * * @param kEvent $event */ function OnAfterItemUpdate(&$event) { $this->saveUserImages($event); $object =& $event->getObject(); /* @var $object UsersItem */ if (!$this->Application->isAdmin || $object->IsTempTable()) { return ; } $this->sendStatusChangeEvent($object->GetID(), $object->GetOriginalField('Status'), $object->GetDBField('Status')); } /** * Stores user's original Status before overwriting with data from temp table * * @param kEvent $event */ function OnBeforeDeleteFromLive(&$event) { $user_status = $this->Application->GetVar('user_status'); if (!$user_status) { $user_status = Array (); } $user_id = $event->getEventParam('id'); if ($user_id > 0) { $user_status[$user_id] = $this->getUserStatus($user_id); $this->Application->SetVar('user_status', $user_status); } } /** * Sends approved/declined email event on user status change (in temp tables during editing) * * @param kEvent $event */ function OnAfterCopyToLive(&$event) { $temp_id = $event->getEventParam('temp_id'); if ($temp_id == 0) { // this is new user create, don't send email events return ; } $new_status = $this->getUserStatus($temp_id); $user_status = $this->Application->GetVar('user_status'); $this->sendStatusChangeEvent($temp_id, $user_status[$temp_id], $new_status); } /** * Returns user status (active, pending, disabled) based on ID and temp mode setting * * @param int $user_id * @return int */ function getUserStatus($user_id) { $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName'); $sql = 'SELECT Status FROM '.$table_name.' WHERE '.$id_field.' = '.$user_id; return $this->Conn->GetOne($sql); } /** * Sends approved/declined email event on user status change * * @param int $user_id * @param int $prev_status * @param int $new_status */ function sendStatusChangeEvent($user_id, $prev_status, $new_status) { $status_events = Array ( STATUS_ACTIVE => 'USER.APPROVE', STATUS_DISABLED => 'USER.DENY', ); $email_event = isset($status_events[$new_status]) ? $status_events[$new_status] : false; if (($prev_status != $new_status) && $email_event) { $this->Application->EmailEventUser($email_event, $user_id); $this->Application->EmailEventAdmin($email_event); } } /** * OnAfterConfigRead for users * * @param kEvent $event */ function OnAfterConfigRead(&$event) { parent::OnAfterConfigRead($event); // 1. arrange user registration countries $first_country = $this->Application->ConfigValue('User_Default_Registration_Country'); if ($first_country) { // update user country dropdown sql $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); $fields['Country']['options_sql'] = preg_replace('/ORDER BY (.*)/', 'ORDER BY IF (DestId = '.$first_country.', 1, 0) DESC, \\1', $fields['Country']['options_sql']); $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); } // 2. set default user registration group $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); $virtual_fields['UserGroup']['default'] = $this->Application->ConfigValue('User_NewGroup'); $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields); // 3. allow avatar upload on Front-End $file_helper =& $this->Application->recallObject('FileHelper'); /* @var $file_helper FileHelper */ $file_helper->createItemFiles($event->Prefix, true); // create image fields if ($this->Application->isAdminUser) { // 4. when in administrative console, then create all users with Active status $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); // $fields['Password']['required'] = 1; // set password required (will broke approve/decline buttons) $fields['Status']['default'] = STATUS_ACTIVE; $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); // 5. remove groups tab on editing forms when AdvancedUserManagement config variable not set if (!$this->Application->ConfigValue('AdvancedUserManagement')) { $edit_tab_presets = $this->Application->getUnitOption($event->Prefix, 'EditTabPresets'); foreach ($edit_tab_presets as $preset_name => $preset_tabs) { if (array_key_exists('groups', $preset_tabs)) { unset($edit_tab_presets[$preset_name]['groups']); if (count($edit_tab_presets[$preset_name]) == 1) { // only 1 tab left -> remove it too $edit_tab_presets[$preset_name] = Array (); } } } $this->Application->setUnitOption($event->Prefix, 'EditTabPresets', $edit_tab_presets); } } } /** * OnMassCloneUsers * * @param kEvent $event */ function OnMassCloneUsers(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { $event->status = erFAIL; return; } $event->status=erSUCCESS; $ids = $this->StoreSelectedIDs($event); $this->Application->SetVar('skip_set_primary', 1); // otherwise it will default primary group, search for skip_set_primary above $temp_handler =& $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler'); /* @var $temp_handler kTempTablesHandler */ $cloned_users = $temp_handler->CloneItems($event->Prefix, '', $ids); $this->clearSelectedIDs($event); } /** * When cloning users, reset password (set random) * * @param kEvent $event */ function OnBeforeClone(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $object->setRequired('Password', 0); $object->setRequired('VerifyPassword', 0); $object->SetDBField('Password', rand(100000000, 999999999)); $object->SetDBField('CreatedOn', adodb_mktime()); $object->SetDBField('ResourceId', false); // this will reset it // change email cause it should be unique $object->NameCopy(array(), $object->GetID(), 'Email', 'copy%1$s.%2$s'); $object->UpdateFormattersSubFields(); } /** * Copy user groups after copying user * * @param kEvent $event */ function OnAfterClone(&$event) { $id = $event->getEventParam('id'); $original_id = $event->getEventParam('original_id'); $sql = 'INSERT '.TABLE_PREFIX."UserGroup SELECT $id, GroupId, MembershipExpires, PrimaryGroup, 0 FROM ".TABLE_PREFIX."UserGroup WHERE PortalUserId = $original_id"; $this->Conn->Query($sql); } /** * Saves selected ids to session * * @param kEvent $event */ function OnSaveSelected(&$event) { $this->StoreSelectedIDs($event); // remove current ID, otherwise group selector will use it in filters $this->Application->DeleteVar($event->getPrefixSpecial(true).'_id'); } /** * Adds selected link to listing * * @param kEvent $event */ function OnProcessSelected(&$event) { $event->SetRedirectParam('opener', 'u'); $user_ids = $this->getSelectedIDs($event, true); $this->clearSelectedIDs($event); $dst_field = $this->Application->RecallVar('dst_field'); if ($dst_field != 'PrimaryGroupId') { return ; } $group_ids = $this->Application->GetVar('g'); $primary_group_id = $group_ids ? array_shift( array_keys($group_ids) ) : false; if (!$user_ids || !$primary_group_id) { return ; } $table_name = $this->Application->getUnitOption('ug', 'TableName'); $sql = 'SELECT PortalUserId FROM '.$table_name.' WHERE (GroupId = '.$primary_group_id.') AND (PortalUserId IN ('.implode(',', $user_ids).'))'; $existing_members = $this->Conn->GetCol($sql); // 1. reset primary group mark $sql = 'UPDATE '.$table_name.' SET PrimaryGroup = 0 WHERE PortalUserId IN ('.implode(',', $user_ids).')'; $this->Conn->Query($sql); foreach ($user_ids as $user_id) { if (in_array($user_id, $existing_members)) { // 2. already member of that group -> just make primary $sql = 'UPDATE '.$table_name.' SET PrimaryGroup = 1 WHERE (PortalUserId = '.$user_id.') AND (GroupId = '.$primary_group_id.')'; $this->Conn->Query($sql); } else { // 3. not member of that group -> make member & make primary $fields_hash = Array ( 'GroupId' => $primary_group_id, 'PortalUserId' => $user_id, 'PrimaryGroup' => 1, ); $this->Conn->doInsert($fields_hash, $table_name); } } } /** * Loads user images * * @param kEvent $event */ function OnAfterItemLoad(&$event) { parent::OnAfterItemLoad($event); // linking existing images for item with virtual fields $image_helper =& $this->Application->recallObject('ImageHelper'); /* @var $image_helper ImageHelper */ $object =& $event->getObject(); /* @var $object kDBItem */ $image_helper->LoadItemImages($object); } /** * Save user images * * @param kEvent $event */ function saveUserImages(&$event) { if (!$this->Application->isAdmin) { $image_helper =& $this->Application->recallObject('ImageHelper'); /* @var $image_helper ImageHelper */ $object =& $event->getObject(); /* @var $object kDBItem */ // process image upload in virtual fields $image_helper->SaveItemImages($object); } } /** * Checks, if given user fields matches at least one of defined ban rules * * @param kDBItem $object * @return bool */ function checkBanRules(&$object) { $table = $this->Application->getUnitOption('ban-rule', 'TableName'); if (!$this->Conn->TableFound($table)) { // when ban table not found -> assume user is ok by default return true; } $sql = 'SELECT * FROM '.$table.' WHERE ItemType = 6 AND Status = ' . STATUS_ACTIVE . ' ORDER BY Priority DESC'; $rules = $this->Conn->Query($sql); $found = false; foreach ($rules as $rule) { $field = $rule['ItemField']; $this_value = strtolower( $object->GetDBField($field) ); $test_value = strtolower( $rule['ItemValue'] ); switch ($rule['ItemVerb']) { /*case 0: // any $found = true; break;*/ case 1: // is if ($this_value == $test_value) { $found = true; } break; /*case 2: // is not if ($this_value != $test_value) { $found = true; } break;*/ case 3: // contains if (strstr($this_value, $test_value)) { $found = true; } break; /*case 4: // not contains if (!strstr($this_value, $test_value)) { $found = true; } break; case 5: // Greater Than if ($test_value > $this_value) { $found = true; } break; case 6: // Less Than if ($test_value < $this_value) { $found = true; } break; case 7: // exists if (strlen($this_value) > 0) { $found = true; } break; case 8: // unique if ($this->ValueExists($field, $this_value)) { $found = true; } break;*/ } if ($found) { break; } } return !$found; } /** * Makes password required for new users * * @param kEvent $event */ function OnPreCreate(&$event) { parent::OnPreCreate($event); if ($event->status == erSUCCESS) { $this->_makePasswordRequired($event); } } /** * Makes password required for new users * * @param kEvent $event */ function OnNew(&$event) { parent::OnNew($event); if ($event->status == erSUCCESS) { $this->_makePasswordRequired($event); } } /** * Makes password required for new users * * @param kEvent $event */ function _makePasswordRequired(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $required_fields = Array ('Password', 'Password_plain', 'VerifyPassword', 'VerifyPassword_plain'); foreach ($required_fields as $required_field) { $object->setRequired($required_field); } } } Index: branches/5.0.x/core/units/users/users_config.php =================================================================== --- branches/5.0.x/core/units/users/users_config.php (revision 13120) +++ branches/5.0.x/core/units/users/users_config.php (revision 13121) @@ -1,484 +1,486 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.org/license for copyright notices and details. */ defined('FULL_PATH') or die('restricted access!'); $config = Array( 'Prefix' => 'u', 'ItemClass' => Array('class'=>'UsersItem','file'=>'users_item.php','build_event'=>'OnItemBuild'), 'ListClass' => Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'), 'EventHandlerClass' => Array('class'=>'UsersEventHandler','file'=>'users_event_handler.php','build_event'=>'OnBuild'), 'TagProcessorClass' => Array('class'=>'UsersTagProcessor','file'=>'users_tag_processor.php','build_event'=>'OnBuild'), 'RegisterClasses' => Array( Array('pseudo' => 'UsersSyncronizeManager', 'class' => 'UsersSyncronizeManager', 'file' => 'users_syncronize.php', 'build_event' => ''), ), 'AutoLoad' => true, 'ConfigPriority' => 0, 'Hooks' => Array ( Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => 'u', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterItemLoad', 'OnBeforeItemCreate', 'OnBeforeItemUpdate', 'OnUpdateAddress'), 'DoPrefix' => '', 'DoSpecial' => '*', 'DoEvent' => 'OnPrepareStates', ), Array ( 'Mode' => hBEFORE, 'Conditional' => false, 'HookToPrefix' => 'affil', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnCheckAffiliateAgreement'), 'DoPrefix' => '', 'DoSpecial' => '*', 'DoEvent' => 'OnSubstituteSubscriber', ), Array ( 'Mode' => hBEFORE, 'Conditional' => false, 'HookToPrefix' => '', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterConfigRead'), 'DoPrefix' => 'cdata', 'DoSpecial' => '*', 'DoEvent' => 'OnDefineCustomFields', ), Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => 'adm', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnStartup'), 'DoPrefix' => '', 'DoSpecial' => '*', 'DoEvent' => 'OnAutoLoginUser', ), // Captcha processing Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => '', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterConfigRead'), 'DoPrefix' => 'captcha', 'DoSpecial' => '*', 'DoEvent' => 'OnPrepareCaptcha', ), /*Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => '', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnBeforeItemCreate'), 'DoPrefix' => 'captcha', 'DoSpecial' => '*', 'DoEvent' => 'OnValidateCode', ),*/ ), 'QueryString' => Array( 1 => 'id', 2 => 'Page', 3 => 'event', 4 => 'mode', ), 'RegularEvents' => Array( 'membership_expiration' => Array('EventName' => 'OnCheckExpiredMembership', 'RunInterval' => 1800, 'Type' => reAFTER), ), 'IDField' => 'PortalUserId', 'StatusField' => Array('Status'), 'TitleField' => 'Login', 'ItemType' => 6, // used for custom fields only (on user's case) 'StatisticsInfo' => Array( 'pending' => Array( 'icon' => 'icon16_user_pending.gif', 'label' => 'la_Text_Users', 'js_url' => '#url#', 'url' => Array('t' => 'users/users_list', 'pass' => 'm,u', 'u_event' => 'OnSetFilterPattern', 'u_filters' => 'show_active=0,show_pending=1,show_disabled=0'), 'status' => STATUS_PENDING, ), ), 'TitlePresets' => Array ( 'default' => Array ( 'new_status_labels' => Array ('u' => '!la_title_Adding_User!'), 'edit_status_labels' => Array ('u' => '!la_title_Editing_User!'), ), 'users_list' => Array ( 'prefixes' => Array ('u_List'), 'format' => "!la_title_Users!", 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'approve', 'decline', 'e-mail', 'export', 'view', 'dbl-click'), ), 'users_edit' => Array ( 'prefixes' => Array ('u'), 'format' => "#u_status# #u_titlefield#", 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), ), 'user_edit_images' => Array ( 'prefixes' => Array ('u', 'u-img_List'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Images!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next', 'new_item', 'edit', 'delete', 'approve', 'decline', 'setprimary', 'move_up', 'move_down', 'view', 'dbl-click'), ), 'user_edit_groups' => Array ( 'prefixes' => Array ('u', 'u-ug_List'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Groups!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next', 'select_user', 'edit', 'delete', 'setprimary', 'view', 'dbl-click'), ), 'user_edit_items' => Array ( 'prefixes' => Array ('u'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Items!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next', 'edit', 'delete', 'view', 'dbl-click'), ), 'user_edit_custom' => Array ( 'prefixes' => Array ('u'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Custom!", 'toolbar_buttons' => Array ('select', 'cancel', 'prev', 'next'), ), 'admin_list' => Array ( 'prefixes' => Array ('u.admins_List'), 'format' => "!la_title_Administrators!", 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'clone', 'refresh', 'view', 'dbl-click'), ), 'admins_edit' => Array ( 'prefixes' => Array ('u'), 'format' => "#u_status# #u_titlefield#", 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), ), 'regular_users_list' => Array ( 'prefixes' => Array ('u.regular_List'), 'format' => "!la_title_Users!", 'toolbar_buttons' => Array (), ), 'root_edit' => Array ( 'prefixes' => Array ('u'), 'format' => "!la_title_Editing_User! 'root'", 'toolbar_buttons' => Array ('select', 'cancel'), ), 'user_edit_group' => Array ( 'prefixes' => Array ('u', 'u-ug'), 'edit_status_labels' => Array ('u-ug' => '!la_title_EditingMembership!'), 'format' => "#u_status# '#u_titlefield#' - #u-ug_status# '#u-ug_titlefield#'", 'toolbar_buttons' => Array ('select', 'cancel'), ), 'user_image_edit' => Array ( 'prefixes' => Array ('u', 'u-img'), 'new_status_labels' => Array ('u-img' => '!la_title_Adding_Image!'), 'edit_status_labels' => Array ('u-img' => '!la_title_Editing_Image!'), 'new_titlefield' => Array ('u-img' => '!la_title_New_Image!'), 'format' => "#u_status# '#u_titlefield#' - #u-img_status# '#u-img_titlefield#'", 'toolbar_buttons' => Array ('select', 'cancel'), ), 'user_select' => Array ( 'prefixes' => Array ('u_List'), 'format' => "!la_title_Users! - !la_title_SelectUser!", 'toolbar_buttons' => Array ('select', 'cancel', 'dbl-click'), ), 'group_user_select' => Array ( 'prefixes' => Array ('u.group_List'), 'format' => "!la_title_Users! - !la_title_SelectUser!", 'toolbar_buttons' => Array ('select', 'cancel', 'view', 'dbl-click'), ), 'tree_users' => Array('format' => '!la_section_overview!'), ), 'EditTabPresets' => Array ( 'Default' => Array ( 'general' => Array ('title' => 'la_tab_General', 't' => 'users/users_edit', 'priority' => 1), 'groups' => Array ('title' => 'la_tab_Groups', 't' => 'users/users_edit_groups', 'priority' => 2), 'images' => Array ('title' => 'la_tab_Images', 't' => 'users/user_edit_images', 'priority' => 3), 'items' => Array ('title' => 'la_tab_Items', 't' => 'users/user_edit_items', 'priority' => 4), 'custom' => Array ('title' => 'la_tab_Custom', 't' => 'users/users_edit_custom', 'priority' => 5), ), 'Admins' => Array ( 'general' => Array ('title' => 'la_tab_General', 't' => 'users/admins_edit', 'priority' => 1), 'groups' => Array ('title' => 'la_tab_Groups', 't' => 'users/admins_edit_groups', 'priority' => 2), ), ), 'PermSection' => Array('main' => 'in-portal:user_list', 'email' => 'in-portal:user_email', 'custom' => 'in-portal:user_custom'), 'Sections' => Array ( 'in-portal:user_list' => Array ( 'parent' => 'in-portal:users', 'icon' => 'users', 'label' => 'la_title_Users', // 'la_tab_User_List', 'url' => Array ('t' => 'users/users_list', 'pass' => 'm'), 'permissions' => Array ('view', 'add', 'edit', 'delete', 'advanced:ban', 'advanced:send_email', /*'advanced:add_favorite', 'advanced:remove_favorite',*/), 'priority' => 1, 'type' => stTREE, ), 'in-portal:admins' => Array ( 'parent' => 'in-portal:users', 'icon' => 'administrators', 'label' => 'la_title_Administrators', 'url' => Array ('t' => 'users/admins_list', 'pass' => 'm'), 'permissions' => Array ('view', 'add', 'edit', 'delete'), 'perm_prefix' => 'u', 'priority' => 2, 'type' => stTREE, ), // user settings 'in-portal:user_setting_folder' => Array ( 'parent' => 'in-portal:system', 'icon' => 'conf_users', 'label' => 'la_title_Users', 'use_parent_header' => 1, 'url' => Array ('t' => 'index', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view'), 'priority' => 2, 'container' => true, 'type' => stTREE, ), 'in-portal:configure_users' => Array ( 'parent' => 'in-portal:user_setting_folder', 'icon' => 'conf_users_general', 'label' => 'la_tab_ConfigSettings', 'url' => Array ('t' => 'config/config_universal', 'module' => 'In-Portal:Users', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view', 'edit'), 'priority' => 1, 'type' => stTREE, ), 'in-portal:user_email' => Array ( 'parent' => 'in-portal:user_setting_folder', 'icon' => 'conf_email', 'label' => 'la_tab_ConfigE-mail', 'url' => Array ('t' => 'config/config_email', 'module' => 'Core:Users', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view', 'edit'), 'priority' => 2, 'type' => stTREE, ), 'in-portal:user_custom' => Array ( 'parent' => 'in-portal:user_setting_folder', 'icon' => 'conf_customfields', 'label' => 'la_tab_ConfigCustom', 'url' => Array ('t' => 'custom_fields/custom_fields_list', 'cf_type' => 6, 'pass_section' => true, 'pass' => 'm,cf'), 'permissions' => Array ('view', 'add', 'edit', 'delete'), 'priority' => 3, 'type' => stTREE, ), ), 'TableName' => TABLE_PREFIX.'PortalUser', 'ListSQLs' => Array( '' => ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'UserGroup ug ON %1$s.PortalUserId = ug.PortalUserId AND ug.PrimaryGroup = 1 LEFT JOIN '.TABLE_PREFIX.'PortalGroup g ON ug.GroupId = g.GroupId LEFT JOIN '.TABLE_PREFIX.'%3$sPortalUserCustomData cust ON %1$s.ResourceId = cust.ResourceId', 'online' => ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'UserSession s ON s.PortalUserId = %1$s.PortalUserId LEFT JOIN '.TABLE_PREFIX.'UserGroup ug ON %1$s.PortalUserId = ug.PortalUserId AND ug.PrimaryGroup = 1 LEFT JOIN '.TABLE_PREFIX.'PortalGroup g ON ug.GroupId = g.GroupId LEFT JOIN '.TABLE_PREFIX.'%3$sPortalUserCustomData cust ON %1$s.ResourceId = cust.ResourceId', ), 'ItemSQLs' => Array( '' => ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'UserGroup ug ON %1$s.PortalUserId = ug.PortalUserId AND ug.PrimaryGroup = 1 LEFT JOIN '.TABLE_PREFIX.'PortalGroup g ON ug.GroupId = g.GroupId LEFT JOIN '.TABLE_PREFIX.'%3$sPortalUserCustomData cust ON %1$s.ResourceId = cust.ResourceId', ), 'ListSortings' => Array ( '' => Array ( 'Sorting' => Array ('Login' => 'asc'), ) ), 'SubItems' => Array('addr', 'u-cdata', 'u-ug', 'u-img', 'fav', 'user-profile'), 'FilterMenu' => Array( 'Groups' => Array( Array('mode' => 'AND', 'filters' => Array('show_active','show_disabled','show_pending'), 'type' => WHERE_FILTER), ), 'Filters' => Array( 'show_active' => Array('label' =>'la_Enabled', 'on_sql' => '', 'off_sql' => '%1$s.Status != 1' ), 'show_disabled' => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Status != 0' ), 'show_pending' => Array('label' => 'la_Pending', 'on_sql' => '', 'off_sql' => '%1$s.Status != 2' ), ) ), 'CalculatedFields' => Array( '' => Array( 'PrimaryGroup' => 'g.Name', 'FullName' => 'CONCAT(FirstName, " ", LastName)', ), ), 'Fields' => Array ( 'PortalUserId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Login' => Array ('type' => 'string', 'unique'=>Array('Login'), 'default' => null,'required'=>1, 'error_msgs' => Array('unique'=>'!lu_user_already_exist!')), 'Password' => Array ('type' => 'string', 'formatter' => 'kPasswordFormatter', 'encryption_method' => 'md5', 'verify_field' => 'VerifyPassword', 'skip_empty' => 1, 'default' => md5('')), 'FirstName' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'LastName' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'Company' => Array ('type' => 'string','not_null' => '1','default' => ''), 'Email' => Array ( 'type' => 'string', 'formatter' => 'kFormatter', 'regexp'=>'/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', 'sample_value' => 'email@domain.com', 'unique' => Array ('Email'), 'not_null' => 1, 'required' => 1, 'default' => '', 'error_msgs' => Array ( 'invalid_format'=>'!la_invalid_email!', 'unique'=>'!lu_email_already_exist!' ), ), 'CreatedOn' => Array('type'=>'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), 'Phone' => Array('type' => 'string','default' => null), 'Fax' => Array('type' => 'string', 'not_null' => 1, 'default' => ''), 'Street' => Array('type' => 'string', 'default' => null), 'Street2' => Array('type' => 'string', 'not_null' => '1', 'default' => ''), 'City' => Array('type' => 'string','default' => null), 'State' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', 'options' => Array(), 'option_key_field'=>'DestAbbr','option_title_field'=>'Translation', 'not_null' => '1','default' => ''), 'Zip' => Array('type' => 'string','default' => null), 'Country' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', 'options_sql'=>'SELECT %1$s FROM '.TABLE_PREFIX.'StdDestinations LEFT JOIN '.TABLE_PREFIX.'Phrase ON '.TABLE_PREFIX.'Phrase.Phrase = '.TABLE_PREFIX.'StdDestinations.DestName WHERE DestType=1 AND LanguageId = %2$s ORDER BY Translation', 'option_key_field'=>'DestAbbr','option_title_field'=>'Translation', 'not_null' => '1','default' => ''), 'ResourceId' => Array('type' => 'int','not_null' => 1, 'default' => 0), 'Status' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options'=>Array(1=>'la_Enabled', 0=>'la_Disabled', 2=>'la_Pending'), 'use_phrases'=>1, 'not_null' => '1','default' => 1), 'Modified' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), 'dob' => Array('type'=>'int', 'formatter' => 'kDateFormatter', 'default' => null), 'tz' => Array('type' => 'int','default' => 0), 'ip' => Array('type' => 'string','default' => null), 'IsBanned' => Array('type' => 'int','not_null' => 1, 'default' => 0), 'PassResetTime' => Array('type' => 'int','default' => null), 'PwResetConfirm' => Array('type' => 'string','default' => null), 'PwRequestTime' => Array('type' => 'int','default' => null), 'MinPwResetDelay' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(300 => '5', 600 => '10', 900 => '15', 1800 => '30', 3600 => '60'), 'use_phrases' => 0, 'not_null' => '1', 'default' => 1800), 'AdminLanguage' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language ORDER BY PackName', 'option_key_field' => 'LanguageId', 'option_title_field' => 'LocalName', 'default' => NULL ), ), 'VirtualFields' => Array( 'ValidateLogin' => Array('type'=>'string','default'=>''), 'SubscribeEmail' => Array('type'=>'string','default'=>''), 'PrimaryGroup' => Array('type' => 'string', 'default' => ''), 'RootPassword' => Array('type' => 'string', 'formatter' => 'kPasswordFormatter', 'encryption_method' => 'md5', 'verify_field' => 'VerifyRootPassword', 'skip_empty' => 1, 'default' => md5('') ), 'FullName' => Array ('type' => 'string', 'default' => ''), 'UserGroup' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %1$s FROM ' . TABLE_PREFIX . 'PortalGroup WHERE Enabled = 1 AND FrontRegistration = 1', 'option_key_field' => 'GroupId', 'option_title_field' => 'Name', 'not_null' => 1, 'default' => 0, ), ), 'Grids' => Array( // not in use 'Default' => Array( 'Icons' => Array( 0 => 'icon16_user_disabled.png', 1 => 'icon16_user.png', 2 => 'icon16_user_pending.png' ), 'Fields' => Array( 'Login' => Array('title' => 'la_col_Username', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_like_filter'), 'LastName' => Array( 'title'=>'la_col_LastName', 'filter_block' => 'grid_like_filter'), 'FirstName' => Array( 'title'=>'la_col_FirstName', 'filter_block' => 'grid_like_filter'), 'Email' => Array( 'title'=>'la_col_Email', 'filter_block' => 'grid_like_filter'), 'PrimaryGroup' => Array( 'title'=>'la_col_PrimaryGroup', 'filter_block' => 'grid_like_filter'), 'CreatedOn' => Array('title' => 'la_col_CreatedOn', 'filter_block' => 'grid_date_range_filter'), ), ), // used 'UserSelector' => Array( 'Icons' => Array( 0 => 'icon16_user_disabled.png', 1 => 'icon16_user.png', 2 => 'icon16_user_pending.png' ), 'Selector' => 'radio', 'Fields' => Array( 'Login' => Array ('title' => 'la_col_Username', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'FirstName' => Array ('title' => 'la_col_FirstName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'LastName' => Array ('title' => 'la_col_LastName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'Email' => Array ('title' => 'la_col_Email', 'filter_block' => 'grid_like_filter', 'width' => 200, ), 'PrimaryGroup' => Array( 'title'=>'la_col_PrimaryGroup', 'filter_block' => 'grid_like_filter', 'width' => 100, ), 'CreatedOn' => Array('title' => 'la_col_CreatedOn', 'filter_block' => 'grid_date_range_filter', 'width' => 150, ), ), ), // used 'Admins' => Array ( 'Icons' => Array( 0 => 'icon16_admin_disabled.png', 1 => 'icon16_admin.png', 2 => 'icon16_admin_disabled.png', ), 'Fields' => Array ( 'PortalUserId' => Array ('title' => 'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 70), 'Login' => Array ('title' => 'la_col_Username', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'FirstName' => Array ('title' => 'la_col_FirstName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'LastName' => Array ('title' => 'la_col_LastName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'Email' => Array ('title' => 'la_col_Email', 'filter_block' => 'grid_like_filter', 'width' => 200, ), ), ), // used 'RegularUsers' => Array ( 'Icons' => Array( 0 => 'icon16_user_disabled.png', 1 => 'icon16_user.png', 2 => 'icon16_user_pending.png' ), 'Fields' => Array( 'PortalUserId' => Array ('title' => 'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 70), 'Login' => Array ('title' => 'la_col_Username', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'FirstName' => Array ('title' => 'la_col_FirstName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), - 'LastName' => Array ('title' => 'la_col_LastName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), + 'LastName' => Array ('title' => 'la_col_LastName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), 'Email' => Array ('title' => 'la_col_Email', 'filter_block' => 'grid_like_filter', 'width' => 200, ), + 'PrimaryGroup' => Array ('title' => 'la_col_PrimaryGroup', 'filter_block' => 'grid_like_filter', 'width' => 140), 'Status' => Array ('title' => 'la_col_Status', 'filter_block' => 'grid_options_filter', 'width' => 100, ), + 'CreatedOn' => Array ('title' => 'la_col_CreatedOn', 'filter_block' => 'grid_date_range_filter', 'width' => 100), ), ), ), ); \ No newline at end of file