<?php
	class userController extends mainController {

		function __construct() {
			parent::__construct();

			//To change for every Controller
			$this->viewDir = 'User';

			//$this->allow = [];
		}

		//Profile (Edit Profile) page
		public function index($args=null) {

			if (!$this->user->isLogged()) {
				return $this->redirect('login', 'permissionDenied');
			}

			$supportedLanguages = $this->locale->getLanguages();
			$languagesList = [];
			$userDataSession = $this->user->getUser(); //Get current user's data in session
			$userDataDB = $this->user->getUserDB();
			$userDefaultLanguage = '';
			$userAltLangs = [];
			$userRoles = [];

			if ((is_array($userDataDB) && !empty($userDataDB)) && (is_array($userDataSession) && !empty($userDataSession))) {
				$userDefaultLanguage = $userDataDB['language_default'];
				$userAltLangs = $this->user->getUserAltLangsDB();
				$userRoles = $userDataSession['userRoles'];
			}

			//Get all supported languages and select user's default language
			foreach($supportedLanguages as $index => $languages) {
				$selected = $userDefaultLanguage == $languages['lang_code'] ? true : false;
				$languagesList[$index] = $languages;
				$languagesList[$index]['selected'] = $selected;
			}

			$this->view->languageList = $languagesList;

			$alternativeLanguages = [];
			foreach($supportedLanguages as $index => $languages) {
				//if ($languages['lang_code'] != $userDefaultLanguage) {
					$alternativeLanguages[$index] = $languages;
					$alternativeLanguages[$index]['checked'] = isset($userAltLangs[$languages['id']]) ? true : false;
				//}
			}

			$this->view->userUpdatedAt = $userDataDB['updated_at'];
			$this->view->userEmail = trim($userDataDB['email']);
			$this->view->userAltEmail = trim($userDataDB['alternative_email']);
			$this->view->userRemarks = trim($userDataDB['remarks_public']);
			$this->view->userMobNumber = trim($userDataDB['mobile_number']);
			$this->view->userMobWA = trim($userDataDB['mobile_number_chat']);
			$this->view->userPhoneText = trim($userDataDB['allow_phone_text']);
			$this->view->userPhoneChat = trim($userDataDB['allow_phone_chat']);
			$this->view->userEmailMsgs = trim($userDataDB['allow_email_msgs']);
			$this->view->countries = $this->locale->getCountriesByISO2Code($userDataDB['country_code']);
			//$this->view->phoneCodes = $this->locale->getPhoneCodes();
			$this->view->alternativeLanguages = $alternativeLanguages;
			$this->view->userAvatar = $this->user->getAvatar();
			$this->view->hasAvatar = $this->user->hasAvatar();

			//$this->view->roles = $this->user->getRoleList(); <-- Deprecated

			$this->actionTitle = _('Profile');
			$this->breadcrumbs = [['hash'=>null, 'label'=>$this->actionTitle]];

			return $this->setJsonView('index');
		}

		//Save/Edit profile information
		public function editProfile() {

			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'));
			}

			$data = isset($_POST['data']) ? $_POST['data'] : null;

			$validation = $this->validateForm($data);

			if (is_array($validation)) {
				return $this->setRawJsonResponse('err', $validation['msg'], ['class'=>$validation['class']]);
			}

			if ($validation === true) {

				$userId = $this->user->getUserId();
				$passwd1 = trim($data['profile_passwd1']['value']);
				$passwd2 = trim($data['profile_passwd2']['value']);

				$publicRemarks = trim(strip_tags($data['public_remarks']['value']));
				$pubRemarksSize = $this->config['settings']['public-remarks-size'];

				if (strlen($publicRemarks) > (int)$pubRemarksSize) {
					return $this->setRawJsonResponse('err', vsprintf(_('The Remarks text is too long. Maximun allowed size is %s characters.'), $pubRemarksSize));
				}

				if ($userId !== false) {
					$updateAtDate = date('Y-m-d H:i:s');
					$updateData = [
						'email' => $data['email']['value'],
						//'alternative_email' => $data['alt_email']['value'],
						'language_default' => $data['default_lang']['value'],
						'country_code' => $data['country']['value'],
						'remarks_public' => $publicRemarks,
						'mobile_number' => $data['default_mobile']['value'],
						'mobile_number_chat' => $data['mobile_chat']['value'],
						'allow_phone_text' => $data['phone_pref']['value'],
						'allow_phone_chat' => $data['wa_pref']['value'],
						'allow_email_msgs' => $data['wa_email']['value'],
						'updated_at' => $updateAtDate
					];

					if ($passwd1 != '') {
						if (!$this->security->validatePassword($passwd1)) {
							return $this->setRawJsonResponse('err', vsprintf(_('The password provided is not valid. The password must contain at least %s characters and at least 1 non-alphanumeric symbol (!, ?, -, etc.)'), [$this->security->passwordMinLength]), ['class'=>'field-passwd1']);
						}

						if ($passwd1 != $passwd2) {
							return $this->setRawJsonResponse('err', _('The password fields do not match.'), ['class'=>'field-passwd1']);
						}

						$updateData['password'] = md5($passwd1);
					}

					if ($this->db->where('id', $userId)->update('users', $updateData)) {

						if (isset($data['alt_langs']['value']) && is_array($data['alt_langs']['value']) && !empty($data['alt_langs']['value'])) {
							$this->db->where('user_id', $userId)->delete('users_languages_to');

							foreach($data['alt_langs']['value'] as $langId => $langCode) {
								$this->db->insert('users_languages_to', ['user_id'=>$userId, 'language_id'=>$langId]);
							}
						}

						//Refresh user's language in session
						$languageData = $this->db->where('lang_code', $data['default_lang']['value'])->getOne('users_languages');
						if (is_array($languageData) && !empty($languageData)) {
							if ($this->locale->filterValidLanguage($languageData['lang_code'])) {
								$this->user->refreshSessionField('userDefaultLang', $languageData['lang_code']);
							}

							$this->user->refreshSessionField('userDefaultString', $languageData['name_string']);
						}

						//Refresh last update field in user's session
						$this->user->refreshSessionField('userUpdatedAt', $updateAtDate);

						//Refresh country information in session
						$countryData = $this->db->where('country_iso2_code', $data['country']['value'])->getOne('countries');

						if (is_array($countryData) && !empty($countryData)) {
							$this->user->refreshSessionField('userCountryName', $countryData['country_name']);
							$this->user->refreshSessionField('userCountryCode', $countryData['country_iso2_code']);
							$this->user->refreshSessionField('userCountryId', $countryData['id']);
						}

						//Refresh the localised roles
						$localeRoles = $this->user->getUserRolesDB($userId);
						$roleList = [];
						if (is_array($localeRoles) && !empty($localeRoles)) {
							foreach($localeRoles as $roleId => $roleRow) {
								$roleList[$roleId] = $roleRow['role_names'];
							}
							$this->user->refreshSessionField('userRolesLocale', $roleList);
						}

						//Check for avatar file
						$file = isset($_FILES['data']) ? $_FILES['data']: null;

						//Update avatar
						if (is_array($file)) {
							if ((int)$file['error']['avatar']['value'] == 0) {
								$this->user->setAvatar($userId, $file['tmp_name']['avatar']['value']);
							}
						}

						//Check whether remove avatar or don't (without replacing it)
						if (isset($data['remove_avatar']['value'])) {
							if ((int)$data['remove_avatar']['value'] == 1) {
								$this->user->deleteAvatar($userId);
							}
						}

						return $this->setRawJsonResponse('ok', _('Profile information successfully updated.'), ['log'=>''], ['button'=>'refresh-page']);

					} else {
						return $this->setRawJsonResponse('err', _('Unable to update the profile right now. Please try again in a few minutes.').' (Err. cod. 0)');
					}

				} else {
					return $this->setRawJsonResponse('err', _('Incorrect user information, please log in again.'));
				}

				return $this->setRawJsonResponse('err', _('Unable to perform the request right now. Please try again in a few minutes.').' (Err. cod. 1)');
			}

			return $this->setRawJsonResponse('err', _('Unable to perform the request right now. Please try again in a few minutes.').' (Err. cod. 2)');
		}

		//Users list action
		public function usersList($args=null) {

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->redirect('login', 'permissionDenied');
			}

			$userGroupId = $this->user->getUserField('userGroupId');
			$groupInfo = $this->db->where('id', $userGroupId)->getOne('users_groups');
			//$this->view->groupName = isset($groupInfo['group_name']) ? $groupInfo['group_name'] : '';

			$this->view->currentPage = $this->getPost('pageNumb', 1);
			$this->view->orderField = $this->getPost('orderField', 'surname');
			$this->view->orderDir = $this->getPost('orderDir', 'desc');
			$this->view->roleSelectList = [];

			//$this->db->pageLimit = 3;

			if ($this->view->orderDir == 'asc')
				$dynOrderDir = 'desc';
			else
				$dynOrderDir = 'asc';

			//$this->view->strOutput = null;
			$searchData = $this->getPost('searchData');
			parse_str($searchData, $this->view->strOutput);

			//$totalRows = $this->db->where('group_id', $userGroupId)->getValue('users', 'COUNT(*)');

			$fields = [
			'users.id',
			'users.username',
			'users.surname',
			'users.name',
			'users.email',
			'users.updated_at',
			'users.created_at',
			"(SELECT GROUP_CONCAT(GET_JSON_VALUE_BY_KEY(ur.name_translations, '".$this->user->getUserLang()."', '".$this->defLang."') SEPARATOR ', ') AS role_string FROM users_roles_to AS urt JOIN users_roles AS ur ON ur.id=urt.role_id WHERE urt.user_id = users.id GROUP BY urt.user_id ORDER BY role_string) AS roles",
			'users.status'
			];

			$this->db->where('group_id', $userGroupId);

			if (isset($this->view->strOutput['search']['username'])) {
				$keyword = $this->view->strOutput['search']['username'];
				$this->db->where('users.username', "%$keyword%", 'like');
			}

			if (isset($this->view->strOutput['search']['surname'])) {
				$keyword = $this->view->strOutput['search']['surname'];
				$this->db->where('users.surname', "%$keyword%", 'like');
			}

			if (isset($this->view->strOutput['search']['name'])) {
				$keyword = $this->view->strOutput['search']['name'];
				$this->db->where('users.name', "%$keyword%", 'like');
			}

			if (isset($this->view->strOutput['search']['email'])) {
				$keyword = $this->view->strOutput['search']['email'];
				$this->db->where('users.email', "%$keyword%", 'like');
			}

			$roleKeyword = '';
			if (isset($this->view->strOutput['search']['roles']) && trim($this->view->strOutput['search']['roles']) != '') {
				$roleKeyword = $this->view->strOutput['search']['roles'];
				$fields[] = "(SELECT COUNT(*) FROM users_roles_to WHERE users_roles_to.user_id=users.id AND users_roles_to.role_id = $roleKeyword) AS total_user_roles";
				$this->db->having('total_user_roles', 0, '>');
			}

			$this->db->orderBy($this->view->orderField, $dynOrderDir);
			$this->view->usersList = $this->db->paginate('users', $this->view->currentPage, $fields);
			//
			$this->view->getTotUsers =  $this->db->totalUsers;
			$this->view->getTotRoles =  $this->db->TotUsersRoles;
			// Max Add Roles for Users
			$this->view->getMaxAddRoles = $this->db->MaxAddRoles;
			// Max type Roles
			$this->view->getMaxAddAdmins = $this->db->MaxAddAdmins;
			$this->view->getMaxAddModerators = $this->db->MaxAddModerators;
			$this->view->getMaxAddRequesters = $this->db->MaxAddRequesters;
			$this->view->getMaxAddResponders = $this->db->MaxAddResponders;
			$this->view->getMaxAddGuests = $this->db->MaxAddGuests;
			//Total Roles for Users
			$this->view->getTotAdmins = $this->db->TotAdmins;
			$this->view->getTotModerators = $this->db->TotModerators;
			$this->view->getTotRequesters = $this->db->TotRequesters;
			$this->view->getTotResponders = $this->db->TotResponders;
			$this->view->getTotGuests = $this->db->TotGuests;

			// USER ROLES
			$this->view->getUserHasRoles = 111;

			$this->setPagination($this->db, $this->db->totalCount, $this->view->currentPage, 'users/'.time().'/'.$this->view->orderField.'/'.$this->view->orderDir);

			$this->view->lastQuery = $this->db->getLastQuery();

			//Selected list	for column filter
			$roleSelectList = $this->user->getRoles();
			$this->view->roleSelectList = [];

			foreach($roleSelectList as $roleId => $role) {
				$this->view->roleSelectList[$roleId]['value'] = $roleId;
				$this->view->roleSelectList[$roleId]['name'] = $role;
				$this->view->roleSelectList[$roleId]['selected'] = $roleKeyword == $roleId ? true : false;
			}

			$this->actionTitle = _('Users');
			$this->breadcrumbs = [['hash'=>null, 'label'=>$this->actionTitle]];
			$this->view->editLinkHash = 'users-edit/'.time().'/%s/'.$this->view->orderField.'/'.$this->view->orderDir.'/'.$this->view->currentPage;
			return $this->setJsonView('usersList');
		}

		//Users add/edit action (view)
		public function usersEdit($args=null) {

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->redirect('login', 'permissionDenied');
			}

			//Needed by "Home" breadcrumbs' link
			$page = $this->getPost('pageNumb', 1);
			$orderField = $this->getPost('orderField', 'surname');
			$orderDir = $this->getPost('orderDir', 'desc');

			$userId = $this->getPost('userId', 0);

			//Check whether the current logged user is the current editing user
			$this->view->isSelf = $userId == $this->user->getUserId() ? true : false;

			$this->view->userId = $userId;
			$this->view->userData = [];
			$this->view->supportedLanguages = $this->locale->getLanguages();
			$this->view->userAltLanguages = $this->view->supportedLanguages;
			$this->view->roles = [];
			$this->view->countries = $this->locale->getCountriesByISO2Code();
			$this->view->clinicalCenterCountries = $this->getClinicalCenterCountries(true); //true = group by continent
			$this->view->clinicalCenters = $this->db->where('group_id', $this->userGroupId)->orderBy('description', 'asc')->get('clinical_centers');
			$this->view->medicalSpecialties = $this->db->orderBy('description', 'asc')->get('users_medical_specialties');

			//Default values
			$this->view->userClinicalCenters[APPLICANT_ROLE_ID] = 0;
			$this->view->userClinicalCenters[REFERRER_ROLE_ID] = 0;
			$this->view->userClinicalCenters[MODERATOR_ROLE_ID] = 0;
			$this->view->userClinicalCenters[GUEST_ROLE_ID] = 0;
			$roleForClinicalCenters = [];
			$this->view->responderStructure = [];

			$this->view->userMedicalSpecialties = [];
			$this->view->userAvatar = $this->user->getDefaultAvatar();
			$this->view->hasAvatar = false;

			// Max type Roles
			$this->view->getMaxAddAdmins = $this->db->MaxAddAdmins;
			$this->view->getMaxAddModerators = $this->db->MaxAddModerators;
			$this->view->getMaxAddRequesters = $this->db->MaxAddRequesters;
			$this->view->getMaxAddResponders = $this->db->MaxAddResponders;
			$this->view->getMaxAddGuests = $this->db->MaxAddGuests;
			//Total Roles for Users
			$this->view->getTotAdmins = $this->db->TotAdmins;
			$this->view->getTotModerators = $this->db->TotModerators;
			$this->view->getTotRequesters = $this->db->TotRequesters;
			$this->view->getTotResponders = $this->db->TotResponders;
			$this->view->getTotGuests = $this->db->TotGuests;

			// USER ROLES
			$this->view->getUserHasRoles = $this->user->getUserRolesDB($userId);

			$userRoles = $userId > 0 ? $this->user->getUserRolesDB($userId) : [];
			$supportedRoles = $this->user->getRoles(); //All roles
			$responderStructure = $this->db->orderBy('description', 'asc')->get('users_structures');
			//$thid->view->responderStructure = $responderStructure;

			//Check the user roles for the Clinical Centers
			$roleForClinicalCenters = [];

			if (is_array($supportedRoles)) {
				$c = 0;
				foreach($supportedRoles as $roleId => $role) {

					//Get the checked roles based on all supported roles (if true, that role id has been checked)
					//$supportedRoles[$c]['checked'] = isset($userRoles[$roleId]) ? true : false;

					$this->view->roles[$c]['id'] = $roleId;
					$this->view->roles[$c]['name'] = $role;
					$this->view->roles[$c]['checked'] = isset($userRoles[$roleId]) ? true : false;

					//Assign the roles for select the relative Clinical Centers
					if ($this->view->roles[$c]['checked']) {

						if ($roleId == APPLICANT_ROLE_ID) {
							$roleForClinicalCenters[APPLICANT_ROLE_ID] = APPLICANT_ROLE_ID; //Change the default value 0
						}

						if ($roleId == REFERRER_ROLE_ID) {
							$roleForClinicalCenters[REFERRER_ROLE_ID] = REFERRER_ROLE_ID; //Change the default value 0
						}

						if ($roleId == MODERATOR_ROLE_ID) {
							$roleForClinicalCenters[MODERATOR_ROLE_ID] = MODERATOR_ROLE_ID; //Change the default value 0
						}

						if ($roleId == GUEST_ROLE_ID) {
							$roleForClinicalCenters[GUEST_ROLE_ID] = GUEST_ROLE_ID; //Change the default value 0
						}
						
						if ($roleId == GLOBAL_MANAGER_ID) {
							$roleForClinicalCenters[GLOBAL_MANAGER_ID] = GLOBAL_MANAGER_ID; //Change the default value 0
						}
						
						if ($roleId == MANAGER_ID) {
							$roleForClinicalCenters[MANAGER_ID] = MANAGER_ID; //Change the default value 0
						}
					}

					$c++;
				}

				//$this->view->roles = $supportedRoles;
			}


			//Default avatar image
			$this->view->userAvatarImage = $this->user->getDefaultAvatar();

			if ((int)$userId > 0) {

				$this->view->userData = $this->db->where('id', $userId)->getOne('users');
				$this->view->userData['language_default'] = isset($this->view->userData['language_default']) ? $this->convertOldUserLang($this->view->userData['language_default']) : '';

				//Set the current user avatar image
				$this->view->userAvatarImage = $this->user->getAvatar($userId);

				$userAltLangs = $this->user->getUserAltLangsDB($userId);

				foreach($this->view->supportedLanguages as $index => $language) {

					//Select the user's default language in the select box
					$this->view->supportedLanguages[$index]['selected'] = ($this->view->userData['language_default'] == $language['lang_code']) ? true : false;

					//Check all languages known by the user
					$this->view->supportedLanguages[$index]['checked'] = isset($userAltLangs[$language['id']]) ? true : false;
				}

				//Set the alternative language array and remove the user's default language
				$this->view->userAltLanguages = $this->view->supportedLanguages;

				foreach($this->view->userAltLanguages as $index => $language) {
					if ($language['lang_code'] == $this->view->userData['language_default']) {
						unset($this->view->userAltLanguages[$index]);
						break;
					}
				}

				//If the user is Applicant, search the Clinical Center assigned as Applicant
				if (isset($roleForClinicalCenters[APPLICANT_ROLE_ID]) && $roleForClinicalCenters[APPLICANT_ROLE_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[APPLICANT_ROLE_ID] = $this->getUserClinicalCenters($userId, APPLICANT_ROLE_ID);
				} else {
					$this->view->userClinicalCenters[APPLICANT_ROLE_ID] = [];
				}

				//If the user is Referrer, search the Clinical Center assigned as Referrer
				if (isset($roleForClinicalCenters[REFERRER_ROLE_ID]) && $roleForClinicalCenters[REFERRER_ROLE_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[REFERRER_ROLE_ID] = $this->getUserClinicalCenters($userId, REFERRER_ROLE_ID);
				} else {
					$this->view->userClinicalCenters[REFERRER_ROLE_ID] = [];
				}

				//If the user is Moderator, search the Clinical Center assigned as Moderator
				if (isset($roleForClinicalCenters[MODERATOR_ROLE_ID]) && $roleForClinicalCenters[MODERATOR_ROLE_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[MODERATOR_ROLE_ID] = $this->getUserClinicalCenters($userId, MODERATOR_ROLE_ID);
				} else {
					$this->view->userClinicalCenters[MODERATOR_ROLE_ID] = [];
				}

				//If the user is Guest, search the Clinical Center assigned as Guest
				if (isset($roleForClinicalCenters[GUEST_ROLE_ID]) && $roleForClinicalCenters[GUEST_ROLE_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[GUEST_ROLE_ID] = $this->getUserClinicalCenters($userId, GUEST_ROLE_ID);
				} else {
					$this->view->userClinicalCenters[GUEST_ROLE_ID] = [];
				}
				
				//If the user is Manager, search the Clinical Center assigned as Manager
				if (isset($roleForClinicalCenters[MANAGER_ID]) && $roleForClinicalCenters[MANAGER_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[MANAGER_ID] = $this->getUserClinicalCenters($userId, MANAGER_ID);
				} else {
					$this->view->userClinicalCenters[MANAGER_ID] = [];
				}
				
				//If the user is Global Manager, search the Clinical Center assigned as Global Manager
				if (isset($roleForClinicalCenters[GLOBAL_MANAGER_ID]) && $roleForClinicalCenters[GLOBAL_MANAGER_ID] > 0) {
					//The method is in mainController
					$this->view->userClinicalCenters[GLOBAL_MANAGER_ID] = $this->getUserClinicalCenters($userId, GLOBAL_MANAGER_ID);
				} else {
					$this->view->userClinicalCenters[GLOBAL_MANAGER_ID] = [];
				}

				//Method is in mainController
				$this->view->userMedicalSpecialties = $this->getUserMedicalSpecialties($userId);

				$this->view->userAvatar = $this->user->getAvatar($userId);
				$this->view->hasAvatar = $this->user->hasAvatar($userId);
			}

			$this->actionTitle = $userId==0 ? _('User : Add') : _('User : Edit');
			$this->breadcrumbs = [['hash'=>'users/'.time().'/'.$orderField.'/'.$orderDir.'/'.$page, 'label'=>_('Users')], ['hash'=>null, 'label'=>$this->actionTitle]];


			return $this->setJsonView('usersEdit');
		}

		//Users add/edit action (save/update)
		public function usersSave() {
			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'), [], ['button'=>'login']);
			}

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->setRawJsonResponse('err', _('Permission denied.'));
			}

			$data = isset($_POST['data']) ? $_POST['data'] : null;
			$file = isset($_FILES['data']) ? $_FILES['data']: null;

			//return $this->setRawJsonResponse('err', json_encode($data['med_specialties']['value']));

			//Check required values
			$validation = $this->validateForm($data);

			if (is_array($validation)) {
				return $this->setRawJsonResponse('err', $validation['msg'], ['class'=>$validation['class']]);
			}

			if ($validation === true) {
				$userId = (int)$data['user_id']['value'];
				$isSelf = $userId == $this->user->getUserId() ? true : false;
				$isEditing = $userId > 0 ? true : false; //Editing or Saving?

				//Check username
				$isUsernameInUse = $this->user->isUsernameInUse(trim($data['username']['value']));
				if (!$isEditing && $isUsernameInUse) {
					return $this->setRawJsonResponse('err', _('The Username provided is already in use.'));
				}

				$passwd1 = trim($data['profile_passwd1']['value']);
				$passwd2 = trim($data['profile_passwd2']['value']);

				//Check roles number
				if (!isset($data['role']) || !is_array($data['role'])) {
					return $this->setRawJsonResponse('err', _('Please provide at least one role.'));
				}

				//Check if current logged user is an administrator and Administrator role checkbox is unchecked
				if ($isSelf && $this->user->is(ADMIN_ROLE_ID)) {
					if (!isset($data['role']['value'][ADMIN_ROLE_ID])) {
						return $this->setRawJsonResponse('err', _('You cannot downgrade your Administrator role.'));
					}
				}

				$userStatus = isset($data['status']['value']) ? $data['status']['value'] : 0;

				if (isset($data['role']['value'][ADMIN_ROLE_ID])) {
					if ($userStatus == STATUS_TECH_ID) {
						return $this->setRawJsonResponse('err', _("The user status selected doesn't allow to add the Administrator role."));
					}
				}

				//Roles are ok, check the data related to the roles
				if (is_array($data['role']['value'])) {

					//User is a Referrer
					if (isset($data['role']['value'][REFERRER_ROLE_ID])) {

						//Check Medical specialties
						if (!isset($data['med_specialties']['value']) || empty($data['med_specialties']['value'])) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Medical specialty for this user.'));
						}

						//Check Clinical centers
						if (!isset($data['cc_referrer']['value']) || empty($data['cc_referrer']['value'])) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Responder) for this user.'));
						}
					}

					//User is Applicant
					if (isset($data['role']['value'][APPLICANT_ROLE_ID])) {
						//Check Clinical centers
						if (!isset($data['cc_applicant']['value']) || empty($data['cc_applicant']['value'])) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Requester) for this user.'));
						}
					}

					//User is Moderator
					if (isset($data['role']['value'][MODERATOR_ROLE_ID])) {
						//Check Clinical centers
						if (!isset($data['cc_moderator']['value']) || empty($data['cc_moderator']['value'])) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Moderator) for this user.'));
						}
					}

					//User is Guest
					if (isset($data['role']['value'][GUEST_ROLE_ID])) {
						//Check Clinical centers
						if (!isset($data['cc_guest']['value']) || empty($data['cc_guest']['value'])) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Guest) for this user.'));
						}
					}
					
					if (isset($data['role']['value'][GLOBAL_MANAGER_ID])) {
						//Check Clinical centers
						if (!isset($data['cc_global_manager']['value'][0]) || (int)$data['cc_global_manager']['value'][0] == 0) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Global Manager) for this user.'));
						}
					}
					
					if (isset($data['role']['value'][MANAGER_ID])) {
						//Check Clinical centers
						if (!isset($data['cc_manager']['value'][0]) || (int)$data['cc_manager']['value'][0] == 0) {
							return $this->setRawJsonResponse('err', _('Please provide at least one Clinical Center (Manager) for this user.'));
						}
					}

				}

				$publicRemarks = trim(strip_tags($data['public_remarks']['value']));
				$pubRemarksSize = $this->config['settings']['public-remarks-size'];

				if (strlen($publicRemarks) > (int)$pubRemarksSize) {
					return $this->setRawJsonResponse('err', vsprintf(_('The Public Remarks text is too long. Maximun allowed size is %s characters.'), $pubRemarksSize));
				}

				$insertData = [
					'group_id' => $this->userGroupId,
					'username' => trim($data['username']['value']),
					'language_default' => $data['default_lang']['value'],
					'remarks_public' => $publicRemarks,
					'remarks_private' => trim($data['private_remarks']['value']),
					'name' => trim($data['name']['value']),
					'surname' => trim($data['surname']['value']),
					//'fiscal_code' => trim($data['fiscal_code']['value']),
					// BIRTH
					//'birth_date' => trim($data['birth_date']['value']),
					//'city_birth' => trim($data['city_birth']['value']),
					//'province_birth' => trim($data['province_birth']['value']),
					// RESIDENCE
					//'residence_province' => trim($data['residence_province']['value']),
					//'residence_city' => trim($data['residence_city']['value']),
					//'residence_address' => trim($data['residence_address']['value']),
					// DOMICILE
					//'domicile_province' => trim($data['domicile_province']['value']),
					//'domicile_city' => trim($data['domicile_city']['value']),
					//'domicile_address' => trim($data['domicile_address']['value']),
					//'country_id' => $data['country']['value'],
					'country_code' => $data['country']['value'],
					'email' => trim($data['email']['value']),
					//'alternative_email' => trim($data['alt_email']['value']),
					'advanced_request' => $data['advanced_request']['value'],
					'mobile_number' => trim($data['default_mobile']['value']),
					'mobile_number_chat' => trim($data['mobile_chat']['value']),
					'allow_phone_text' => $data['phone_pref']['value'],
					'allow_phone_chat' => $data['wa_pref']['value'],
					'allow_email_msgs' => $data['email_pref']['value']
				];

				//Change the status (if this user is not the current logged user)
				if (!$isSelf) {
					/*if (isset($data['status']['value'])) {
						$insertData['status'] = $data['status']['value'];
					}*/

					$insertData['status'] = $userStatus;
				}

				//Check passwords
				$passwd1 = trim($data['profile_passwd1']['value']);
				$passwd2 = trim($data['profile_passwd2']['value']);

				if ($passwd1 != '') {
					if (!$this->security->validatePassword($passwd1)) {
						return $this->setRawJsonResponse('err', vsprintf(_('The password provided is not valid. The password must contain at least %s characters and at least 1 non-alphanumeric symbol (!, ?, -, etc.)'), [$this->security->passwordMinLength]));
					}

					if ($passwd1 != $passwd2) {
						return $this->setRawJsonResponse('err', _('The password fields do not match.'));
					}

					$insertData['password'] = md5($passwd1);
				}

				/*if ($this->user->getUserStatus() == STATUS_TECH_ID) {
					return $this->setRawJsonResponse('ok', _('All fields have been correctly validated. The current user cannot save the new information.'));
				}*/

				$updatedAtDate = date('Y-m-d H:i:s'); //Also used to refresh the current user session
				if ($userId > 0) { //Update

					$insertData['updated_at'] = $updatedAtDate;
					$this->db->where('id', $userId);
					if (!$this->db->update('users', $insertData)) {
						$this->logger->logUserAction($this->user->getUserId(), "UPDATE USER ERROR", $this->db->getLastError());
						return $this->setRawJsonResponse('err', $this->db->getLastError());
					}
					$this->logger->logUserAction($this->user->getUserId(), "UPDATE USER $userId");
				} else { //Insert

					$insertData['created_at'] = $updatedAtDate;
					$insertData['updated_at'] = $updatedAtDate;

					$insertId = $this->db->insert('users', $insertData);
					if ($insertId) {
						$userId = $insertId;
						$this->logger->logUserAction($this->user->getUserId(), "INSERT USER $userId");
					} else {
						$this->logger->logUserAction($this->user->getUserId(), "INSERT USER ERROR", $this->db->getLastError());
						return $this->setRawJsonResponse('err', $this->db->getLastError());
					}
				}

				//Updating or inserting ok
				if ($userId > 0) {

					$userIsSelf = $userId == $this->user->getUserId() ? true : false;
					$userDisplayName = $this->user->setDisplayName(['userName'=>trim($data['name']['value']), 'userSurname'=>trim($data['surname']['value'])]);



					//Update the Medical spacialties
					$this->db->where('user_id', $userId)->delete('users_medical_specialties_to');
					if (isset($data['med_specialties']['value'])) {
						$medSpecialties = $data['med_specialties']['value'];

						if (is_array($medSpecialties) && !empty($medSpecialties)) {

							foreach($medSpecialties as $specialityId) {
								$this->db->insert('users_medical_specialties_to', ['user_id'=>$userId, 'specialty_id'=>$specialityId]);
							}

							$this->memoryCache->remove('medical:specialties:'.$userId);

							/*$this->db->where('user_id', $userId);
							if ($this->db->delete('users_medical_specialties_to')) {
								foreach($medSpecialties as $specialityId) {
									$this->db->insert('users_medical_specialties_to', ['user_id'=>$userId, 'specialty_id'=>$specialityId]);
								}

								$this->memoryCache->remove('medical:specialties:'.$userId);
							}*/
						}
					} else {
						$this->memoryCache->remove('medical:specialties:'.$userId);
					}

					//Update Clinical Center for these roles
					$checkRoles = [REFERRER_ROLE_ID, APPLICANT_ROLE_ID, MODERATOR_ROLE_ID, GUEST_ROLE_ID, MANAGER_ID, GLOBAL_MANAGER_ID];

					
					//return $this->setRawJsonResponse('err', json_encode($data['cc_manager']['value']));
					
					//Loop the roles
					foreach($checkRoles as $checkRole) {

						switch($checkRole) {
							case REFERRER_ROLE_ID:
							$fieldName = 'cc_referrer';
							break;

							case APPLICANT_ROLE_ID:
							$fieldName = 'cc_applicant';
							break;

							case MODERATOR_ROLE_ID:
							$fieldName = 'cc_moderator';
							break;

							case GUEST_ROLE_ID:
							$fieldName = 'cc_guest';
							break;
							
							case GLOBAL_MANAGER_ID:
							$fieldName = 'cc_global_manager';
							break;
							
							case MANAGER_ID:
							$fieldName = 'cc_manager';
							break;
						}

						//Check whether this role is checked
						if (isset($data['role']['value'][$checkRole])) {

							//Check if field data exist in POST request
							if (isset($data[$fieldName]['value'])) {

								//Take the center id values (array)
								$centerIDs = $data[$fieldName]['value'];

								//Check if there are clinical center ids
								if (is_array($centerIDs) && !empty($centerIDs)) {

									//Clean the relationship without assigned role id (role_id = 0)
									$this->db->where('user_id', $userId)->where('role_id', 0)->delete('users_clinical_centers_to');

									//Delete the previous clinical center <-> user/role relationship
									$this->db->where('user_id', $userId)->where('role_id', $checkRole)->delete('users_clinical_centers_to');

									//Add the new clinical center for this user and this role
									foreach($centerIDs as $centerId) {
										$this->db->insert('users_clinical_centers_to', ['user_id'=>$userId, 'center_id'=>$centerId, 'role_id'=>$checkRole]);
									}


								}

							}

						} else {
							//If the role is not checked, delete the corresponding clinical centers if exist
							$this->db->where('user_id', $userId)->where('role_id', 0)->delete('users_clinical_centers_to');
							$this->db->where('user_id', $userId)->where('role_id', $checkRole)->delete('users_clinical_centers_to');
						}

						//Delete the keys in cache
						$this->memoryCache->remove('clinical:center:'.$userId.':'.$checkRole);
						$this->memoryCache->remove('clinical:center:'.$userId.':0');

					}

					//Update the selected roles
					$checkedRoles = $data['role']['value'];

					//Clean the previuoses user/role relationships
					$this->db->where('user_id', $userId);

					if ($this->db->delete('users_roles_to')) {
						foreach($checkedRoles as $checkedRole) {
							$this->db->insert('users_roles_to', ['user_id'=>$userId, 'role_id'=>$checkedRole]);
						}
					}

					//Update alternative languages
					if (isset($data['alt_langs']['value']) && is_array($data['alt_langs']['value'])) {
						$checkedAltLangs = $data['alt_langs']['value'];

						//Clean previouse user/languages relationship
						$this->db->where('user_id', $userId);
						if ($this->db->delete('users_languages_to')) {
							foreach($checkedAltLangs as $checkedAltLang) {
								$this->db->insert('users_languages_to', ['user_id'=>$userId, 'language_id'=>$checkedAltLang]);
							}
						}
					}

					//Update avatar
					if (is_array($file)) {
						if ((int)$file['error']['avatar']['value'] == 0) {
							$this->user->setAvatar($userId, $file['tmp_name']['avatar']['value']);
						}
					}

					//Check whether remove avatar or don't (without replacing it)
					if (isset($data['remove_avatar']['value'])) {
						if ((int)$data['remove_avatar']['value'] == 1) {
							$this->user->deleteAvatar($userId);
						}
					}

					//Delete user session
					if (!$isSelf) {
						$this->user->removeAllUserSessionRecords($userId);
					} else {
						$countryData = $this->db->where('country_iso2_code', $data['country']['value'])->getOne('countries');
						$languageData = $this->db->where('lang_code', $data['default_lang']['value'])->getOne('users_languages');
						$this->user->refreshUserSession([
							'id'=>$userId,
							'username'=>trim($data['username']['value']),
							'name'=>trim($data['name']['value']),
							'surname'=>trim($data['surname']['value']),
							'language_default'=>$data['default_lang']['value'],
							'roles'=>$this->user->getUserRolesDB($userId),
							'country_data'=> is_array($countryData) ? $countryData : [],
							'language_data'=> is_array($languageData) ? $languageData : [],
							'updated_at'=>$updatedAtDate,
							'group_id'=>$this->userGroupId
						]);
					}

					$jsPopupButton = $isEditing ? 'refresh-hash' : 'refresh-user-edit';
					return $this->setRawJsonResponse('ok', _('User information successfully updated.'), [], ['userId'=>$userId, 'button'=>$jsPopupButton]);

				} else {
					return $this->setRawJsonResponse('err', _('An error occurred saving the data. Please try again in a few minutes.'));
				}
			} //validation
		}

		public function usersSearch() {
			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'), [], ['button'=>'login']);
			}

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->setRawJsonResponse('err', _('Permission denied.'));
			}

			$this->view->supportedLanguages = $this->locale->getLanguages();
			$this->view->countries = $this->locale->getCountriesByISO2Code();

			$clinicalCenters = $this->db->orderBy('description', 'asc')->get('clinical_centers');
			$this->view->clinicalCentersPerRole = [];
			$this->view->clinicalCenterCountries = $this->getClinicalCenterCountries(true); //true = group by continent

			//Array structure: role id => html select field name
			$checkCcRoles = [APPLICANT_ROLE_ID=>'cc_applicant', REFERRER_ROLE_ID=>'cc_referrer', MODERATOR_ROLE_ID=>'cc_moderator', GUEST_ROLE_ID=>'cc_guest'];
			$checkCcCountries = [APPLICANT_ROLE_ID=>'cn_applicant', REFERRER_ROLE_ID=>'cn_referrer', MODERATOR_ROLE_ID=>'cn_moderator', GUEST_ROLE_ID=>'cn_guest'];

			//Pass the role array to the view too
			$this->view->checkCcRoles = $checkCcRoles;
			$this->view->checkCcCountries = $checkCcCountries;
			$this->view->checkCcRolesLabels = [APPLICANT_ROLE_ID=>_('Requester'), REFERRER_ROLE_ID=>_('Responder'), MODERATOR_ROLE_ID=>_('Moderator'), GUEST_ROLE_ID=>_('Guest')];

			//Set the clinical center list for all roles
			foreach($checkCcRoles as $roleId => $roleField) {
				$this->view->clinicalCentersPerRole[$roleId] = $clinicalCenters;
			}

			$this->view->medicalSpecialties = $this->db->orderBy('description', 'asc')->get('users_medical_specialties');

			$supportedRoles = $this->user->getRoles();
			$c = 0;
			foreach($supportedRoles as $roleId => $roleName) {
				$this->view->supportedRoles[$c]['id'] = $roleId;
				$this->view->supportedRoles[$c]['name'] = $roleName;
				$c++;
			}

			$this->view->status = -1; //Default selected "All"

			$searchData = $this->getPost('searchData');

			if (!is_null($searchData)) {
				parse_str($searchData, $parsedData);
				$data = $parsedData['data'];

				if (is_null($data)) {
					$data = $this->memoryCache->read('user:search:'.$this->user->getUserId());
				}
			}

			//For debugging
			$this->view->searchData = $data;

			$this->view->isSearch = false;
			$this->view->results = [];
			$this->view->resultCount = 0;
			$this->view->tableHasCcApplicant = false;
			$this->view->tableHasCcReferrer = false;
			$this->view->tableHasSpecialties = false;

			if (!is_null($data)) {

				$this->view->isSearch = true;

				$this->memoryCache->write('user:search:'.$this->user->getUserId(), $data, '+10 years');

				$this->view->currentPage = $this->getPost('pageNumb', 1);
				$this->view->orderField = $this->getPost('orderField', 'surname');
				$this->view->orderDir = $this->getPost('orderDir', 'desc');

				$fields[] = "COUNT(u.id) AS total_users";

				$fields = ['u.id', 'u.name', 'u.surname', 'u.updated_at', "(SELECT  GROUP_CONCAT(GET_JSON_VALUE_BY_KEY(ur.name_translations, '".$this->user->getUserLang()."', '".$this->defLang."') SEPARATOR ', ') FROM users_roles_to rrt JOIN users_roles ur ON ur.id=rrt.role_id WHERE rrt.user_id=u.id ORDER BY ur.role_name) AS role_list"];

				if (isset($data['default_lang']) && $data['default_lang'] != '') {
					$this->db->where('u.language_default', $data['default_lang'], 'like');

					foreach($this->view->supportedLanguages as $index => $language) {
						$this->view->supportedLanguages[$index]['selected'] = $language['lang_code'] == $data['default_lang'] ? true : false;
					}
				}

				if (isset($data['country']) && $data['country'] != '') {
					$this->db->where('u.country_code', $data['country']);

					foreach($this->view->countries as $index => $country) {
						$this->view->countries[$index]['selected'] = $country['country_iso2_code'] == $data['country'] ? true : false;
					}
				}

				if (isset($data['status'])) {
					if ((int)$data['status'] > -1) {//-1 = Any
						$this->db->where('u.status', $data['status']);
					}
					$this->view->status = (int)$data['status'];
				}

				if (isset($data['role']) && is_array($data['role']) && !empty($data['role'])) {

					$c = 0;
					foreach($supportedRoles as $roleId => $roleName) {
						$this->view->supportedRoles[$c]['checked'] = isset($data['role'][$roleId]) ? true : false;
						$c++;
					}

					$this->view->tableHasRoles = true;

					$roleList = implode(',', $data['role']);
					$fields[] = "(SELECT COUNT(*) FROM users_roles_to urt WHERE urt.user_id=u.id AND urt.role_id IN($roleList)) AS role_results";
					$this->db->having('role_results', 0, '>');
				}

				$this->view->tableHasCcColumn = [];

				$countCC = 0;
				foreach($checkCcRoles as $roleId => $fieldName) {

					if (isset($data['role'][$roleId])) {

						$this->view->tableHasCcColumn[$roleId] = true;

						$filterForCount = "";
						$filterForList = "";

						if (isset($data[$fieldName]) && is_array($data[$fieldName]) && !empty($data[$fieldName])) {

							$ccRoleList = implode(',', $data[$fieldName]);
							$filterForCount = "AND ucct.center_id IN($ccRoleList)";
							$filterForList = "AND cc.id IN($ccRoleList)";

							foreach($this->view->clinicalCentersPerRole[$roleId] as $index => $ccItem) {
								$this->view->clinicalCentersPerRole[$roleId][$index]['selected'] = in_array($ccItem['id'], $data[$fieldName]) ? true : false;
							}

							//Count how many clinical centers are in this role and filter by the centers id
							$fields[] = "(SELECT COUNT(*) FROM users_clinical_centers_to ucct WHERE ucct.user_id=u.id AND ucct.role_id=$roleId $filterForCount) AS ".$fieldName."_results";

							//Create the clinical center comma separated list
							$fields[] = "(SELECT GROUP_CONCAT(cc.description SEPARATOR ', ') FROM users_clinical_centers_to ucct JOIN clinical_centers cc ON cc.id=ucct.center_id WHERE ucct.user_id=u.id $filterForList ORDER BY cc.description) AS ".$fieldName."_list";

							//If is the firs role, use having, if it isn't, use orHaving
							if ($countCC == 0) {
								$this->db->having($fieldName.'_results', 0, '>');
							} else {
								$this->db->orHaving($fieldName.'_results', 0, '>');
							}

						} else {
							//If there aren't clinical centers, just count how many centers are in this role
							$fields[] = "(SELECT COUNT(*) FROM users_clinical_centers_to ucct WHERE ucct.user_id=u.id AND ucct.role_id=$roleId $filterForCount) AS ".$fieldName."_results";

							//Create the clinical center comma separated list
							$fields[] = "(SELECT GROUP_CONCAT(cc.description SEPARATOR ', ') FROM users_clinical_centers_to ucct JOIN clinical_centers cc ON cc.id=ucct.center_id WHERE ucct.user_id=u.id AND ucct.role_id=$roleId $filterForList ORDER BY cc.description) AS ".$fieldName."_list";
						}

						$countCC++;

					} else {
						$this->view->tableHasCcColumn[$roleId] = false;
					}

				}

				if (isset($data['med_specialties']) && is_array($data['med_specialties']) && !empty($data['med_specialties'])) {

					$this->view->tableHasSpecialties = true;

					foreach($this->view->medicalSpecialties as $index => $specialtyItem) {
						$this->view->medicalSpecialties[$index]['selected'] = in_array($specialtyItem['id'], $data['med_specialties']) ? true : false;
					}

					$specialtyList = implode(',', $data['med_specialties']);
					$fields[] = "(SELECT COUNT(*) FROM users_medical_specialties_to umst WHERE umst.user_id=u.id AND umst.specialty_id IN($specialtyList)) AS specialty_result";

					$fields[] = "(SELECT GROUP_CONCAT(ms.description SEPARATOR ', ') FROM users_medical_specialties_to umst JOIN users_medical_specialties ms ON ms.id=umst.specialty_id WHERE umst.user_id=u.id ORDER BY ms.description) AS specialty_list";

					$this->db->having('specialty_result', 0, '>');
				}

				$this->db->where('u.group_id', $this->userGroupId);

				$this->view->results = $this->db->orderBy('u.surname', 'asc')->paginate('users u', $this->view->currentPage, $fields);

				$this->setPagination($this->db, $this->db->totalCount, $this->view->currentPage, 'users-search/'.time().'/'.$this->view->orderField.'/'.$this->view->orderDir);

				//$this->view->totalResults = $resultsTotal;
				//$this->view->queryDebug = $this->db->getLastQuery();
			}


			$this->actionTitle = _('Users : Search');
			$this->breadcrumbs = [['hash'=>'users/'.time().'/surname/desc/1', 'label'=>_('Users')], ['hash'=>null, 'label'=>$this->actionTitle]];

			return $this->setJsonView('usersSearch');
		}

		public function exportUsers() {
			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'), [], ['button'=>'login']);
			}

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->setRawJsonResponse('err', _('Permission denied.'));
			}


			$parsedData = null;
			$formData = $this->getPost('formData', null);
			parse_str($formData, $parsedData);
			$returnValues = [];
			$userNames = [];
			$exportedUsers = '';

			if (isset($parsedData['export_user_list'])) {

				foreach($parsedData['export_user_list'] as $userId) {
					$userInfo = $this->db
						->where('u.id', $userId)
						->where('urt.role_id', APPLICANT_ROLE_ID)
						->join('users_roles_to urt', 'urt.user_id=u.id', 'INNER')
						->getOne('users u', 'u.*');

					if (is_array($userInfo) && !empty($userInfo)) {
						$returnValues['users'][$userId] = $userInfo;
						$userNames[] = $userInfo['surname'].' '.$userInfo['name'];

						$userCc = $this->db
							->where('ucct.user_id', $userId)
							->join('clinical_centers cc', 'cc.id=ucct.center_id', 'INNER')
							->get('users_clinical_centers_to ucct', null, ['ucct.*']);
						if (is_array($userCc) && !empty($userCc)) {
							$returnValues['userCc'][$userId] = $userCc;
						}

						$userLangs = $this->db
							->where('ult.user_id', $userId)
							->get('users_languages_to ult');
						if (is_array($userLangs) && !empty($userLangs)) {
							$returnValues['userLangs'][$userId] = $userLangs;
						} else {
							$returnValues['userLangs'][$userId] = [];
						}

						//Set user's role
						$returnValues['userRole'][$userId] = ['user_id'=>$userId, 'role_id'=>APPLICANT_ROLE_ID];
					}
				}

				if (!empty($returnValues)) {
					$returnValues['cc'] = [];
					$returnValues['ccMs'] = [];
					$returnValues['ms'] = [];

					$clinicalCenter = $this->db->get('clinical_centers');
					if (is_array($clinicalCenter) && !empty($clinicalCenter)) {
						$returnValues['cc'] = $clinicalCenter;
					}

					$clinicalCenterMs = $this->db->get('clinical_center_medical_specialties_to');
					if (is_array($clinicalCenterMs) && !empty($clinicalCenterMs)) {
						$returnValues['ccMs'] = $clinicalCenterMs;
					}

					$medicalSpecialties = $this->db->get('users_medical_specialties');
					if (is_array($medicalSpecialties) && !empty($medicalSpecialties)) {
						$returnValues['ms'] = $medicalSpecialties;
					}

					$exportedUsers = implode(', ', $userNames);
				}

				if (!empty($returnValues)) {

					$tmpDir = DATA_TMP_DIR;
					$fileName = 'GHT-User-Export_'.date('YmdHis').'.ghtusr';
					$fileContent = gzcompress(json_encode($returnValues));
					$filePath = $tmpDir.$fileName;
					$ret = file_put_contents($filePath, $fileContent);

					if ($ret === false) {

						return $this->setRawJsonResponse('err', _('Unable to create the users file.'), [], ['log'=>$filePath]);

					} else {

						return $this->setRawJsonResponse('ok', '', ['log'=>$returnValues, 'dwnFileName'=>$fileName, 'dwnFilePath'=>$filePath]);

					}

				} else {
					return $this->setRawJsonResponse('err', _('Unable to export the selected users. Please check the users role.'));
				}


			} else {
				return $this->setRawJsonResponse('err', _('Please provide at least one user.'));
			}

		}

		public function searchClean() {
			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'), [], ['button'=>'login']);
			}

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->setRawJsonResponse('err', _('Permission denied.'));
			}

			$ret = $this->db->where('cache_key', 'user:search:'.$this->user->getUserId())->delete('cache_memory');

			return $this->setRawJsonResponse('ok', _('Search field successfully cleaned.'), ['log'=>$ret]);
		}

		public function getCCentersByCountries() {
			if (!$this->user->isLogged()) {
				return $this->setRawJsonResponse('err', _('Session expired, please log in again.'), [], ['button'=>'login']);
			}

			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->setRawJsonResponse('err', _('Permission denied.'));
			}

			$ids = isset($_POST['ids']) ? $_POST['ids'] : null;
			$selectAll = []; //Selected "All in this continent"
			$selectCountries = []; //Selected some other countries

			if (!is_null($ids)) {

				if(is_array($ids)) {

					foreach($ids as $countryCode) {
						if (strpos($countryCode, '|') !== false) {
							$selectAll[] = "'".explode('|', $countryCode)[1]."'";
						}  else {
							$selectCountries[] = "'".$countryCode."'";
						}
					}

					//Select all countries of these continents
					if (!empty($selectAll)) {
						$countryCodes = implode(',', $selectAll);
						$resultsAll = $this->db->where('continent_code IN('.$countryCodes.')')->get('clinical_centers', null, ['id']);
					}

					//Select all countries in this array
					if (!empty($selectCountries)) {
						$countryCodes = implode(',', $selectCountries);
						$resultsCountries = $this->db->where('country_code IN('.$countryCodes.')')->get('clinical_centers', null, ['id']);
					}

					//Merge and remove duplicates

					$allCcIds = [];

					if (is_array($resultsAll)) {
						foreach($resultsAll as $item) {
							$allCcIds[] = $item['id'];
						}
					}

					if (is_array($resultsCountries)) {
						foreach($resultsCountries as $item) {
							$allCcIds[] = $item['id'];
						}
					}

					$allIds = array_unique($allCcIds);

					return $this->setRawJsonResponse('ok', '', ['ids'=>$allCcIds]);

				}
			}

			//If the passed ids array is empty, clear the Clinical center list on the right side
			return $this->setRawJsonResponse('ok', '', ['ids'=>[]]);
		}

		//Users sessions action
		public function usersSessions() {
			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->redirect('login', 'permissionDenied');
			}

			$userGroupId = $this->user->getUserField('userGroupId');
			$groupInfo = $this->db->where('id', $userGroupId)->getOne('users_groups');
			$this->view->groupName = isset($groupInfo['group_name']) ? $groupInfo['group_name'] : '';

			$page = $this->getPost('pageNumb', 1);
			$totalRows = $this->db
				->join('users u', 'u.id=s.user_id', 'INNER')
				->where('s.user_id', 0, '>')
				->where('u.group_id', $userGroupId)
				->getValue('sessions s', 'COUNT(*)');

			$sessions = $this->db
				->join('users u', 'u.id=s.user_id', 'INNER')
				->where('s.user_id', 0, '>')
				->where('u.group_id', $userGroupId)
				->orderBy('s.session_updated_at', 'DESC')
				->paginate('sessions s', $page);

			$this->setPagination($this->db, $totalRows, $page, 'users-sessions');

			$this->view->sessions = $sessions;
			$this->actionTitle = _('Users : Sessions');
			$this->breadcrumbs = [['hash'=>null, 'label'=>$this->actionTitle]];

			return $this->setJsonView('usersSessions');
		}

		//Users access logs action
		public function usersAccessLogs() {
			if(!$this->checkPermissions([ADMIN_ROLE_ID])) {
				return $this->redirect('login', 'permissionDenied');
			}

			$userGroupId = $this->user->getUserField('userGroupId');
			$groupInfo = $this->db->where('id', $userGroupId)->getOne('users_groups');
			$this->view->groupName = isset($groupInfo['group_name']) ? $groupInfo['group_name'] : '';

			$page = $this->getPost('pageNumb', 1);
			$accesses = $this->db
				->join('users u', 'u.id=a.user_id', 'INNER')
				->where('a.user_id', 0, '>')
				->where('u.group_id', $userGroupId)
				->orderBy('a.created_at', 'DESC')
				->paginate('log_access a', $page, ['a.*', 'a.created_at AS access_date', 'u.id AS user_id', 'u.username', 'u.surname', 'u.name']);

			$totalRows = $this->db
				->join('users u', 'u.id=a.user_id', 'INNER')
				->where('a.user_id', 0, '>')
				->where('u.group_id', $userGroupId)
				->getValue('log_access a', 'COUNT(*)');

			$this->setPagination($this->db, $totalRows, $page, 'users-access-logs');

			$this->view->accesses = $accesses;
			$this->actionTitle = _('Users : Access logs');
			$this->breadcrumbs = [['hash'=>null, 'label'=>$this->actionTitle]];
			return $this->setJsonView('usersAccessLogs');
		}

		public function usersNotificationTracker() {
			if(!$this->checkPermissions([ADMIN_ROLE_ID, MODERATOR_ROLE_ID])) {
				return $this->redirect('login', 'permissionDenied');
			}

			$this->view->currentPage = $this->getPost('pageNumb', 1);
			$this->view->notifType = $this->getPost('notifType', 'email');
			//$this->view->orderField = $this->getPost('orderField', 'surname');
			//$this->view->orderDir = $this->getPost('orderDir', 'desc');
			$this->view->trackers = [];

			$results = $this->db
				->where('u.group_id', $this->userGroupId)
				->where('el.notif_type', $this->view->notifType)
				->join('users u', 'u.id=el.user_id', 'INNER')
				//->groupBy('el.id')
				->orderBy('el.created_at', 'desc')
				->paginate('log_notifications el', $this->view->currentPage, ['u.id user_id', 'u.name', 'u.surname', 'el.id mail_code',  'el.request_result', 'el.mail_to', 'el.mail_subject', 'el.mail_opened', 'el.mail_opened_at', 'el.phone_to', 'el.phone_msg', 'el.created_at']);

			$this->setPagination($this->db, $this->db->totalCount, $this->view->currentPage, 'notification-tracker/'.time().'/'.$this->view->notifType);

			$this->view->queryDebug = $this->db->getLastQuery();
			$this->view->trackers = $results;

			$this->actionTitle = _('Notification tracker');
			$this->breadcrumbs = [['hash'=>null, 'label'=>$this->actionTitle]];
			return $this->setJsonView('usersNotificationTracker');
		}

		public function allowAccess() {
			if (!$this->user->isLogged()) {
				return $this->redirect('login', 'index');
			}

			return false;
		}

	}
