adm_program/modules/profile/profile_new.php
<?php
/**
***********************************************************************************************
* Create or edit a user profile
*
* @copyright The Admidio Team
* @see https://www.admidio.org/
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only
***********************************************************************************************
*/
/******************************************************************************
* Parameters:
*
* user_uuid : Uuid of the user who should be edited
* mode - html : Show form to create or edit a user profile
* - save : Save all data of the user profile form
* copy : true - The user of the user_id will be copied and the base for this new user
* accept_registration : If set to true, another forward url to role assignment will be set.
* lastname : (Optional) Lastname could be set and will than be preassigned for new users
* firstname : (Optional) First name could be set and will than be preassigned for new users
*
*****************************************************************************/
use Admidio\Exception;
use Admidio\UserInterface\Form;
try {
require_once(__DIR__ . '/../../system/common.php');
// Initialize and check the parameters
$getUserUuid = admFuncVariableIsValid($_GET, 'user_uuid', 'uuid');
$getMode = admFuncVariableIsValid($_GET, 'mode', 'string', array('defaultValue' => 'html', 'validValues' => array('html', 'save')));
$getCopy = admFuncVariableIsValid($_GET, 'copy', 'bool');
$getAcceptRegistration = admFuncVariableIsValid($_GET, 'accept_registration', 'bool');
$registrationOrgId = $gCurrentOrgId;
// read user data
if (!$gValidLogin || $getAcceptRegistration) {
// create user registration object and set requested organization
$user = new UserRegistration($gDb, $gProfileFields);
$user->readDataByUuid($getUserUuid);
if (isset($_POST['reg_org_id'])) {
$user->setOrganization((int)$_POST['reg_org_id']);
}
} else {
$user = new User($gDb, $gProfileFields);
$user->readDataByUuid($getUserUuid);
}
// check if module may be called
if (!$gValidLogin) {
// Registration disabled, so also lock this mode
if (!$gSettingsManager->getBool('registration_enable_module')) {
throw new Exception('SYS_MODULE_DISABLED');
}
} else {
if ($getUserUuid === '') {
// checks if the user has the necessary rights to create new users
if (!$gCurrentUser->editUsers()) {
throw new Exception('SYS_NO_RIGHTS');
}
if (isset($_GET['lastname']) && isset($_GET['firstname'])) {
// If last name and first name are passed, then these are already preassigned
$user->setValue('LAST_NAME', stripslashes($_GET['lastname']));
$user->setValue('FIRST_NAME', stripslashes($_GET['firstname']));
}
} else {
// checks if the user has the necessary rights to change the corresponding profile
if (!$gCurrentUser->hasRightEditProfile($user)) {
throw new Exception('SYS_NO_RIGHTS');
}
}
}
if ($getMode === 'html') {
// set headline of the script
if ($getCopy) {
// if we want to copy the user than set id = 0
$user->setValue('usr_id', 0);
$getUserUuid = '';
$headline = $gL10n->get('SYS_COPY_VAR', array($user->getValue('FIRST_NAME') . ' ' . $user->getValue('LAST_NAME')));
} elseif ($getUserUuid === '' && $gValidLogin) {
$headline = $gL10n->get('SYS_CREATE_MEMBER');
} elseif ($getUserUuid === '' && !$gValidLogin) {
$headline = $gL10n->get('SYS_REGISTRATION');
} elseif ($user->getValue('usr_id') === $gCurrentUserId) {
$headline = $gL10n->get('SYS_EDIT_MY_PROFILE');
} else {
$headline = $gL10n->get('SYS_EDIT_PROFILE');
}
$gNavigation->addUrl(CURRENT_URL, $headline);
// create html page object
$page = new HtmlPage('admidio-profile-edit', $headline);
// create html form
$form = new Form(
'profile_edit_form',
'modules/profile.edit.tpl',
SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/profile/profile_new.php', array('user_uuid' => $getUserUuid, 'mode' => 'save', 'accept_registration' => $getAcceptRegistration)),
$page
);
// *******************************************************************************
// Loop over all categories and profile fields
// *******************************************************************************
$category = '';
$showLoginData = true;
foreach ($gProfileFields->getProfileFields() as $field) {
$showField = false;
$category = $field->getValue('cat_name');
// at registration check if the field is enabled for registration
if (!$gValidLogin && $field->getValue('usf_registration') == 1) {
$showField = true;
} // check if the current user has the right to edit this profile field of the selected user
elseif ($gValidLogin && $gCurrentUser->allowedEditProfileField($user, $field->getValue('usf_name_intern'))) {
$showField = true;
}
// at category basic data show login information fields
// if it's a new record or administrator or approval of new registration
if ($field->getValue('cat_name_intern') === 'BASIC_DATA' && $showLoginData
&& (($user->getValue('usr_id') > 0 && $gCurrentUser->isAdministrator()) || $getUserUuid === '')) {
$showLoginData = false;
$fieldProperty = Form::FIELD_DEFAULT;
if (!$gValidLogin || $getAcceptRegistration) {
$fieldProperty = Form::FIELD_REQUIRED;
}
$form->addInput(
'usr_login_name',
$gL10n->get('SYS_USERNAME'),
$user->getValue('usr_login_name'),
array(
'maxLength' => 254,
'property' => $fieldProperty,
'helpTextId' => 'SYS_USERNAME_DESCRIPTION',
'class' => 'form-control-small',
'autocomplete' => 'username',
'category' => $category
)
);
if (!$gValidLogin) {
// at registration add password and password confirm to form
$form->addInput(
'usr_password',
$gL10n->get('SYS_PASSWORD'),
'',
array(
'type' => 'password',
'property' => Form::FIELD_REQUIRED,
'minLength' => PASSWORD_MIN_LENGTH,
'passwordStrength' => true,
'helpTextId' => 'SYS_PASSWORD_DESCRIPTION',
'class' => 'form-control-small',
'autocomplete' => 'new-password',
'category' => $category
)
);
$form->addInput(
'password_confirm',
$gL10n->get('SYS_CONFIRM_PASSWORD'),
'',
array(
'type' => 'password',
'property' => Form::FIELD_REQUIRED,
'minLength' => PASSWORD_MIN_LENGTH,
'class' => 'form-control-small',
'autocomplete' => 'new-password',
'category' => $category
)
);
// show selectbox with all organizations of database
if ($gSettingsManager->getBool('system_organization_select')) {
$sql = 'SELECT org_id, org_longname
FROM ' . TBL_ORGANIZATIONS . '
ORDER BY org_longname, org_shortname';
$form->addSelectBoxFromSql(
'reg_org_id',
$gL10n->get('SYS_ORGANIZATION'),
$gDb,
$sql,
array(
'property' => Form::FIELD_REQUIRED,
'defaultValue' => $registrationOrgId,
'category' => $category
)
);
}
}
}
// only show fields that are enabled for registration or the user has permission to edit that field
if ($showField) {
// add profile fields to form
$fieldProperty = Form::FIELD_DEFAULT;
$helpId = '';
$usfNameIntern = $field->getValue('usf_name_intern');
if ($gProfileFields->getProperty($usfNameIntern, 'usf_disabled') == 1
&& !$gCurrentUser->hasRightEditProfile($user, false) && $getUserUuid !== '') {
// disable field if this is configured in profile field configuration
$fieldProperty = Form::FIELD_DISABLED;
} elseif ($gProfileFields->hasRequiredInput($usfNameIntern, $user->getValue('usr_id'), !$gValidLogin || $getAcceptRegistration)) {
$fieldProperty = Form::FIELD_REQUIRED;
}
if (strlen($gProfileFields->getProperty($usfNameIntern, 'usf_description')) > 0) {
$helpId = $gProfileFields->getProperty($gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'), 'usf_description');
if (Admidio\Language::isTranslationStringId($helpId)) {
$helpId = array($helpId, array($gProfileFields->getProperty($usfNameIntern, 'usf_name')));
}
}
// code for different field types
if ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'CHECKBOX') {
$form->addCheckbox(
$gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'),
$gProfileFields->getProperty($usfNameIntern, 'usf_name'),
(bool)$user->getValue($usfNameIntern),
array(
'property' => $fieldProperty,
'helpTextId' => $helpId,
'icon' => 'bi-' . $gProfileFields->getProperty($usfNameIntern, 'usf_icon', 'database'),
'category' => $category
)
);
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'DROPDOWN' || $usfNameIntern === 'COUNTRY') {
// set array with values and set default value
if ($usfNameIntern === 'COUNTRY') {
$arrListValues = $gL10n->getCountries();
$defaultValue = null;
if ((int)$user->getValue('usr_id') === 0 && strlen($gSettingsManager->getString('default_country')) > 0) {
$defaultValue = $gSettingsManager->getString('default_country');
} elseif ($user->getValue('usr_id') > 0 && strlen($user->getValue($usfNameIntern)) > 0) {
$defaultValue = $user->getValue($usfNameIntern, 'database');
}
} else {
$arrListValues = $gProfileFields->getProperty($usfNameIntern, 'usf_value_list');
$defaultValue = $user->getValue($usfNameIntern, 'database');
}
$form->addSelectBox(
$gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'),
$gProfileFields->getProperty($usfNameIntern, 'usf_name'),
$arrListValues,
array(
'property' => $fieldProperty,
'defaultValue' => $defaultValue,
'helpTextId' => $helpId,
'icon' => 'bi-' . $gProfileFields->getProperty($usfNameIntern, 'usf_icon', 'database'),
'category' => $category
)
);
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'RADIO_BUTTON') {
$showDummyRadioButton = false;
if (!$gProfileFields->hasRequiredInput($usfNameIntern, $user->getValue('usr_id'), !$gValidLogin || $getAcceptRegistration)) {
$showDummyRadioButton = true;
}
$form->addRadioButton(
$gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'),
$gProfileFields->getProperty($usfNameIntern, 'usf_name'),
$gProfileFields->getProperty($usfNameIntern, 'usf_value_list', 'html'),
array(
'property' => $fieldProperty,
'defaultValue' => (int)$user->getValue($usfNameIntern, 'database'),
'showNoValueButton' => $showDummyRadioButton,
'helpTextId' => $helpId,
'icon' => 'bi-' . $gProfileFields->getProperty($usfNameIntern, 'usf_icon', 'database'),
'category' => $category
)
);
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'TEXT_BIG') {
$form->addMultilineTextInput(
$gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'),
$gProfileFields->getProperty($usfNameIntern, 'usf_name'),
$user->getValue($usfNameIntern),
3,
array(
'maxLength' => 4000,
'property' => $fieldProperty,
'helpTextId' => $helpId,
'icon' => 'bi-' . $gProfileFields->getProperty($usfNameIntern, 'usf_icon', 'database'),
'category' => $category
)
);
} else {
$fieldType = 'text';
if ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'DATE') {
$fieldType = 'date';
$maxlength = '10';
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'EMAIL') {
// email could not be longer than 254 characters
$fieldType = 'email';
$maxlength = '254';
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'URL') {
// maximal browser compatible url length will be 2000 characters
$maxlength = '2000';
} elseif ($gProfileFields->getProperty($usfNameIntern, 'usf_type') === 'NUMBER') {
$fieldType = 'number';
$maxlength = array(0, 9999999999, 1);
} elseif ($gProfileFields->getProperty($usfNameIntern, 'cat_name_intern') === 'SOCIAL_NETWORKS') {
$maxlength = '255';
} else {
$maxlength = '100';
}
$form->addInput(
$gProfileFields->getProperty($usfNameIntern, 'usf_name_intern'),
$gProfileFields->getProperty($usfNameIntern, 'usf_name'),
$user->getValue($usfNameIntern),
array(
'type' => $fieldType,
'maxLength' => $maxlength,
'property' => $fieldProperty,
'helpTextId' => $helpId,
'icon' => 'bi-' . $gProfileFields->getProperty($usfNameIntern, 'usf_icon', 'database'),
'category' => $category
)
);
}
}
}
// if captchas are enabled then visitors of the website must resolve this
if (!$gValidLogin && $gSettingsManager->getBool('registration_enable_captcha')) {
$form->addCaptcha('captcha_code');
}
if (!$gValidLogin) {
// Registration
$form->addSubmitButton('btn_save', $gL10n->get('SYS_SEND'), array('icon' => 'bi-envelope-fill'));
} else {
$form->addSubmitButton('btn_save', $gL10n->get('SYS_SAVE'), array('icon' => 'bi-check-lg'));
}
if ($getUserUuid !== '') {
// show information about user who creates the recordset and changed it
$page->assignSmartyVariable('nameUserCreated', $user->getNameOfCreatingUser());
$page->assignSmartyVariable('timestampUserCreated', $user->getValue('ann_timestamp_create'));
$page->assignSmartyVariable('nameLastUserEdited', $user->getNameOfLastEditingUser());
$page->assignSmartyVariable('timestampLastUserEdited', $user->getValue('ann_timestamp_change'));
}
$form->addToHtmlPage();
$gCurrentSession->addFormObject($form);
$page->show();
} elseif ($getMode === 'save') {
// ------------------------------------------------------------
// Save all data of the profile form to the user object
// ------------------------------------------------------------
// check form field input and sanitized it from malicious content
$profileEditForm = $gCurrentSession->getFormObject($_POST['admidio-csrf-token']);
$formValues = $profileEditForm->validate($_POST);
// Login name and password must be checked during registration
if (!$gValidLogin) {
// Passwort muss mindestens 8 Zeichen lang sein
if (strlen($_POST['usr_password']) < PASSWORD_MIN_LENGTH) {
throw new Exception('SYS_PASSWORD_LENGTH');
}
// both password fields must be identical
if ($_POST['usr_password'] !== $_POST['password_confirm']) {
throw new Exception('SYS_PASSWORDS_NOT_EQUAL');
}
if (PasswordUtils::passwordStrength($_POST['usr_password'], $user->getPasswordUserData()) < $gSettingsManager->getInt('password_min_strength')) {
throw new Exception('SYS_PASSWORD_NOT_STRONG_ENOUGH');
}
}
// write all profile fields to the user object
foreach ($formValues as $key => $value) {
if (strpos($key, 'usr_') !== 0) {
$user->setValue($key, $value);
}
}
if (isset($_POST['usr_login_name']) && ($gCurrentUser->isAdministrator() || $getUserUuid === '')) {
// Only administrators could change login name or within a new registration
if ($_POST['usr_login_name'] !== $user->getValue('usr_login_name')) {
if (strlen($_POST['usr_login_name']) > 0) {
// check if the username is already assigned
$sql = 'SELECT usr_uuid
FROM ' . TBL_USERS . '
WHERE usr_login_name = ?';
$pdoStatement = $gDb->queryPrepared($sql, array($_POST['usr_login_name']));
if ($pdoStatement->rowCount() > 0 && $pdoStatement->fetchColumn() !== $getUserUuid) {
throw new Exception('SYS_LOGIN_NAME_EXIST');
}
}
if (!$user->setValue('usr_login_name', $_POST['usr_login_name'])) {
throw new Exception('SYS_FIELD_INVALID_CHAR', array('SYS_USERNAME'));
}
}
}
// if registration, then still fill the corresponding fields
if (!$gValidLogin) {
$user->setPassword($_POST['usr_password']);
// At user registration with activated captcha check the captcha input
if ($gSettingsManager->getBool('registration_enable_captcha')) {
FormValidation::checkCaptcha($_POST['captcha_code']);
}
}
// ------------------------------------------------------------
// Save user data to database
// ------------------------------------------------------------
$gDb->startTransaction();
$user->save();
$gDb->endTransaction();
// if data of the logged-in user is changed, then update session variables
if ((int)$user->getValue('usr_id') === $gCurrentUserId) {
$gCurrentUser = $user;
}
// ------------------------------------------------------------
// redirect to the correct page depending on the call mode
// ------------------------------------------------------------
if (!$gValidLogin) {
// registration was successful then go to homepage
$gNavigation->deleteLastUrl();
echo json_encode(array(
'status' => 'success',
'message' => $gL10n->get('SYS_REGISTRATION_SAVED'),
'url' => $gHomepage
));
exit();
} else {
if ($getUserUuid === '' || $getAcceptRegistration) {
// assign a registration or create a new user
if ($getAcceptRegistration) {
// accept a registration, assign necessary roles and send a notification email
$user->acceptRegistration();
$messageId = 'SYS_ASSIGN_REGISTRATION_SUCCESSFUL';
} else {
// a new user is created with the user management module
// then the user must get the necessary roles
$user->assignDefaultRoles();
$messageId = 'SYS_SAVE_DATA';
}
// if current user has the right to assign roles then show roles dialog
// otherwise go to previous url (default roles are assigned automatically)
if ($gCurrentUser->assignRoles()) {
echo json_encode(array(
'status' => 'success',
'url' => SecurityUtils::encodeUrl(
ADMIDIO_URL . FOLDER_MODULES . '/profile/roles.php',
array(
'user_uuid' => $user->getValue('usr_uuid'),
'accept_registration' => $getAcceptRegistration,
'new_user' => $getUserUuid === ''
))
));
exit();
} else {
$gNavigation->deleteLastUrl();
echo json_encode(array(
'status' => 'success',
'message' => $messageId,
'url' => $gNavigation->getPreviousUrl()
));
exit();
}
} elseif (!$user->getValue('usr_valid')) {
// a registration was edited then go back to profile view
$gNavigation->deleteLastUrl();
echo json_encode(array('status' => 'success', 'url' => $gNavigation->getPreviousUrl()));
exit();
} else {
// go back to profile view
$gNavigation->deleteLastUrl();
echo json_encode(array('status' => 'success', 'url' => $gNavigation->getUrl()));
exit();
}
}
}
} catch (Exception $e) {
if ($getMode === 'save') {
echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
} else {
$gMessage->show($e->getMessage());
}
}