3 # FILE: UserEditingUI.php 5 # Part of the Collection Workflow Integration System (CWIS) 6 # Copyright 2015 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu/cwis/ 22 $this->
User = $CWUser;
35 $UpdateUserEmail=FALSE)
37 # save other user information 50 $UserFields[] =
"EMail";
52 foreach ($UserFields as $VarName)
54 $FormVarName =
"F_".$VarName;
55 if (isset($FormValues[$FormVarName]) && strlen($FormValues[$FormVarName]))
57 $this->
User->
Set($VarName, $FormValues[$FormVarName]);
61 # real name is handled separately so we can signal 62 # EVENT_USER_REAL_NAME_CHANGED if needed 64 # if a new real name was provided 65 $NewRealName = GetArrayValue($FormValues,
"F_RealName",
"");
66 if (strlen($NewRealName))
68 # pull out the old value 69 $OldRealName = $this->
User->
Get(
"RealName");
71 # update the stored value 72 $this->
User->
Set(
"RealName", $NewRealName);
74 # if this was an existing user and the value changed 75 if (!$IsNewUser && $OldRealName != $NewRealName)
77 # signal the real name change 78 $GLOBALS[
"AF"]->SignalEvent(
79 "EVENT_USER_REAL_NAME_CHANGED",
81 "UserId" => $this->
User->
Id(),
82 "OldRealName" => $OldRealName,
83 "NewRealName" => $NewRealName));
100 $Resource = $this->
User->GetResource();
101 $EmptyFields = array();
102 $RecordChanged = FALSE;
104 # for each metadata field in the User schema 105 foreach ($Fields as $Field)
107 # if user has permission to edit field 108 if ($Resource->UserCanEditField($this->User, $Field))
110 $OldValue = $Resource->Get($Field);
111 switch ($Field->Type())
120 # if we have a value from the form for this field 121 # (check necessary because user may push Save button 122 # before form has finished loading) 123 if (isset($_POST[
"F_".$Field->DBFieldName()]))
125 # run value through any hooked filters 126 $NewValue = trim($_POST[
"F_".$Field->DBFieldName()]);
127 $SignalResult = $AF->SignalEvent(
128 "EVENT_POST_FIELD_EDIT_FILTER", array(
130 "Resource" => $Resource,
131 "Value" => $NewValue));
132 $NewValue = $SignalResult[
"Value"];
134 # clean out xss threats 135 $NewValue = StripXSSThreats($NewValue);
137 # filter date field values for validity 141 $TestDate =
new Date($NewValue);
142 if ($TestDate->Precision() == 0) { $NewValue =
""; }
145 # filter url values for URI 148 && !preg_match(
'/^[a-zA-Z]+:\/\//', $NewValue))
150 $NewValue =
"http://".$NewValue;
153 # filter HTML tags out of text values if appropriate 157 if (!$Field->AllowHTML())
159 $NewValue = strip_tags($NewValue);
163 # if value was supplied or field is not required 164 if (strlen($NewValue) || $Field->Optional())
167 $Resource->Set($Field, $NewValue);
171 # add field to error list 172 $EmptyFields[] = $Field;
178 # if there are no values set 179 if (!isset($_POST[
"F_".$Field->DBFieldName().
"X"])
180 || !isset($_POST[
"F_".$Field->DBFieldName().
"Y"]))
182 # if the field isn't optional, add it to the error list 183 if (!$Field->Optional())
185 $EmptyFields[] = $Field;
188 # go to the next field 192 # run value through any hooked filters 194 "X" => $_POST[
"F_".$Field->DBFieldName().
"X"],
195 "Y" => $_POST[
"F_".$Field->DBFIeldName().
"Y"]);
196 $SignalResult = $AF->SignalEvent(
197 "EVENT_POST_FIELD_EDIT_FILTER", array(
199 "Resource" => $Resource,
200 "Value" => $NewValue));
201 $NewValue = $SignalResult[
"Value"];
203 # if value looks valid 204 if (is_numeric($NewValue[
"X"])
205 && is_numeric($NewValue[
"Y"]))
208 $Resource->Set($Field, $NewValue);
211 # the field is optional and the values are blank 212 else if ($Field->Optional()
213 && !strlen(trim($NewValue[
"X"]))
214 && !strlen(trim($NewValue[
"Y"])))
217 $Resource->Set($Field, array(
"X" =>
"",
"Y" =>
""));
220 # empty fields and field is required 221 else if (!$Field->Optional())
223 # flag field as empty 224 $EmptyFields[] = $Field;
230 # while there are form values for this field 231 $ValueCount = $Field->GetCountOfPossibleValues();
232 $InterfaceToggleThreshold = 250;
233 $Factory = $Field->GetFactory();
234 $ValuesToSet = array();
235 $InputValues = array();
237 # old way it was being set 238 $BaseFieldName =
"D_".$Field->DBFieldName().
"_";
241 # set values the old way 242 if (isset($_POST[$BaseFieldName.$FieldIndex]))
244 while (isset($_POST[$BaseFieldName.$FieldIndex]))
246 # retrieve value from form field 247 $InputValues[] = $_POST[$BaseFieldName.$FieldIndex];
249 # move to the next form value 254 # set values the new way 255 else if (isset($_POST[
"F_".$Field->DBFieldName()]))
257 $InputValues = $_POST[
"F_".$Field->DBFieldName()];
260 foreach ($InputValues as $Value)
262 # If we have a non-empty value 265 # Check to see if it was a name, and if so 266 # convert it to an index. Otherwise, 267 # it was already an index and we should use it 269 $Item = $Factory->GetItemByName($Value);
272 $Value = $Item->Id();
275 # it looks like it was being wrongly assumed that 276 # this would always be a number, but when there's 277 # an error, it won't find an item and display SQL 278 # errors later on. So, if the value isn't numeric, 279 # refuse to work with it 280 else if (!is_numeric($Value))
286 $Value = intval($Value);
294 # if form value appears valid 297 # add value to list of those to be set 298 # (set method expects IDs to appear as indexes) 299 $ValuesToSet[$Value] = 1;
303 # if value found to set or field is not required 304 if (count($ValuesToSet) || $Field->Optional())
306 $OldKeys = array_keys($OldValue);
307 $NewKeys = array_keys($ValuesToSet);
312 if ($OldKeys != $NewKeys)
314 # clear any existing values for this field 315 $Resource->ClearByField($Field);
317 # if values found to set 318 if (count($ValuesToSet))
320 # set values in resource 321 $Resource->Set($Field, $ValuesToSet);
327 # add field to error list 328 $EmptyFields[] = $Field;
333 # if field allows multiple values 334 $ValuesToSet = array();
335 if ($Field->AllowMultiple())
337 # retrieve possible values for this field 338 $PossibleValues = $Field->GetPossibleValues();
340 # newer way to get the values 341 if (isset($_POST[
"F_".$Field->DBFieldName()]))
343 $GivenValues = $_POST[
"F_".$Field->DBFieldName()];
345 # for each possible value 346 foreach ($PossibleValues as $ValueId => $ValueName)
348 # if form field is set for value 349 if (in_array($ValueId, $GivenValues))
351 # add value to list of those to be set 352 $ValuesToSet[$ValueId] = 1;
357 # old way to get the values 360 # for each possible value 361 foreach ($PossibleValues as $ValueId => $ValueName)
363 # if form field is set for value 364 if (isset($_POST[
"D_".$Field->DBFieldName()
367 # add value to list of those to be set 368 $ValuesToSet[$ValueId] = 1;
375 # retrieve value for this field (if available) 376 if (isset($_POST[
"F_".$Field->DBFieldName()]))
378 $ValuesToSet[$_POST[
"F_".$Field->DBFieldName()]] = 1;
382 # if value found to set or field is not required 383 if (count($ValuesToSet) || $Field->Optional())
385 $OldKeys = array_keys($OldValue);
386 $NewKeys = array_keys($ValuesToSet);
391 if ($OldKeys != $NewKeys)
393 # clear any existing values for this field 394 $Resource->ClearByField($Field);
396 # if values found to set 397 if (count($ValuesToSet))
399 # set values in resource 400 $Resource->Set($Field, $ValuesToSet);
406 # add field to error list 407 $EmptyFields[] = $Field;
412 $NewValue = trim(GetArrayValue(
414 "F_".$Field->DBFieldName()));
416 if (strlen($NewValue))
418 $SignalResult = $AF->SignalEvent(
419 "EVENT_POST_FIELD_EDIT_FILTER", array(
421 "Resource" => $Resource,
422 "Value" => $NewValue));
424 $NewValue = $SignalResult[
"Value"];
425 $Resource->Set($Field, $NewValue);
428 # allow the field to be unset if it's optional 429 else if ($Field->Optional())
431 $SignalResult = $AF->SignalEvent(
432 "EVENT_POST_FIELD_EDIT_FILTER", array(
434 "Resource" => $Resource,
435 "Value" => $NewValue));
437 $NewValue = $SignalResult[
"Value"];
438 $Resource->Set($Field, $NewValue);
444 # get the new value from the submitted form data 445 $NewValue = GetArrayValue(
447 "F_".$Field->DBFieldName(),
450 foreach ($NewValue as $Key => $ReferenceId)
452 # remove any blank values 453 if (strlen(trim($ReferenceId)) < 1)
455 unset($NewValue[$Key]);
458 # remove any values that don't look right 459 if (!is_numeric($ReferenceId))
461 unset($NewValue[$Key]);
466 $Resource->Set($Field, $NewValue);
471 # (these types handled via special upload mechanisms) 477 # If anything changed, set the update flag. 478 $RecordChanged |= ($OldValue
479 != $Resource->Get($Field));
483 # If the record was changed, modify the appropriate timestamp fields 486 $Resource->UpdateAutoupdateFields(
490 # update search and recommender DBs if configured to do so 491 $Resource->QueueSearchAndRecommenderUpdate();
493 # signal the modified event if the resource isn't a temp one 494 if (!$Resource->IsTempResource())
496 $AF->SignalEvent(
"EVENT_RESOURCE_MODIFY", array(
"Resource" => $Resource));
500 # return list of any empty required fields to caller 511 # for each metadata field that might have an uploaded image 513 $Resource = $this->
User->GetResource();
515 foreach ($Fields as $Field)
517 $FormFieldName =
"F_".$Field->DBFieldName();
519 # if field is modifiable by specified user 520 # and we have an uploaded file for this field 521 if ($Resource->UserCanEditField($this->User, $Field)
522 && isset($Files[$FormFieldName][
"tmp_name"])
523 && is_uploaded_file($Files[$FormFieldName][
"tmp_name"]))
526 $TmpFileName = $Files[$FormFieldName][
"tmp_name"];
527 $NewFile =
new File($TmpFileName, $Resource->Id(), $Field->Id(),
528 $Files[$FormFieldName][
"name"]);
530 # if file save went fine 533 $GLOBALS[
"AF"]->SignalEvent(
534 "EVENT_RESOURCE_FILE_ADD",
537 "Resource" => $Resource,
538 "File" => $NewFile));
543 # set error message and error out 544 switch ($NewFile->Status())
547 $Error = ERR_ZEROLENGTH;
551 $Error = ERR_FILEUPLOADERROR;
554 $ErrParamOne = $Files[$FormFieldName][
'name'];
555 $ErrParamTwo = $NewFile->Status();
559 unlink($TmpFileName);
562 # delete images that have been selected for delete 563 if (isset($FormValues[$FormFieldName.
"_Delete"]))
565 $DeletionIds = $FormValues[$FormFieldName.
"_Delete"];
567 foreach ($DeletionIds as $DeletionId)
569 $File =
new File($DeletionId);
571 $GLOBALS[
"AF"]->SignalEvent(
572 "EVENT_RESOURCE_FILE_DELETE",
575 "Resource" => $Resource,
578 $Resource->Clear($Field, $File->Id());
592 # for each metadata field that might have an uploaded image 594 $Resource = $this->
User->GetResource();
596 foreach ($Fields as $Field)
598 $FormFieldName =
"F_".$Field->DBFieldName();
600 # if field is modifiable by specified user 601 # and we have an uploaded file for this field 602 if ($Resource->UserCanEditField($this->User, $Field)
603 && isset($Files[$FormFieldName][
"tmp_name"])
604 && is_uploaded_file($Files[$FormFieldName][
"tmp_name"]))
606 # create temp copy of file with correct name 607 $TempFile =
"tmp/".$Files[$FormFieldName][
'name'];
608 copy($Files[$FormFieldName][
"tmp_name"], $TempFile);
610 # create new Image object from uploaded file 613 $Field->MaxWidth(), $Field->MaxHeight(),
614 $Field->MaxPreviewWidth(), $Field->MaxPreviewHeight(),
615 $Field->MaxThumbnailWidth(), $Field->MaxThumbnailHeight());
617 # if file save failed 618 if ($Image->Status() !=
AI_OKAY)
620 # set error message and error out 621 switch ($Image->Status())
626 ? ERR_UNSUPPORTEDIMAGEFORMAT : ERR_UNKNOWNIMAGETYPE;
627 $ErrParamOne = $Files[$Field->DBFieldName()][
'name'];
631 $Error = ERR_IMAGEUPLOADERROR;
632 $ErrParamOne = $Files[$FormFieldName][
'name'];
633 $ErrParamTwo = $Image->Status();
639 # attach image to resource 640 $Resource->Set($Field, $Image->Id());
644 # delete images that have been selected for delete 645 if (isset($FormValues[$FormFieldName.
"_Delete"]))
647 $DeletionIds = $FormValues[$FormFieldName.
"_Delete"];
649 foreach ($DeletionIds as $DeletionId)
651 $Resource->Clear($Field,
new SPTImage($DeletionId));
667 $ErrorMessages = NULL)
672 # if errors were found in incoming values 673 if ($FTool->IncomingFieldValuesHaveErrors() || count($UserErrorCodes))
675 # make form fields based on error codes 676 $CodeToFieldMap = array(
692 foreach ($UserErrorCodes as $Code)
694 if (isset($CodeToFieldMap[$Code]))
696 if (is_array(isset($CodeToFieldMap[$Code])))
698 foreach ($CodeToFieldMap[$Code] as $FieldName)
700 $FTool->SetAdditionalErrorFields($FieldName);
705 $FTool->SetAdditionalErrorFields($CodeToFieldMap[$Code]);
710 $FTool->SetAdditionalErrorCodes($ErrorMessages);
718 # mark form fields based on the associated errors 719 $CodeToFieldMap = array(
736 if ($FTool->ErrorsLogged() || count($UserErrorCodes))
738 # if the user did not provide error message strings, get the defaults 739 if (is_null($ErrorMessages))
741 $ErrorMessages = self::GetAdditionalErrorCodes($_POST[
"F_UserName"]);
744 # look up messages for any unknown error codes 745 foreach ($UserErrorCodes as $Code)
747 if (!isset($ErrorMessages[$Code]))
753 # for each reported error 754 foreach ($UserErrorCodes as $Code)
756 # see if this error corresponds to a field or fields 757 if (isset($CodeToFieldMap[$Code]))
759 # if so, log the error for each implicated field 760 foreach ($CodeToFieldMap[$Code] as $Field)
762 $FTool->LogError($ErrorMessages[$Code], $Field);
767 # otherwise, log the error as a general error 768 $FTool->LogError($ErrorMessages[$Code]);
788 $Protocol = isset($_SERVER[
"HTTPS"]) ?
"https://" :
"http://";
790 $ActivationUrlParameters =
"?UN=".urlencode($NewUser->Get(
"UserName"))
791 .
"&AC=".$NewUser->GetActivationCode();
792 $ActivationUrl = $Protocol.$_SERVER[
"SERVER_NAME"]
793 .dirname($_SERVER[
"SCRIPT_NAME"])
794 .
"/index.php".$ActivationUrlParameters.
"&P=ActivateAccount";
795 $ManualActivationUrl = $Protocol.$_SERVER[
"SERVER_NAME"]
796 .dirname($_SERVER[
"SCRIPT_NAME"])
797 .
"/index.php?P=ManuallyActivateAccount";
800 "X-PORTALNAME-X" => $GLOBALS[
"G_SysConfig"]->PortalName(),
801 "X-ACTIVATIONURL-X" => $ActivationUrl,
802 "X-ACTIVATIONPARAMETERS-X" => $ActivationUrlParameters,
803 "X-MANUALACTIVATIONURL-X" => $ManualActivationUrl,
815 $FieldsToExclude = array(), $AdditionalFields = array())
818 array_unshift($UsStates,
"--");
820 # blank Placeholder values overwrite default of "($Label)" 822 "LoginInformation" => array(
824 "Label" =>
"Login Information",
828 "Label" =>
"User Name",
836 "Label" =>
"Password",
842 "PasswordAgain" => array(
844 "Label" =>
"Password (Again)",
848 "Help" =>
"(passwords are case sensitive)",
852 "Label" =>
"E-mail Address",
857 "Help" =>
"(must be valid to activate account)",
859 "EMailAgain" => array(
861 "Label" =>
"E-mail Address (Again)",
867 "UserInformation" => array(
869 "Label" =>
"User Information (Optional)" 873 "Label" =>
"Real Name",
881 "Label" =>
"Web Site",
887 "AddressLineOne" => array(
889 "Label" =>
"Address",
895 "AddressLineTwo" => array(
897 "Label" =>
"Address (Cont'd)",
915 "AllowMultiple" => FALSE,
916 "Options" => $UsStates,
920 "Label" =>
"Zip Code",
928 "Label" =>
"Country",
936 if (isset($ReadOnlyFields))
938 foreach ($ReadOnlyFields as $ReadOnly)
940 $FormFields[$ReadOnly][
"ReadOnly"] = TRUE;
944 if (isset($FieldsToExclude))
946 foreach ($FieldsToExclude as $Exclude)
948 unset($FormFields[$Exclude]);
952 if (isset($AdditionalFields)) {
953 $FormFields = array_merge($FormFields, $AdditionalFields);
968 .
" with an account. If you have forgotten the account user name or" 969 .
" password you can click" 970 .
" <a href=\"index.php?P=ForgottenPasswordComplete&UN=" 971 .urlencode($UserName).
"\">here</a>" 972 .
" to send a reminder via e-mail.",
984 $UserErrorCodes = $UserFactory->TestNewUserValues($FormValues[
"F_UserName"],
985 $FormValues[
"F_Password"], $FormValues[
"F_PasswordAgain"],
986 $FormValues[
"F_EMail"], $FormValues[
"F_EMailAgain"]);
988 $SignupStatus = $GLOBALS[
"AF"]->SignalEvent(
989 "EVENT_USER_SIGNUP_VERIFY",
991 "UserName" => $FormValues[
"F_UserName"],
992 "Password" => $FormValues[
"F_Password"],
993 "EMail" => $FormValues[
"F_EMail"],
996 if ($SignupStatus[
"Status"] !==
U_OKAY)
998 $UserErrorCodes[]= $SignupStatus[
"Status"];
1001 return $UserErrorCodes;
1004 # ---- PRIVATE INTERFACE -------------------------------------------------
static GetActivationEmailSubstitutions($NewUser)
Retrieve the array of substitutions for new user activation mails.
const FILESTAT_ZEROLENGTH
const U_ILLEGALEMAILAGAIN
UpdateUserAttributes(array $FormValues, $IsNewUser=FALSE, $UpdateUserEmail=FALSE)
Save user attributes that aren't stored in User Schema fields.
static TestUserValues($FormValues)
Check potential form values for a user including event signals.
static GetRequestAccountForm($ReadOnlyFields=array(), $FieldsToExclude=array(), $AdditionalFields=array())
Retrieve the array of Request Account Form information.
const U_ILLEGALPASSWORDAGAIN
Class supplying standard methods that process changes to user entered via HTML forms.
UploadImages($FormValues, $Files)
Process image upload requests for a user.
const U_EMPTYPASSWORDAGAIN
static GetAdditionalErrorCodes($UserName)
Get the list of account creation-related error messages.
CWIS-specific user factory class.
static GetStatusMessageForCode($StatusCode)
Get text error message for a specified error code.
Set($FieldName, $NewValue)
static GetPasswordRulesDescription()
Get a string describing the password rules.
Encapsulates a full-size, preview, and thumbnail image.
const U_DUPLICATEUSERNAME
UploadFiles($FormValues, $Files)
Process file upload requests.
static GetUsStatesList()
Get an array of US state names with their two-letter abbreviations as the index.
UpdateUserFields(array $Fields)
Save updated values for fields from the User schema based on data supplised in HTML forms...
Class representing a stored (usually uploaded) file.
static UserFormHasErrors(&$FTool, $UserErrorCodes, $ErrorMessages=NULL)
Determine if a user editing form has errors, setting error codes in the correspnding FormTool...
__construct($CWUser)
Set up a new UserEditingUI.
const AI_UNSUPPORTEDFORMAT
const U_PASSWORDSDONTMATCH