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 if (isset($FormValues[
"F_RealName"]))
63 # the real name is handled separately from the other settings 64 $OldRealName = $this->
User->
Get(
"RealName");
65 $NewRealName = GetArrayValue($_POST,
"F_RealName",
"");
67 if (!$IsNewUser && $OldRealName != $NewRealName)
69 $this->
User->
Set(
"RealName", $NewRealName);
71 # signal the real name change 72 $GLOBALS[
"AF"]->SignalEvent(
73 "EVENT_USER_REAL_NAME_CHANGED",
75 "UserId" => $this->
User->
Id(),
76 "OldRealName" => $OldRealName,
77 "NewRealName" => $NewRealName));
94 $Resource = $this->
User->GetResource();
95 $EmptyFields = array();
96 $RecordChanged = FALSE;
98 # for each metadata field in the User schema 99 foreach ($Fields as $Field)
101 # if user has permission to edit field 102 if ($Resource->UserCanEditField($this->User, $Field))
104 $OldValue = $Resource->Get($Field);
105 switch ($Field->Type())
114 # if we have a value from the form for this field 115 # (check necessary because user may push Save button 116 # before form has finished loading) 117 if (isset($_POST[
"F_".$Field->DBFieldName()]))
119 # run value through any hooked filters 120 $NewValue = trim($_POST[
"F_".$Field->DBFieldName()]);
121 $SignalResult = $AF->SignalEvent(
122 "EVENT_POST_FIELD_EDIT_FILTER", array(
124 "Resource" => $Resource,
125 "Value" => $NewValue));
126 $NewValue = $SignalResult[
"Value"];
128 # clean out xss threats 129 $NewValue = StripXSSThreats($NewValue);
131 # filter date field values for validity 135 $TestDate =
new Date($NewValue);
136 if ($TestDate->Precision() == 0) { $NewValue =
""; }
139 # filter url values for URI 142 && !preg_match(
'/^[a-zA-Z]+:\/\//', $NewValue))
144 $NewValue =
"http://".$NewValue;
147 # filter HTML tags out of text values if appropriate 151 if (!$Field->AllowHTML())
153 $NewValue = strip_tags($NewValue);
157 # if value was supplied or field is not required 158 if (strlen($NewValue) || $Field->Optional())
161 $Resource->Set($Field, $NewValue);
165 # add field to error list 166 $EmptyFields[] = $Field;
172 # if there are no values set 173 if (!isset($_POST[
"F_".$Field->DBFieldName().
"X"])
174 || !isset($_POST[
"F_".$Field->DBFieldName().
"Y"]))
176 # if the field isn't optional, add it to the error list 177 if (!$Field->Optional())
179 $EmptyFields[] = $Field;
182 # go to the next field 186 # run value through any hooked filters 188 "X" => $_POST[
"F_".$Field->DBFieldName().
"X"],
189 "Y" => $_POST[
"F_".$Field->DBFIeldName().
"Y"]);
190 $SignalResult = $AF->SignalEvent(
191 "EVENT_POST_FIELD_EDIT_FILTER", array(
193 "Resource" => $Resource,
194 "Value" => $NewValue));
195 $NewValue = $SignalResult[
"Value"];
197 # if value looks valid 198 if (is_numeric($NewValue[
"X"])
199 && is_numeric($NewValue[
"Y"]))
202 $Resource->Set($Field, $NewValue);
205 # the field is optional and the values are blank 206 else if ($Field->Optional()
207 && !strlen(trim($NewValue[
"X"]))
208 && !strlen(trim($NewValue[
"Y"])))
211 $Resource->Set($Field, array(
"X" =>
"",
"Y" =>
""));
214 # empty fields and field is required 215 else if (!$Field->Optional())
217 # flag field as empty 218 $EmptyFields[] = $Field;
224 # while there are form values for this field 225 $ValueCount = $Field->GetCountOfPossibleValues();
226 $InterfaceToggleThreshold = 250;
227 $Factory = $Field->GetFactory();
228 $ValuesToSet = array();
229 $InputValues = array();
231 # old way it was being set 232 $BaseFieldName =
"D_".$Field->DBFieldName().
"_";
235 # set values the old way 236 if (isset($_POST[$BaseFieldName.$FieldIndex]))
238 while (isset($_POST[$BaseFieldName.$FieldIndex]))
240 # retrieve value from form field 241 $InputValues[] = $_POST[$BaseFieldName.$FieldIndex];
243 # move to the next form value 248 # set values the new way 249 else if (isset($_POST[
"F_".$Field->DBFieldName()]))
251 $InputValues = $_POST[
"F_".$Field->DBFieldName()];
254 foreach ($InputValues as $Value)
256 # If we have a non-empty value 259 # Check to see if it was a name, and if so 260 # convert it to an index. Otherwise, 261 # it was already an index and we should use it 263 $Item = $Factory->GetItemByName($Value);
266 $Value = $Item->Id();
269 # it looks like it was being wrongly assumed that 270 # this would always be a number, but when there's 271 # an error, it won't find an item and display SQL 272 # errors later on. So, if the value isn't numeric, 273 # refuse to work with it 274 else if (!is_numeric($Value))
280 $Value = intval($Value);
288 # if form value appears valid 291 # add value to list of those to be set 292 # (set method expects IDs to appear as indexes) 293 $ValuesToSet[$Value] = 1;
297 # if value found to set or field is not required 298 if (count($ValuesToSet) || $Field->Optional())
300 $OldKeys = array_keys($OldValue);
301 $NewKeys = array_keys($ValuesToSet);
306 if ($OldKeys != $NewKeys)
308 # clear any existing values for this field 309 $Resource->ClearByField($Field);
311 # if values found to set 312 if (count($ValuesToSet))
314 # set values in resource 315 $Resource->Set($Field, $ValuesToSet);
321 # add field to error list 322 $EmptyFields[] = $Field;
327 # if field allows multiple values 328 $ValuesToSet = array();
329 if ($Field->AllowMultiple())
331 # retrieve possible values for this field 332 $PossibleValues = $Field->GetPossibleValues();
334 # newer way to get the values 335 if (isset($_POST[
"F_".$Field->DBFieldName()]))
337 $GivenValues = $_POST[
"F_".$Field->DBFieldName()];
339 # for each possible value 340 foreach ($PossibleValues as $ValueId => $ValueName)
342 # if form field is set for value 343 if (in_array($ValueId, $GivenValues))
345 # add value to list of those to be set 346 $ValuesToSet[$ValueId] = 1;
351 # old way to get the values 354 # for each possible value 355 foreach ($PossibleValues as $ValueId => $ValueName)
357 # if form field is set for value 358 if (isset($_POST[
"D_".$Field->DBFieldName()
361 # add value to list of those to be set 362 $ValuesToSet[$ValueId] = 1;
369 # retrieve value for this field (if available) 370 if (isset($_POST[
"F_".$Field->DBFieldName()]))
372 $ValuesToSet[$_POST[
"F_".$Field->DBFieldName()]] = 1;
376 # if value found to set or field is not required 377 if (count($ValuesToSet) || $Field->Optional())
379 $OldKeys = array_keys($OldValue);
380 $NewKeys = array_keys($ValuesToSet);
385 if ($OldKeys != $NewKeys)
387 # clear any existing values for this field 388 $Resource->ClearByField($Field);
390 # if values found to set 391 if (count($ValuesToSet))
393 # set values in resource 394 $Resource->Set($Field, $ValuesToSet);
400 # add field to error list 401 $EmptyFields[] = $Field;
406 $NewValue = trim(GetArrayValue(
408 "F_".$Field->DBFieldName()));
410 if (strlen($NewValue))
412 $SignalResult = $AF->SignalEvent(
413 "EVENT_POST_FIELD_EDIT_FILTER", array(
415 "Resource" => $Resource,
416 "Value" => $NewValue));
418 $NewValue = $SignalResult[
"Value"];
419 $Resource->Set($Field, $NewValue);
422 # allow the field to be unset if it's optional 423 else if ($Field->Optional())
425 $SignalResult = $AF->SignalEvent(
426 "EVENT_POST_FIELD_EDIT_FILTER", array(
428 "Resource" => $Resource,
429 "Value" => $NewValue));
431 $NewValue = $SignalResult[
"Value"];
432 $Resource->Set($Field, $NewValue);
438 # get the new value from the submitted form data 439 $NewValue = GetArrayValue(
441 "F_".$Field->DBFieldName(),
444 foreach ($NewValue as $Key => $ReferenceId)
446 # remove any blank values 447 if (strlen(trim($ReferenceId)) < 1)
449 unset($NewValue[$Key]);
452 # remove any values that don't look right 453 if (!is_numeric($ReferenceId))
455 unset($NewValue[$Key]);
460 $Resource->Set($Field, $NewValue);
465 # (these types handled via special upload mechanisms) 471 # If anything changed, set the update flag. 472 $RecordChanged |= ($OldValue
473 != $Resource->Get($Field));
477 # If the record was changed, modify the appropriate timestamp fields 480 $Resource->UpdateAutoupdateFields(
484 # update search and recommender DBs if configured to do so 485 $Resource->QueueSearchAndRecommenderUpdate();
487 # signal the modified event if the resource isn't a temp one 488 if (!$Resource->IsTempResource())
490 $AF->SignalEvent(
"EVENT_RESOURCE_MODIFY", array(
"Resource" => $Resource));
494 # return list of any empty required fields to caller 505 # for each metadata field that might have an uploaded image 507 $Resource = $this->
User->GetResource();
509 foreach ($Fields as $Field)
511 $FormFieldName =
"F_".$Field->DBFieldName();
513 # if field is modifiable by specified user 514 # and we have an uploaded file for this field 515 if ($Resource->UserCanEditField($this->User, $Field)
516 && isset($Files[$FormFieldName][
"tmp_name"])
517 && is_uploaded_file($Files[$FormFieldName][
"tmp_name"]))
520 $TmpFileName = $Files[$FormFieldName][
"tmp_name"];
521 $NewFile =
new File($TmpFileName, $Resource->Id(), $Field->Id(),
522 $Files[$FormFieldName][
"name"]);
524 # if file save went fine 527 $GLOBALS[
"AF"]->SignalEvent(
528 "EVENT_RESOURCE_FILE_ADD",
531 "Resource" => $Resource,
532 "File" => $NewFile));
537 # set error message and error out 538 switch ($NewFile->Status())
541 $Error = ERR_ZEROLENGTH;
545 $Error = ERR_FILEUPLOADERROR;
548 $ErrParamOne = $Files[$FormFieldName][
'name'];
549 $ErrParamTwo = $NewFile->Status();
553 unlink($TmpFileName);
556 # delete images that have been selected for delete 557 if (isset($FormValues[$FormFieldName.
"_Delete"]))
559 $DeletionIds = $FormValues[$FormFieldName.
"_Delete"];
561 foreach ($DeletionIds as $DeletionId)
563 $File =
new File($DeletionId);
565 $GLOBALS[
"AF"]->SignalEvent(
566 "EVENT_RESOURCE_FILE_DELETE",
569 "Resource" => $Resource,
572 $Resource->Clear($Field, $File->Id());
586 # for each metadata field that might have an uploaded image 588 $Resource = $this->
User->GetResource();
590 foreach ($Fields as $Field)
592 $FormFieldName =
"F_".$Field->DBFieldName();
594 # if field is modifiable by specified user 595 # and we have an uploaded file for this field 596 if ($Resource->UserCanEditField($this->User, $Field)
597 && isset($Files[$FormFieldName][
"tmp_name"])
598 && is_uploaded_file($Files[$FormFieldName][
"tmp_name"]))
600 # create temp copy of file with correct name 601 $TempFile =
"tmp/".$Files[$FormFieldName][
'name'];
602 copy($Files[$FormFieldName][
"tmp_name"], $TempFile);
604 # create new Image object from uploaded file 607 $Field->MaxWidth(), $Field->MaxHeight(),
608 $Field->MaxPreviewWidth(), $Field->MaxPreviewHeight(),
609 $Field->MaxThumbnailWidth(), $Field->MaxThumbnailHeight());
611 # if file save failed 612 if ($Image->Status() !=
AI_OKAY)
614 # set error message and error out 615 switch ($Image->Status())
620 ? ERR_UNSUPPORTEDIMAGEFORMAT : ERR_UNKNOWNIMAGETYPE;
621 $ErrParamOne = $Files[$Field->DBFieldName()][
'name'];
625 $Error = ERR_IMAGEUPLOADERROR;
626 $ErrParamOne = $Files[$FormFieldName][
'name'];
627 $ErrParamTwo = $Image->Status();
633 # attach image to resource 634 $Resource->Set($Field, $Image->Id());
638 # delete images that have been selected for delete 639 if (isset($FormValues[$FormFieldName.
"_Delete"]))
641 $DeletionIds = $FormValues[$FormFieldName.
"_Delete"];
643 foreach ($DeletionIds as $DeletionId)
645 $Resource->Clear($Field,
new SPTImage($DeletionId));
661 $ErrorMessages = NULL)
666 # if errors were found in incoming values 667 if ($FTool->IncomingFieldValuesHaveErrors() || count($UserErrorCodes))
669 # make form fields based on error codes 670 $CodeToFieldMap = array(
686 foreach ($UserErrorCodes as $Code)
688 if (isset($CodeToFieldMap[$Code]))
690 if (is_array(isset($CodeToFieldMap[$Code])))
692 foreach ($CodeToFieldMap[$Code] as $FieldName)
694 $FTool->SetAdditionalErrorFields($FieldName);
699 $FTool->SetAdditionalErrorFields($CodeToFieldMap[$Code]);
704 $FTool->SetAdditionalErrorCodes($ErrorMessages);
712 # mark form fields based on the associated errors 713 $CodeToFieldMap = array(
730 if ($FTool->ErrorsLogged() || count($UserErrorCodes))
732 # if the user did not provide error message strings, get the defaults 733 if (is_null($ErrorMessages))
735 $ErrorMessages = self::GetAdditionalErrorCodes($_POST[
"F_UserName"]);
738 # look up messages for any unknown error codes 739 foreach ($UserErrorCodes as $Code)
741 if (!isset($ErrorMessages[$Code]))
747 # for each reported error 748 foreach ($UserErrorCodes as $Code)
750 # see if this error corresponds to a field or fields 751 if (isset($CodeToFieldMap[$Code]))
753 # if so, log the error for each implicated field 754 foreach ($CodeToFieldMap[$Code] as $Field)
756 $FTool->LogError($ErrorMessages[$Code], $Field);
761 # otherwise, log the error as a general error 762 $FTool->LogError($ErrorMessages[$Code]);
782 $Protocol = isset($_SERVER[
"HTTPS"]) ?
"https://" :
"http://";
784 $ActivationUrlParameters =
"?UN=".urlencode($NewUser->Get(
"UserName"))
785 .
"&AC=".$NewUser->GetActivationCode();
786 $ActivationUrl = $Protocol.$_SERVER[
"SERVER_NAME"]
787 .dirname($_SERVER[
"SCRIPT_NAME"])
788 .
"/index.php".$ActivationUrlParameters.
"&P=ActivateAccount";
789 $ManualActivationUrl = $Protocol.$_SERVER[
"SERVER_NAME"]
790 .dirname($_SERVER[
"SCRIPT_NAME"])
791 .
"/index.php?P=ManuallyActivateAccount";
794 "X-PORTALNAME-X" => $GLOBALS[
"G_SysConfig"]->PortalName(),
795 "X-ACTIVATIONURL-X" => $ActivationUrl,
796 "X-ACTIVATIONPARAMETERS-X" => $ActivationUrlParameters,
797 "X-MANUALACTIVATIONURL-X" => $ManualActivationUrl,
809 $FieldsToExclude = array(), $AdditionalFields = array())
812 array_unshift($UsStates,
"--");
814 # blank Placeholder values overwrite default of "($Label)" 816 "LoginInformation" => array(
818 "Label" =>
"Login Information",
822 "Label" =>
"User Name",
830 "Label" =>
"Password",
836 "PasswordAgain" => array(
838 "Label" =>
"Password (Again)",
842 "Help" =>
"(passwords are case sensitive)",
846 "Label" =>
"E-mail Address",
851 "Help" =>
"(must be valid to activate account)",
853 "EMailAgain" => array(
855 "Label" =>
"E-mail Address (Again)",
861 "UserInformation" => array(
863 "Label" =>
"User Information (Optional)" 867 "Label" =>
"Real Name",
875 "Label" =>
"Web Site",
881 "AddressLineOne" => array(
883 "Label" =>
"Address",
889 "AddressLineTwo" => array(
909 "AllowMultiple" => FALSE,
910 "Options" => $UsStates,
914 "Label" =>
"Zip Code",
922 "Label" =>
"Country",
930 if (isset($ReadOnlyFields))
932 foreach ($ReadOnlyFields as $ReadOnly)
934 $FormFields[$ReadOnly][
"ReadOnly"] = TRUE;
938 if (isset($FieldsToExclude))
940 foreach ($FieldsToExclude as $Exclude)
942 unset($FormFields[$Exclude]);
946 if (isset($AdditionalFields)) {
947 $FormFields = array_merge($FormFields, $AdditionalFields);
962 .
" with an account. If you have forgotten the account user name or" 963 .
" password you can click" 964 .
" <a href=\"index.php?P=ForgottenPasswordComplete&UN=" 965 .urlencode($UserName).
"\">here</a>" 966 .
" to send a reminder via e-mail.",
978 $UserErrorCodes = $UserFactory->TestNewUserValues($FormValues[
"F_UserName"],
979 $FormValues[
"F_Password"], $FormValues[
"F_PasswordAgain"],
980 $FormValues[
"F_EMail"], $FormValues[
"F_EMailAgain"]);
982 $SignupStatus = $GLOBALS[
"AF"]->SignalEvent(
983 "EVENT_USER_SIGNUP_VERIFY",
985 "UserName" => $FormValues[
"F_UserName"],
986 "Password" => $FormValues[
"F_Password"],
987 "EMail" => $FormValues[
"F_EMail"],
990 if ($SignupStatus[
"Status"] !==
U_OKAY)
992 $UserErrorCodes[]= $SignupStatus[
"Status"];
995 return $UserErrorCodes;
998 # ---- 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