/**
  * Saves a new or existing CB+CMS user
  * WARNINGS:
  * - You must verify authorization of user to perform this (user checkCBpermissions() )
  * - You must $this->load() existing user first
  *
  * @param  array   $array   Raw unfiltered input, typically $_POST
  * @param  int     $ui      1 = Front-end (limitted rights), 2 = Backend (almost unlimitted), 0 = automated (full)
  * @param  string  $reason  'edit' or 'register'
  * @return boolean
  */
 function saveSafely(&$array, $ui, $reason)
 {
     global $_CB_framework, $_CB_database, $ueConfig, $_PLUGINS;
     // Get current user state and store it into $oldUserComplete:
     $oldUserComplete = new moscomprofilerUser($this->_db);
     foreach (array_keys(get_object_vars($this)) as $k) {
         if (substr($k, 0, 1) != '_') {
             // ignore internal vars
             $oldUserComplete->{$k} = $this->{$k};
         }
     }
     if ($oldUserComplete->gids === null) {
         $oldUserComplete->gids = array();
     }
     // 1) Process and validate the fields in form by CB field plugins:
     // 2) Bind the fields to CMS User:
     $bindResults = $this->bindSafely($array, $ui, $reason, $oldUserComplete);
     if ($bindResults) {
         // During bindSafely, in saveTabContents, the validations have already taken place, for mandatory fields.
         if ($this->name == '' && $this->username == '' && $this->email != '') {
             $this->username = $this->email;
             $this->_cmsUser->username = $this->username;
         }
         // Checks that name is set. If not, uses the username as name, as Mambo/Joola mosUser::store() uses name for ACL
         // and ACL bugs with no name.
         if ($this->name == '') {
             $this->name = $this->username;
             $this->_cmsUser->name = $this->name;
         } elseif ($this->username == '') {
             $this->username = $this->name;
             $this->_cmsUser->username = $this->username;
         }
         if (!$this->checkSafely()) {
             $bindResults = false;
         }
     }
     // For new registrations or backend user creations, set registration date and password if neeeded:
     $isNew = !$this->id;
     $newCBuser = $oldUserComplete->user_id == null;
     if ($isNew) {
         if (checkJversion() != 1) {
             // J1.5 works better with null here... has bug that it offsets the time by server date, others need this:
             $this->registerDate = $_CB_framework->dateDbOfNow();
         }
     }
     if ($bindResults) {
         if ($isNew) {
             if ($this->password == null) {
                 $this->setRandomPassword();
                 $ueConfig['emailpass'] = 1;
                 // set this global to 1 to force password to be sent to new users.
             }
         }
         // In backend only: if group has been changed and where original group was a Super Admin: check if there is at least a super-admin left:
         if ($ui == 2) {
             $myGids = $_CB_framework->acl->get_groups_below_me(null, true);
             $cms_admin = $_CB_framework->acl->mapGroupNamesToValues('Administrator');
             $cms_super_admin = $_CB_framework->acl->mapGroupNamesToValues('Superadministrator');
             $i_am_super_admin = $_CB_framework->acl->amIaSuperAdmin();
             $i_am_admin = in_array($cms_admin, $myGids);
             if (!$isNew) {
                 if (checkJversion() == 2) {
                     if ($i_am_super_admin && $_CB_framework->myId() == $this->id) {
                         // Check that a fool Super User does not block himself:
                         if ($this->block && !$oldUserComplete->block) {
                             $this->_error = 'Super Users can not block themselves';
                             return false;
                         }
                         // Check that a fool Super User does not demote himself from Super-User rights:
                         if ($this->gids != $oldUserComplete->gids) {
                             $staysSuperUser = $_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.admin', null);
                             if (!$staysSuperUser) {
                                 $this->_error = 'You cannot demote yourself from your Super User permission';
                                 return false;
                             }
                         }
                     }
                     // Check that a non-Super User/non-admin does not demote an admin or a Super user:
                     if ($this->gids != $oldUserComplete->gids) {
                         if (!$i_am_super_admin && !(CBuser::getMyInstance()->authoriseAction('core.admin') || CBuser::getMyInstance()->authoriseAction('core.manage', 'com_users') && CBuser::getMyInstance()->authoriseAction('core.edit', 'com_users') && CBuser::getMyInstance()->authoriseAction('core.edit.state', 'com_users'))) {
                             // I am not a Super User and not an Users administrator:
                             $userIsSuperUser = JUser::getInstance($this->id)->authorise('core.admin');
                             // User is super-user: Check if he stays so:
                             if ($userIsSuperUser) {
                                 $staysSuperUser = $_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.admin', null);
                                 if (!$staysSuperUser) {
                                     $this->_error = 'You cannot remove a Super User permission. Only Super Users can do that.';
                                     return false;
                                 }
                             }
                             $userCanAdminUsers = (CBuser::getInstance($this->id)->authoriseAction('core.manage', 'com_users') || CBuser::getInstance($this->id)->authoriseAction('core.manage')) && CBuser::getInstance($this->id)->authoriseAction('core.edit', 'com_users') && CBuser::getInstance($this->id)->authoriseAction('core.edit.state', 'com_users');
                             // User is users-administrator: check if he can stay so:
                             if ($userCanAdminUsers) {
                                 $staysUserAdmin = ($_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.manage', 'com_users') || $_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.manage')) && $_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.edit', 'com_users') && $_CB_framework->acl->authorizeGroupsForAction($this->gids, 'core.edit.state', 'com_users');
                                 if (!$staysUserAdmin) {
                                     $this->_error = 'An users manager cannot be demoted by a non-administrator';
                                     return false;
                                 }
                             }
                         }
                     }
                 } else {
                     if ($this->gid != $oldUserComplete->gid) {
                         if ($oldUserComplete->gid == $cms_super_admin) {
                             // count number of active super admins
                             $query = 'SELECT COUNT( id )' . "\n FROM #__users" . "\n WHERE gid = " . (int) $cms_super_admin . "\n AND block = 0";
                             $_CB_database->setQuery($query);
                             $count = $_CB_database->loadResult();
                             if ($count <= 1) {
                                 // disallow change if only one Super Admin exists
                                 $this->_error = 'You cannot change this users Group as it is the only active Super Administrator for your site';
                                 return false;
                             }
                         }
                         $user_group = strtolower($_CB_framework->acl->get_group_name($oldUserComplete->gid, 'ARO'));
                         if ($user_group == 'super administrator' && !$i_am_super_admin) {
                             // disallow change of super-Admin by non-super admin
                             $this->_error = 'You cannot change this users Group as you are not a Super Administrator for your site';
                             return false;
                         } elseif ($this->id == $_CB_framework->myId() && $i_am_super_admin) {
                             // CB-specific: disallow change of own Super Admin group:
                             $this->_error = 'You cannot change your own Super Administrator status for your site';
                             return false;
                         } else {
                             if (!$i_am_super_admin && $i_am_admin && $oldUserComplete->gid == $cms_admin) {
                                 // disallow change of super-Admin by non-super admin
                                 $this->_error = 'You cannot change the Group of another Administrator as you are not a Super Administrator for your site';
                                 return false;
                             } elseif (in_array($oldUserComplete->gid, $myGids) && !in_array($this->gid, $myGids)) {
                                 // disallow change of group of user into a group that is not child of admin/superadmin:
                                 $this->_error = 'You cannot change the Group of this user to a group that is not child of Registered or Manager as otherwise that user cannot login. If you really need to do that, you can do it in Joomla User Manager.';
                                 return false;
                             }
                         }
                     }
                     // ensure user can't add group higher than themselves done below
                 }
             }
             // Security check to avoid creating/editing user to higher level than himself: CB response to artf4529.
             if (!$i_am_super_admin && $this->gids != $oldUserComplete->gids) {
                 // Does user try to edit a user that has higher groups ?
                 if (count(array_diff($this->gids, $myGids)) != 0) {
                     $this->_error = 'Unauthorized attempt to change an user at higher level than allowed !';
                     return false;
                 }
                 // Does the user try to demote higher levels ?
                 if (array_diff($this->gids, $myGids) != array_diff($oldUserComplete->gids, $myGids)) {
                     $this->_error = 'Unauthorized attempt to change higher groups of an user than allowed !';
                     return false;
                 }
             }
         }
     }
     if ($reason == 'edit') {
         if ($ui == 1) {
             $_PLUGINS->trigger('onBeforeUserUpdate', array(&$this, &$this, &$oldUserComplete, &$oldUserComplete));
         } elseif ($ui == 2) {
             if ($isNew || $newCBuser) {
                 $_PLUGINS->trigger('onBeforeNewUser', array(&$this, &$this, false));
             } else {
                 $_PLUGINS->trigger('onBeforeUpdateUser', array(&$this, &$this, &$oldUserComplete));
             }
         }
     } elseif ($reason == 'register') {
         $_PLUGINS->trigger('onBeforeUserRegistration', array(&$this, &$this));
     }
     $beforeResult = !$_PLUGINS->is_errors();
     if (!$beforeResult) {
         $this->_error = $_PLUGINS->getErrorMSG(false);
         // $_PLUGIN collects all error messages, incl. previous ones.
     }
     // Saves tab plugins:
     // on edits, user params and block/email/approved/confirmed are done in cb.core predefined fields.
     // So now calls this and more (CBtabs are already created in $this->bindSafely() ).
     $pluginTabsResult = true;
     if ($reason == 'edit') {
         $this->_cbTabs->savePluginTabs($this, $array);
         $pluginTabsResult = !$_PLUGINS->is_errors();
         if (!$pluginTabsResult) {
             $this->_error = $_PLUGINS->getErrorMSG(false);
             // $_PLUGIN collects all error messages, incl. previous ones.
         }
     }
     if ($bindResults && $beforeResult && $pluginTabsResult) {
         // Hashes password for CMS storage:
         $clearTextPassword = $this->password;
         if ($clearTextPassword) {
             $hashedPassword = $this->hashAndSaltPassword($clearTextPassword);
             $this->password = $hashedPassword;
         }
         // Stores user if it's a new user:
         if ($isNew) {
             if (!$this->store()) {
                 return false;
             }
         }
         // Restores cleartext password for the saveRegistrationPluginTabs:
         $this->password = $clearTextPassword;
         if ($isNew) {
             // Sets the instance of user, to avoid reload from database, and loss of the cleartext password.
             CBuser::setUserGetCBUserInstance($this);
         }
     }
     if ($reason == 'register') {
         // call here since we got to have a user id:
         $registerResults = array();
         $registerResults['tabs'] = $this->_cbTabs->saveRegistrationPluginTabs($this, $array);
         if ($_PLUGINS->is_errors()) {
             if ($bindResults && $beforeResult && $pluginTabsResult) {
                 $plugins_error = $_PLUGINS->getErrorMSG(false);
                 // $_PLUGIN collects all error messages, incl. previous ones.
                 if ($isNew) {
                     // if it was a new user, and plugin gave error, revert the creation:
                     $this->delete();
                 }
                 $this->_error = $plugins_error;
             } else {
                 $this->_error = $_PLUGINS->getErrorMSG(false);
                 // $_PLUGIN collects all error messages, incl. previous ones.
             }
             $pluginTabsResult = false;
         }
     }
     if ($bindResults && $beforeResult && $pluginTabsResult) {
         $this->_cbTabs->commitTabsContents($this, $array, $reason);
         $commit_errors = $_PLUGINS->getErrorMSG(false);
         if (count($commit_errors) > 0) {
             $this->_error = $commit_errors;
             $bindResults = false;
         }
     }
     if (!($bindResults && $beforeResult && $pluginTabsResult)) {
         $this->_cbTabs->rollbackTabsContents($this, $array, $reason);
         // Normal error exit point:
         $_PLUGINS->trigger('onSaveUserError', array(&$this, $this->_error, $reason));
         if (is_array($this->_error)) {
             $this->_error = implode('<br />', $this->_error);
         }
         return false;
     }
     // Stores the user (again if it's a new as the plugins might have changed the user record):
     if ($clearTextPassword) {
         $this->password = $hashedPassword;
     }
     if (!$this->store()) {
         return false;
     }
     // Restores cleartext password for the onAfter and activation events:
     $this->password = $clearTextPassword;
     // Triggers onAfter and activateUser events:
     if ($reason == 'edit') {
         if ($ui == 1) {
             $_PLUGINS->trigger('onAfterUserUpdate', array(&$this, &$this, $oldUserComplete));
         } elseif ($ui == 2) {
             if ($isNew || $newCBuser) {
                 if ($isNew) {
                     $ueConfig['emailpass'] = 1;
                     // set this global to 1 to force password to be sent to new users.
                 }
                 $_PLUGINS->trigger('onAfterNewUser', array(&$this, &$this, false, true));
                 if ($this->block == 0 && $this->approved == 1 && $this->confirmed) {
                     activateUser($this, 2, 'NewUser', false, $isNew);
                 }
             } else {
                 if (!(($oldUserComplete->approved == 1 || $oldUserComplete->approved == 2) && $oldUserComplete->confirmed) && ($this->approved == 1 && $this->confirmed)) {
                     // first time a just registered and confirmed user got approved in backend through save user:
                     if (isset($ueConfig['emailpass']) && $ueConfig['emailpass'] == "1" && $this->password == '') {
                         // generate the password is auto-generated and not set by the admin at this occasion:
                         $this->setRandomPassword();
                         $pwd = $this->hashAndSaltPassword($this->password);
                         $_CB_database->setQuery("UPDATE #__users SET password="******" WHERE id = " . (int) $this->id);
                         $_CB_database->query();
                     }
                 }
                 $_PLUGINS->trigger('onAfterUpdateUser', array(&$this, &$this, $oldUserComplete));
                 if (!(($oldUserComplete->approved == 1 || $oldUserComplete->approved == 2) && $oldUserComplete->confirmed) && ($this->approved == 1 && $this->confirmed)) {
                     // first time a just registered and confirmed user got approved in backend through save user:
                     activateUser($this, 2, 'UpdateUser', false);
                 }
             }
         }
     } elseif ($reason == 'register') {
         $registerResults['after'] = $_PLUGINS->trigger('onAfterUserRegistration', array(&$this, &$this, true));
         $registerResults['ok'] = true;
         return $registerResults;
     }
     return true;
 }
Пример #2
0
	function drawUsersList( $uid, $listid, $searchFormValuesRAW ) {
		global $_CB_database, $_CB_framework, $ueConfig, $Itemid, $_PLUGINS;
	
		$search					=	null;
		$searchGET				=	cbGetParam( $searchFormValuesRAW, 'search' );
		$limitstart				=	(int) cbGetParam( $searchFormValuesRAW, 'limitstart', 0 );
		$searchmode				=	(int) cbGetParam( $searchFormValuesRAW, 'searchmode', 0 );
		$randomParam			=	(int) cbGetParam( $searchFormValuesRAW, 'rand', 0 );
	
		// old search on formated name:
	
	/*	if ( $searchPOST || count( $_POST ) ) {
			// simple spoof check security
			cbSpoofCheck( 'usersList' );
			if ( cbGetParam( $searchFormValuesRAW, "action" ) == "search" ) {
				$search			=	$searchPOST;
			}
		} else
			if ( isset( $searchFormValuesRAW['limitstart'] ) ) {
				$search				=	stripslashes( $searchGET );
			}
	*/
		// get my user and gets the list of user lists he is allowed to see (ACL):
	
		$myCbUser				=&	CBuser::getInstance( $uid );
		if ( $myCbUser === null ) {
			$myCbUser			=&	CBuser::getInstance( null );
		}
		$myUser					=&	$myCbUser->getUserData();
	/*
		$myUser					=	new moscomprofilerUser( $_CB_database );
		if ( $uid ) {
			$myUser->load( (int) $uid );
		}
	*/
		$useraccessgroupSQL		=	" AND useraccessgroupid IN (".implode(',',getChildGIDS(userGID($uid))).")";
		$_CB_database->setQuery( "SELECT listid, title FROM #__comprofiler_lists WHERE published=1" . $useraccessgroupSQL . " ORDER BY ordering" );
		$plists					=	$_CB_database->loadObjectList();
		$lists					=	array();
		$publishedlists			=	array();
	
		for ( $i=0, $n=count( $plists ); $i < $n; $i++ ) {
			$plist				=&	$plists[$i];
			$listTitleNoHtml	=	strip_tags( cbReplaceVars( getLangDefinition( $plist->title ), $myUser, false, false ) );
		   	$publishedlists[]	=	moscomprofilerHTML::makeOption( $plist->listid, $listTitleNoHtml );
		}
	
		// select either list selected or default list to which he has access (ACL):
	
		if ( $listid == 0 ) {
			$_CB_database->setQuery( "SELECT listid FROM #__comprofiler_lists "
			. "\n WHERE `default`=1 AND published=1" . $useraccessgroupSQL );
			$listid				=	(int) $_CB_database->loadresult();
			if ( $listid == 0 && ( count( $plists ) > 0 ) ) {
				$listid			=	(int) $plists[0]->listid;
			}
		}
		if ( ! ( $listid > 0 ) ) {
			echo _UE_NOLISTFOUND;
			return;
		}
	
		// generates the drop-down list of lists:
	
		if ( count( $plists ) > 1 ) {
			$lists['plists']	=	moscomprofilerHTML::selectList( $publishedlists, 'listid', 'class="inputbox" size="1" onchange="this.form.submit();"', 'value', 'text', $listid, 1 );
		}
	
		// loads the list record:
	
		$row					=	new moscomprofilerLists( $_CB_database );
		if ( ( ! $row->load( (int) $listid ) ) || ( $row->published != 1 ) ) {
			echo _UE_LIST_DOES_NOT_EXIST;
			return;
		}
		if ( ! allowAccess( $row->useraccessgroupid,'RECURSE', userGID($uid) ) ) {
			echo _UE_NOT_AUTHORIZED;
			return;
		}
	
		$params					=	new cbParamsBase( $row->params );
	
		$hotlink_protection		=	$params->get( 'hotlink_protection', 0 );
		if ( $hotlink_protection == 1 ) {
			if ( ( $searchGET !== null ) || $limitstart ) {
				cbSpoofCheck( 'usersList', 'GET' );
			}
		}
	
		$limit					=	(int) $params->get( 'list_limit' );
		if ( $limit == 0 ) {
			$limit				=	(int) $ueConfig['num_per_page'];
		}
	
		$showPaging				=	$params->get( 'list_paging', 1 );
		if ( $showPaging != 1 ) {
			$limitstart			=	0;
		}
	
		$isModerator			=	isModerator( $_CB_framework->myId() );
	
		$_PLUGINS->loadPluginGroup( 'user' );
		// $plugSearchFieldsArray	=	$_PLUGINS->trigger( 'onStartUsersList', array( &$listid, &$row, &$search, &$limitstart, &$limit ) );
		$_PLUGINS->trigger( 'onStartUsersList', array( &$listid, &$row, &$search, &$limitstart, &$limit ) );
	
		// handles the users allowed to be listed in the list by ACL:
	
		$allusergids			=	array();
		$usergids				=	explode( ',', $row->usergroupids );
	/*	This was a bug tending to list admins when "public backend" was checked, and all frontend users when "public backend was checked. Now just ignore them:
		foreach( $usergids AS $usergid ) {
			$allusergids[]		=	$usergid;
			if ($usergid==29 || $usergid==30) {
				$groupchildren	=	array();
				$groupchildren	=	$_CB_framework->acl->get_group_children( $usergid, 'ARO','RECURSE' );
				$allusergids	=	array_merge($allusergids,$groupchildren);
			}
		}
	*/
		$allusergids			=	array_diff( $usergids, array( 29, 30 ) );
		$usergids				=	implode( ",", $allusergids );
	
		// build SQL Select query:
	
		$random					=	0;
		if( $row->sortfields != '' ) {
			$matches			=	null;
			if ( preg_match( '/^RAND\(\)\s(ASC|DESC)$/', $row->sortfields, $matches ) ) {
				// random sorting needs to have same seed on pages > 1 to not have probability to show same users:
				if ( $limitstart ) {
					$random		=	(int) $randomParam;
				}
				if ( ! $random ) {
					$random		=	rand( 0, 32767 );
				}
				$row->sortfields =	'RAND(' . (int) $random . ') ' . $matches[1];
			}
			$orderby			=	"\n ORDER BY " . $row->sortfields;
		}
		$filterby				=	'';
		if ( $row->filterfields != '' ) {
			$filterRules		=	utf8RawUrlDecode( substr( $row->filterfields, 1 ) );
	
			if ( $_CB_framework->myId() ) {
				$user			=	new moscomprofilerUser( $_CB_database );
				if ( $user->load( (int) $_CB_framework->myId() ) ) {
					$filterRules	=	cbReplaceVars( $filterRules, $user, array( $_CB_database, 'getEscaped' ), false, array() );
				}
			}
			$filterby			=	" AND ". $filterRules;
		}
	
		// Prepare part after SELECT .... " and before "FROM" :
	
		$tableReferences		=	array( '#__comprofiler' => 'ue', '#__users' => 'u' );
	
		// Fetch all fields:
	
		$tabs					=	$myCbUser->_getCbTabs();		//	new cbTabs( 0, 1 );		//TBD: later: this private method should not be called here, but the whole users-list should go into there and be called here.
	
		$allFields				=	$tabs->_getTabFieldsDb( null, $myUser, 'list' );
		// $_CB_database->setQuery( "SELECT * FROM #__comprofiler_fields WHERE published = 1" );
		// $allFields				=	$_CB_database->loadObjectList( 'fieldid', 'moscomprofilerFields', array( &$_CB_database ) );
	
	
		//Make columns array. This array will later be constructed from the tabs table:
	
		$columns				=	array();
	
		for ( $i = 1; $i < 50; ++$i ) {
			$enabledVar			=	"col".$i."enabled";
	
			if ( ! isset( $row->$enabledVar ) ) {
				break;
			}
			$titleVar			=	"col".$i."title";
			$fieldsVar			=	"col".$i."fields";
			$captionsVar		=	"col".$i."captions";
	
			if ( $row->$enabledVar == 1 ) {
				$col			=	new stdClass();
				$col->fields	=	( $row->$fieldsVar ? explode( '|*|', $row->$fieldsVar ) : array() );
				$col->title		=	$row->$titleVar;
				$col->titleRendered		=	$myCbUser->replaceUserVars( $col->title );
				$col->captions	=	$row->$captionsVar;
				// $col->sort	=	1; //All columns can be sorted
				$columns[$i]	=	$col;
			}
		}
	
		// build fields and tables accesses, also check for searchable fields:
	
		$searchableFields		=	array();
		$fieldsSQL				=	cbUsersList::getFieldsSQL( $columns, $allFields, $tableReferences, $searchableFields, $params );
	
		$_PLUGINS->trigger( 'onAfterUsersListFieldsSql', array( &$columns, &$allFields, &$tableReferences ) );
	
		$tablesSQL				=	array();
		$joinsSQL				=	array();
		$tablesWhereSQL			=	array(	'block'		=>	'u.block = 0',
											'approved'	=>	'ue.approved = 1',
											'confirmed'	=>	'ue.confirmed = 1'
										 );
	
		if ( checkJversion() == 2 ) {
			$joinsSQL[]				=	'JOIN #__user_usergroup_map g ON g.`user_id` = u.`id`';
		}
	
		if ( ! $isModerator ) {
			$tablesWhereSQL['banned']	=	'ue.banned = 0';
		}
		if ( $usergids ) {
			if ( checkJversion() == 2 ) {
				$tablesWhereSQL['gid']	=	'g.group_id IN (' . $usergids . ')';
			} else {
				$tablesWhereSQL['gid']	=	'u.gid IN (' . $usergids . ')';
			}
		}
	
		foreach ( $tableReferences as $table => $name ) {
			$tablesSQL[]				=	$table . ' ' . $name;
			if ( $name != 'u' ) {
				$tablesWhereSQL[]		=	"u.`id` = " . $name . ".`id`";
			}
		}
	
		// handles search criterias:
	
		$list_compare_types		=	$params->get( 'list_compare_types', 0 );
		$searchVals				=	new stdClass();
		$searchesFromFields		=	$tabs->applySearchableContents( $searchableFields, $searchVals, $searchFormValuesRAW, $list_compare_types );
		$whereFields			=	$searchesFromFields->reduceSqlFormula( $tableReferences, $joinsSQL, TRUE );
		if ( $whereFields ) {
			$tablesWhereSQL[]	=	'(' . $whereFields . ')';
	/*
			if ( $search === null ) {
				$search			=	'';
			}
	*/
		}
	
		$_PLUGINS->trigger( 'onBeforeUsersListBuildQuery', array( &$tablesSQL, &$joinsSQL, &$tablesWhereSQL ) );
	
		$queryFrom				=	"FROM " . implode( ', ', $tablesSQL )
								.	( count( $joinsSQL ) ? "\n " . implode( "\n ", $joinsSQL ) : '' )
								.	"\n WHERE " . implode( "\n AND ", $tablesWhereSQL );
	
		// handles old formatted names search:
	/*
		if ( $search != '' ) {
			$searchSQL			=	cbEscapeSQLsearch( strtolower( $_CB_database->getEscaped( $search ) ) );
			$queryFrom 			.=	" AND (";
	
			$searchFields		=	array();
			if ( $ueConfig['name_format']!='3' ) {
				$searchFields[]	=	"u.name LIKE '%%s%'";
			}
			if ( $ueConfig['name_format']!='1' ) {
				$searchFields[]	=	"u.username LIKE '%%s%'";
			}
			if ( is_array( $plugSearchFieldsArray ) ) {
				foreach ( $plugSearchFieldsArray as $v ) {
					if ( is_array( $v ) ) {
						$searchFields	=	array_merge( $searchFields, $v );
					}
				}
			}
			$queryFrom			.=	str_replace( '%s', $searchSQL, implode( " OR ", $searchFields ) );
			$queryFrom			.=	")";
		}
	*/
		$queryFrom				.=	" " . $filterby;
	
		$_PLUGINS->trigger( 'onBeforeUsersListQuery', array( &$queryFrom, 1, $listid ) );	// $uid = 1
	
		$errorMsg		=	null;
	
		// counts number of users and loads the listed fields of the users if not in search-form-only mode:
	
		if ( $searchmode == 0 ) {
			if ( checkJversion() == 2 ) {
				$_CB_database->setQuery( "SELECT COUNT(DISTINCT u.id) " . $queryFrom );
			} else {
			$_CB_database->setQuery( "SELECT COUNT(*) " . $queryFrom );
			}
			$total					=	$_CB_database->loadResult();
	
			if ( ( $limit > $total ) || ( $limitstart >= $total ) ) {
				$limitstart			=	0;
			}
	
			// $query					=	"SELECT u.id, ue.banned, '' AS 'NA' " . ( $fieldsSQL ? ", " . $fieldsSQL . " " : '' ) . $queryFrom . " " . $orderby
			if ( checkJversion() == 2 ) {
				$query				=	"SELECT DISTINCT ue.*, u.*, '' AS 'NA' " . ( $fieldsSQL ? ", " . $fieldsSQL . " " : '' ) . $queryFrom . " " . $orderby;
			} else {
				$query				=	"SELECT ue.*, u.*, '' AS 'NA' " . ( $fieldsSQL ? ", " . $fieldsSQL . " " : '' ) . $queryFrom . " " . $orderby;
			}
			$_CB_database->setQuery( $query, (int) $limitstart, (int) $limit );
			$users				=	$_CB_database->loadObjectList( null, 'moscomprofilerUser', array( &$_CB_database ) );
	
			if ( ! $_CB_database->getErrorNum() ) {
				// creates the CBUsers in cache corresponding to the $users:
				foreach ( array_keys( $users ) as $k) {
					CBuser::setUserGetCBUserInstance( $users[$k] );
				}
			} else {
				$users			=	array();
				$errorMsg		=	_UE_ERROR_IN_QUERY_TURN_SITE_DEBUG_ON_TO_VIEW;
			}
	
			if ( count( get_object_vars( $searchVals ) ) > 0 ) {
				$search			=	'';
			} else {
				$search			=	null;
			}
	
		} else {
			$total				=	null;
			$users				=	array();
			if ( $search === null ) {
				$search			=	'';
			}
		}
	
		// Compute itemId of users in users-list:
	
		if ( $Itemid ) {
			$option_itemid		=	(int) $Itemid;
		} else {
			$option_itemid		=	getCBprofileItemid( 0 );
		}
		HTML_comprofiler::usersList( $row, $users, $columns, $allFields, $lists, $listid, $search, $searchmode, $option_itemid, $limitstart, $limit, $total, $myUser, $searchableFields, $searchVals, $tabs, $list_compare_types, $showPaging, $hotlink_protection, $errorMsg, $random );
	}
Пример #3
0
	/**
	 * Saves a new or existing CB+CMS user
	 * WARNINGS:
	 * - You must verify authorization of user to perform this (user checkCBpermissions() )
	 * - You must $this->load() existing user first
	 *
	 * @param  array   $array   Raw unfiltered input, typically $_POST
	 * @param  int     $ui      1 = Front-end (limitted rights), 2 = Backend (almost unlimitted), 0 = automated (full)
	 * @param  string  $reason  'edit' or 'register'
	 * @return boolean
	 */
	function saveSafely( &$array, $ui, $reason ) {
		global $_CB_framework, $_CB_database, $ueConfig, $_PLUGINS;

		// Get current user state and store it into $oldUserComplete:

		$oldUserComplete						=	new moscomprofilerUser( $this->_db );
		foreach ( array_keys( get_object_vars( $this ) ) as $k ) {
			if( substr( $k, 0, 1 ) != '_' ) {		// ignore internal vars
				$oldUserComplete->$k			=	$this->$k;
			}
		}


		// 1) Process and validate the fields in form by CB field plugins:
		// 2) Bind the fields to CMS User:
		$bindResults							=	$this->bindSafely( $array, $ui, $reason, $oldUserComplete );

		if ( $bindResults ) {
			// During bindSafely, in saveTabContents, the validations have already taken place, for mandatory fields.
			if ( ( $this->name == '' ) && ( $this->username == '' ) && ( $this->email != '' ) ) {
				$this->username						=	$this->email;
				$this->_cmsUser->username			=	$this->username;
			}
			// Checks that name is set. If not, uses the username as name, as Mambo/Joola mosUser::store() uses name for ACL
			// and ACL bugs with no name.
			if ( $this->name == '' ) {
				$this->name							=	$this->username;
				$this->_cmsUser->name				=	$this->name;
			} elseif ( $this->username == '' ) {
				$this->username						=	$this->name;
				$this->_cmsUser->username			=	$this->username;
			}

			if ( ! $this->checkSafely() ) {
				$bindResults					=	false;
			}
		}

		// For new registrations or backend user creations, set registration date and password if neeeded:
		$isNew									=	( ! $this->id );
		$newCBuser								=	( $oldUserComplete->user_id == null );

		if ( $isNew ) {
			if ( checkJversion() != 1 ) {
				// J1.5 works better with null here... has bug that it offsets the time by server date, others need this:
				$this->registerDate				=	date('Y-m-d H:i:s', $_CB_framework->now() );
			}
		}

		if ( $bindResults ) {
			if ( $isNew ) {
				if ( $this->password == null ) {
					$this->setRandomPassword();
					$ueConfig['emailpass']		=	1;		// set this global to 1 to force password to be sent to new users.
				}
			}

			// In backend only: if group has been changed and where original group was a Super Admin: check if there is at least a super-admin left:
			if ( $ui == 2 ) {
				$myGid							=	userGID( $_CB_framework->myId() );
				$cms_admin						=	$_CB_framework->acl->mapGroupNamesToValues( 'Administrator' );
				$cms_super_admin				=	$_CB_framework->acl->mapGroupNamesToValues( 'Superadministrator' );
				if ( ! $isNew ) {
					if ( $this->gid != $oldUserComplete->gid ) {
						if ( $oldUserComplete->gid == $cms_super_admin ) {
							// count number of active super admins
							if ( checkJversion() == 2 ) {
								$query			=	'SELECT COUNT( a.id )'
												.	"\n FROM #__users AS a"
												.	"\n INNER JOIN #__user_usergroup_map AS b"
												.	' ON b.user_id = a.id'
												.	"\n WHERE b.group_id = " . (int) $cms_super_admin
												.	"\n AND a.block = 0"
												;
							} else {
								$query			=	'SELECT COUNT( id )'
												.	"\n FROM #__users"
												.	"\n WHERE gid = " . (int) $cms_super_admin
												.	"\n AND block = 0"
												;
							}
							$_CB_database->setQuery( $query );
							$count				=	$_CB_database->loadResult();

							if ( $count <= 1 ) {
								// disallow change if only one Super Admin exists
								$this->_error	=	'You cannot change this users Group as it is the only active Super Administrator for your site';
								return false;
							}
						}

						$user_group				=	strtolower( $_CB_framework->acl->get_group_name( $oldUserComplete->gid, 'ARO' ) );

						if ( ( $user_group == 'super administrator' && $myGid != $cms_super_admin ) ) {
							// disallow change of super-Admin by non-super admin
							$this->_error		=	'You cannot change this users Group as you are not a Super Administrator for your site';
								return false;
						} elseif ( $this->id == $_CB_framework->myId() && $myGid == $cms_super_admin ) {
							// CB-specific: disallow change of own Super Admin group:
							$this->_error		=	'You cannot change your own Super Administrator status for your site';
								return false;
						} else if ( $myGid == $cms_admin && $oldUserComplete->gid == $cms_admin ) {
							// disallow change of super-Admin by non-super admin
							$this->_error		=	'You cannot change the Group of another Administrator as you are not a Super Administrator for your site';
								return false;
						}	// ensure user can't add group higher than themselves done below
					}

				}
				// Security check to avoid creating/editing user to higher level than himself: CB response to artf4529.
				if ( ! in_array( $this->gid, getChildGIDS( $myGid ) ) ) {
						$this->_error				=	'illegal attempt to set user at higher level than allowed !';
						return false;
					}

			}

		}

		if ( $reason == 'edit' ) {
			if ( $ui == 1 ) {
				$_PLUGINS->trigger( 'onBeforeUserUpdate', array( &$this, &$this, &$oldUserComplete, &$oldUserComplete ) );
			} elseif ( $ui == 2 ) {
				if ( $isNew || $newCBuser ) {
					$_PLUGINS->trigger( 'onBeforeNewUser', array( &$this, &$this, false ) );
				} else {
					$_PLUGINS->trigger( 'onBeforeUpdateUser', array( &$this, &$this, &$oldUserComplete ) );
				}
			}
		} elseif ( $reason == 'register' ) {
			$_PLUGINS->trigger( 'onBeforeUserRegistration', array( &$this, &$this ) );
		}
		$beforeResult							=	! $_PLUGINS->is_errors();
		if ( ! $beforeResult ) {
			$this->_error						=	$_PLUGINS->getErrorMSG( false );			// $_PLUGIN collects all error messages, incl. previous ones.
		}

		// Saves tab plugins:

		// on edits, user params and block/email/approved/confirmed are done in cb.core predefined fields.
		// So now calls this and more (CBtabs are already created in $this->bindSafely() ).
		$pluginTabsResult						=	true;
		if ( $reason == 'edit' ) {
			$this->_cbTabs->savePluginTabs( $this, $array );
			$pluginTabsResult					=	! $_PLUGINS->is_errors();
			if ( ! $pluginTabsResult ) {
				$this->_error					=	$_PLUGINS->getErrorMSG( false );			// $_PLUGIN collects all error messages, incl. previous ones.
			}
		}

		if ( $bindResults && $beforeResult && $pluginTabsResult ) {
			// Hashes password for CMS storage:

			$clearTextPassword					=	$this->password;
			if ( $clearTextPassword ) {
				$hashedPassword					=	$this->hashAndSaltPassword( $clearTextPassword );
				$this->password					=	$hashedPassword;
			}

			// Stores user if it's a new user:

			if ( $isNew ) {
				if ( ! $this->store() ) {
					return false;
				}
			}

			// Restores cleartext password for the saveRegistrationPluginTabs:

			$this->password						=	$clearTextPassword;
		}

		if ( $reason == 'register' ) {
			if ( $bindResults && $beforeResult && $pluginTabsResult ) {
				// Sets the instance of user, to avoid reload from database, and loss of the cleartext password.
				CBuser::setUserGetCBUserInstance( $this );
			}
			// call here since we got to have a user id:
			$registerResults					=	array();
			$registerResults['tabs']			=	$this->_cbTabs->saveRegistrationPluginTabs( $this, $array );
			if ( $_PLUGINS->is_errors() ) {

				if ( $bindResults && $beforeResult && $pluginTabsResult ) {
					$plugins_error				=	$_PLUGINS->getErrorMSG( false );			// $_PLUGIN collects all error messages, incl. previous ones.
					if ( $isNew ) {
						// if it was a new user, and plugin gave error, revert the creation:
						$this->delete();
					}
					$this->_error				=	$plugins_error;
				} else {
					$this->_error				=	$_PLUGINS->getErrorMSG( false );			// $_PLUGIN collects all error messages, incl. previous ones.
				}
				$pluginTabsResult				=	false;
			}
		}

		if ( ! ( $bindResults && $beforeResult && $pluginTabsResult ) ) {
			// Normal error exit point:
			$_PLUGINS->trigger( 'onSaveUserError', array( &$this, $this->_error, $reason ) );
			if ( is_array( $this->_error ) ) {
				$this->_error						=	implode( '<br />', $this->_error );
			}
			return false;
		}

		// Stores the user (again if it's a new as the plugins might have changed the user record):
		if ( $clearTextPassword ) {
			$this->password						=	$hashedPassword;
		}
		if ( ! $this->store() ) {
			return false;
		}

		// Restores cleartext password for the onAfter and activation events:

		$this->password							=	$clearTextPassword;

		// Triggers onAfter and activateUser events:

		if ( $reason == 'edit' ) {
			if ( $ui == 1 ) {
				$_PLUGINS->trigger( 'onAfterUserUpdate', array( &$this, &$this, $oldUserComplete ) );
			} elseif ( $ui == 2 ) {
				if ( $isNew || $newCBuser ) {
					if ( $isNew ) {
						$ueConfig['emailpass']	=	1;		// set this global to 1 to force password to be sent to new users.
					}
					$_PLUGINS->trigger( 'onAfterNewUser', array( &$this, &$this, false, true ) );
					if ( $this->block == 0 && $this->approved == 1 && $this->confirmed ) {
						activateUser( $this, 2, 'NewUser', false, $isNew );
					}
				} else {
					if ( ( ! ( ( $oldUserComplete->approved == 1 || $oldUserComplete->approved == 2 ) && $oldUserComplete->confirmed ) )
						 && ($this->approved == 1 && $this->confirmed ) )
					{
						// first time a just registered and confirmed user got approved in backend through save user:
						if( isset( $ueConfig['emailpass'] ) && ( $ueConfig['emailpass'] == "1" ) && ( $this->password == '' ) ) {
							// generate the password is auto-generated and not set by the admin at this occasion:
							$this->setRandomPassword();
							$pwd			=	$this->hashAndSaltPassword( $this->password );
							$_CB_database->setQuery( "UPDATE #__users SET password="******" WHERE id = " . (int) $this->id );
			    			$_CB_database->query();
						}
					}
					$_PLUGINS->trigger( 'onAfterUpdateUser', array( &$this, &$this, $oldUserComplete ) );
					if ( ( ! ( ( $oldUserComplete->approved == 1 || $oldUserComplete->approved == 2 ) && $oldUserComplete->confirmed ) )
						 && ($this->approved == 1 && $this->confirmed ) )
					{
						// first time a just registered and confirmed user got approved in backend through save user:
						activateUser( $this, 2, 'UpdateUser', false );
					}

				}
			}
		} elseif ( $reason == 'register' ) {
			$registerResults['after']			=	$_PLUGINS->trigger( 'onAfterUserRegistration', array( &$this, &$this, true ) );
			$registerResults['ok']				=	true;
			return $registerResults;
		}
		return true;
	}
Пример #4
-1
 /**
  * Draws Users list (ECHO)
  *
  * @param  int      $userId
  * @param  int      $listId
  * @param  array    $postData
  * @return void
  */
 public function drawUsersList($userId, $listId, $postData)
 {
     global $_CB_database, $_PLUGINS;
     $_PLUGINS->loadPluginGroup('user');
     $searchData = cbGetParam($postData, 'search');
     $limitstart = (int) cbGetParam($postData, 'limitstart');
     $searchMode = (int) cbGetParam($postData, 'searchmode', 0);
     $random = (int) cbGetParam($postData, 'rand', 0);
     $cbUser = CBuser::getInstance((int) $userId, false);
     $user = $cbUser->getUserData();
     $search = null;
     $input = array();
     $publishedLists = array();
     $query = 'SELECT *' . "\n FROM " . $_CB_database->NameQuote('#__comprofiler_lists') . "\n WHERE " . $_CB_database->NameQuote('published') . " = 1" . "\n AND " . $_CB_database->NameQuote('viewaccesslevel') . " IN " . $_CB_database->safeArrayOfIntegers(Application::MyUser()->getAuthorisedViewLevels()) . "\n ORDER BY " . $_CB_database->NameQuote('ordering');
     $_CB_database->setQuery($query);
     /** @var ListTable[] $userLists */
     $userLists = $_CB_database->loadObjectList(null, '\\CB\\Database\\Table\\ListTable', array($_CB_database));
     if ($userLists) {
         foreach ($userLists as $userList) {
             $publishedLists[] = moscomprofilerHTML::makeOption((int) $userList->listid, strip_tags($cbUser->replaceUserVars($userList->title, false, false)));
             if (!$listId && $userList->default) {
                 $listId = (int) $userList->listid;
             }
         }
         if (!$listId) {
             $listId = (int) $userLists[0]->listid;
         }
     }
     if (!$listId) {
         echo CBTxt::Th('UE_NOLISTFOUND', 'There are no published user lists!');
         return;
     }
     if ($userLists) {
         $input['plists'] = moscomprofilerHTML::selectList($publishedLists, 'listid', 'class="form-control input-block" onchange="this.form.submit();"', 'value', 'text', (int) $listId, 1);
     }
     $row = self::getInstance((int) $listId);
     if (!$row) {
         echo CBTxt::Th('UE_LIST_DOES_NOT_EXIST', 'This list does not exist');
         return;
     }
     if (!$cbUser->authoriseView('userslist', $row->listid)) {
         echo CBTxt::Th('UE_NOT_AUTHORIZED', 'You are not authorized to view this page!');
         return;
     }
     $params = new Registry($row->params);
     if ($params->get('hotlink_protection', 0) == 1) {
         if ($searchData !== null || $limitstart) {
             cbSpoofCheck('userslist', 'GET');
         }
     }
     $limit = (int) $params->get('list_limit', 30);
     if (!$limit) {
         $limit = 30;
     }
     if ($params->get('list_paging', 1) != 1) {
         $limitstart = 0;
     }
     $isModerator = Application::MyUser()->isGlobalModerator();
     $_PLUGINS->trigger('onStartUsersList', array(&$listId, &$row, &$search, &$limitstart, &$limit));
     // Prepare query variables:
     $userGroupIds = explode('|*|', $row->usergroupids);
     $orderBy = self::getSorting($listId, $userId, $random);
     $filterBy = self::getFiltering($listId, $userId);
     $columns = self::getColumns($listId, $userId);
     // Grab all the fields the $user can access:
     $tabs = new cbTabs(0, 1);
     $fields = $tabs->_getTabFieldsDb(null, $user, 'list');
     // Build the field SQL:
     $tableReferences = array('#__comprofiler' => 'ue', '#__users' => 'u');
     $searchableFields = array();
     $fieldsSQL = cbUsersList::getFieldsSQL($columns, $fields, $tableReferences, $searchableFields, $params);
     $_PLUGINS->trigger('onAfterUsersListFieldsSql', array(&$columns, &$fields, &$tableReferences));
     // Build the internal joins and where statements best off list parameters:
     $tablesSQL = array();
     $joinsSQL = array();
     $tablesWhereSQL = array();
     if ($isModerator) {
         if (!$params->get('list_show_blocked', 0)) {
             $tablesWhereSQL['block'] = 'u.block = 0';
         }
         if (!$params->get('list_show_banned', 1)) {
             $tablesWhereSQL['banned'] = 'ue.banned = 0';
         }
         if (!$params->get('list_show_unapproved', 0)) {
             $tablesWhereSQL['approved'] = 'ue.approved = 1';
         }
         if (!$params->get('list_show_unconfirmed', 0)) {
             $tablesWhereSQL['confirmed'] = 'ue.confirmed = 1';
         }
     } else {
         $tablesWhereSQL = array('block' => 'u.block = 0', 'approved' => 'ue.approved = 1', 'confirmed' => 'ue.confirmed = 1', 'banned' => 'ue.banned = 0');
     }
     $joinsSQL[] = 'JOIN #__user_usergroup_map g ON g.`user_id` = u.`id`';
     if ($userGroupIds) {
         $tablesWhereSQL['gid'] = 'g.group_id IN ' . $_CB_database->safeArrayOfIntegers($userGroupIds);
     }
     foreach ($tableReferences as $table => $name) {
         if ($name == 'u') {
             $tablesSQL[] = $table . ' ' . $name;
         } else {
             $joinsSQL[] = 'JOIN ' . $table . ' ' . $name . ' ON ' . $name . '.`id` = u.`id`';
         }
     }
     // Build the search criteria:
     $searchValues = new stdClass();
     $searchesFromFields = $tabs->applySearchableContents($searchableFields, $searchValues, $postData, $params->get('list_compare_types', 0));
     $whereFields = $searchesFromFields->reduceSqlFormula($tableReferences, $joinsSQL, true);
     if ($whereFields) {
         $tablesWhereSQL[] = '(' . $whereFields . ')';
     }
     $_PLUGINS->trigger('onBeforeUsersListBuildQuery', array(&$tablesSQL, &$joinsSQL, &$tablesWhereSQL));
     // Construct the FROM and WHERE for the userlist query:
     $queryFrom = "FROM " . implode(', ', $tablesSQL) . (count($joinsSQL) ? "\n " . implode("\n ", $joinsSQL) : '') . "\n WHERE " . implode("\n AND ", $tablesWhereSQL) . " " . $filterBy;
     $_PLUGINS->trigger('onBeforeUsersListQuery', array(&$queryFrom, 1, $listId));
     // $ui = 1 (frontend)
     $errorMsg = null;
     // Checks if the list is being actively searched and it allows searching; otherwise reset back to normal:
     $searchCount = count(get_object_vars($searchValues));
     if ($params->get('list_search', 1) > 0 && $params->get('list_search_empty', 0) && !$searchCount) {
         $searchMode = 1;
         $listAll = false;
     } else {
         $listAll = $searchCount ? true : false;
     }
     if ($searchMode == 0 || $searchMode == 1 && $searchCount || $searchMode == 2) {
         // Prepare the userlist count query for pagination:
         $_CB_database->setQuery("SELECT COUNT( DISTINCT u.id ) " . $queryFrom);
         $total = $_CB_database->loadResult();
         if ($limit > $total || $limitstart >= $total) {
             $limitstart = 0;
         }
         // Prepare the actual userlist query to build a list of users:
         $query = "SELECT DISTINCT ue.*, u.*, '' AS 'NA' " . ($fieldsSQL ? ", " . $fieldsSQL . " " : '') . $queryFrom . " " . $orderBy;
         $_CB_database->setQuery($query, (int) $limitstart, (int) $limit);
         /** @var UserTable[] $users */
         $users = $_CB_database->loadObjectList(null, '\\CB\\Database\\Table\\UserTable', array($_CB_database));
         if (!$_CB_database->getErrorNum()) {
             $profileLink = $params->get('allow_profilelink', 1);
             // If users exist lets cache them and disable profile linking if necessary:
             if ($users) {
                 foreach (array_keys($users) as $k) {
                     // Add this user to cache:
                     CBuser::setUserGetCBUserInstance($users[$k]);
                     if (!$profileLink) {
                         $users[$k]->set('_allowProfileLink', 0);
                     }
                 }
             }
         } else {
             $errorMsg = CBTxt::T('UE_ERROR_IN_QUERY_TURN_SITE_DEBUG_ON_TO_VIEW', 'There is an error in the database query. Site admin can turn site debug to on to view and fix the query.');
         }
         if ($searchCount) {
             $search = '';
         } else {
             $search = null;
         }
         if ($search === null && ($searchMode == 1 && $searchCount || $searchMode == 2)) {
             $search = '';
         }
     } else {
         $total = 0;
         $users = array();
         if ($search === null) {
             $search = '';
         }
     }
     $pageNav = new cbPageNav($total, $limitstart, $limit);
     HTML_comprofiler::usersList($row, $users, $columns, $fields, $input, $search, $searchMode, $pageNav, $user, $searchableFields, $searchValues, $tabs, $errorMsg, $listAll, $random);
 }