00001 <?PHP
00002 #
00003 # FILE: FormTool.php
00004 #
00005 # Part of the Collection Workflow Integration System (CWIS)
00006 # Copyright 2011 Edward Almasy and Internet Scout Project
00007 # http://scout.wisc.edu/
00008 #
00009
00010 class FormTool {
00011
00012 # ---- PUBLIC INTERFACE --------------------------------------------------
00013
00014 # object constructor
00015 function FormTool($FormFields, $AdditionalErrorMessages = NULL)
00016 {
00017 # if form field value is not an array
00018 if (!is_array($FormFields))
00019 {
00020 # look for form field file to include
00021 $PossibleFileNames = array(
00022 "local/include/%NAME%",
00023 "local/include/%NAME%.php",
00024 "local/include/Form--%NAME%.php",
00025 "local/include/SPT--Form--%NAME%.php",
00026 "include/%NAME%",
00027 "include/%NAME%.php",
00028 "include/Form--%NAME%.php",
00029 "include/SPT--Form--%NAME%.php",
00030 );
00031 foreach ($PossibleFileNames as $FileName)
00032 {
00033 $FileName = str_replace("%NAME%", $FormFields, $FileName);
00034 if (file_exists($FileName))
00035 {
00036 $FormFieldFile = $FileName;
00037 break;
00038 }
00039 }
00040
00041 # if form field file was found
00042 if (isset($FormFieldFile))
00043 {
00044 # load form field file (should set $FormFields)
00045 include_once($FormFieldFile);
00046 }
00047 }
00048
00049 # save field info with field name as index
00050 foreach ($FormFields as $Field)
00051 {
00052 $this->Fields[$Field->Name()] = $Field;
00053 }
00054
00055 # save additional error messages (if any)
00056 $this->AdditionalErrorMessages = $AdditionalErrorMessages;
00057
00058 # set default error color
00059 $this->ErrorColor = "red";
00060
00061 # save any additional fields indicated to be marked for error
00062 if (isset($_GET["FTAddErrFields"]) && count($_GET["FTAddErrFields"]))
00063 {
00064 $this->AdditionalErrorFields = explode("!", $_GET["FTAddErrFields"]);
00065 }
00066 else
00067 {
00068 $this->AdditionalErrorFields = array();
00069 }
00070 }
00071
00072 # get/set field values
00073 function ValueForField($FieldName, $NewValue = NULL)
00074 {
00075 return $this->Fields[$FieldName]->Value($NewValue);
00076 }
00077
00078 # checks whether all required form variables are set in $_POST
00079 function AllRequiredVarsAreSet()
00080 {
00081 # assume that all required variables will be found
00082 $AllFound = TRUE;
00083
00084 # for each required form variable
00085 foreach ($this->Fields as $FieldName => $Field)
00086 {
00087 # if variable is not set in $_POST
00088 if (!isset($_POST[$FieldName]) || !strlen($_POST[$FieldName]))
00089 {
00090 # set flag indicating we found a missing var and exit loop
00091 $AllFound = FALSE;
00092 break;
00093 }
00094 }
00095
00096 # report back to caller whether we found on required vars
00097 return $AllFound;
00098 }
00099
00100 # return URL parameter string with form values that are set (from $_POST)
00101 # (returns empty string if none of the form values are set)
00102 # (URL parameter string does not include leading separator (? or &))
00103 function GetValsAsUrlParams($IncludePasswords = FALSE)
00104 {
00105 # assume no values will be found
00106 $UrlParams = "";
00107
00108 # for each form field
00109 foreach ($this->Fields as $FieldName => $Field)
00110 {
00111 # if form value is set and contains something and is not excluded
00112 if (isset($_POST[$FieldName])
00113 && strlen(trim($_POST[$FieldName]))
00114 && (!$Field->IsPassword() || $IncludePasswords))
00115 {
00116 # add value to URL param string
00117 $UrlParams = strlen($UrlParams)
00118 ? $UrlParams."&".$FieldName."=".urlencode($_POST[$FieldName])
00119 : $FieldName."=".urlencode($_POST[$FieldName]);
00120 }
00121 }
00122
00123 # return parameter string to caller
00124 return $UrlParams;
00125 }
00126
00127 # set field values from URL parameters where available
00128 function SetFieldValuesFromUrlParams()
00129 {
00130 # for each field
00131 foreach ($this->Fields as $FieldName => $Field)
00132 {
00133 # if value is available for field in incoming GET parameters
00134 if (isset($_GET[$FieldName]))
00135 {
00136 # set field value
00137 $Field->Value($_GET[$FieldName]);
00138 }
00139 }
00140 }
00141
00142 # check form values for each field and report whether errors found
00143 function IncomingFieldValuesHaveErrors()
00144 {
00145 return (count($_GET) || count($_POST)) ?
00146 (strlen($this->GetErrorCodesAsUrlParams()) ? TRUE : FALSE) : FALSE;
00147 }
00148
00149 # return URL parameter string with codes for any form value errors
00150 # (returns empty string if no errors found)
00151 # (URL parameter string does not include leading separator (? or &))
00152 function GetErrorCodesAsUrlParams()
00153 {
00154 # start with empty error code string
00155 $ErrorCodeString = "";
00156
00157 # for each field value
00158 foreach ($this->Fields as $FieldName => $Field)
00159 {
00160 # if validation function says that value is invalid
00161 $ErrorCode = $this->CheckFieldValue($FieldName);
00162 if ($ErrorCode)
00163 {
00164 # add error code for value to error code string
00165 $ErrorCodeString .= (strlen($ErrorCodeString) ? "!" : "")
00166 .$FieldName."-".$ErrorCode;
00167 }
00168 }
00169
00170 # if values were added to error code string
00171 if (strlen($ErrorCodeString))
00172 {
00173 # prepend name of GET variable to contain error codes
00174 $ErrorCodeString = "FTFieldErrs=".$ErrorCodeString;
00175 }
00176
00177 # if additional error codes were supplied
00178 if (isset($this->AdditionalErrorCodes) && count($this->AdditionalErrorCodes))
00179 {
00180 # for each additional error code
00181 foreach ($this->AdditionalErrorCodes as $Code)
00182 {
00183 # append code to string
00184 $AddCodeString = isset($AddCodeString) ? $AddCodeString."!".$Code
00185 : $Code;
00186 }
00187
00188 # append additional error code string to error code string
00189 $ErrorCodeString .= (strlen($ErrorCodeString) ? "&" : "")
00190 ."FTAddErrCodes=".$AddCodeString;
00191 }
00192
00193 # if additional fields were supplied to be marked as erroneous
00194 if (count($this->AdditionalErrorFields))
00195 {
00196 # for each additional error code
00197 foreach ($this->AdditionalErrorFields as $FieldName)
00198 {
00199 # append code to string
00200 $AddFieldString = isset($AddFieldString) ? $AddFieldString."!".$FieldName
00201 : $FieldName;
00202 }
00203
00204 # append additional error code string to error code string
00205 $ErrorCodeString .= (strlen($ErrorCodeString) ? "&" : "")
00206 ."FTAddErrFields=".$AddFieldString;
00207 }
00208
00209 # return error code string to caller
00210 return $ErrorCodeString;
00211 }
00212
00213 # save additional fields to be marked as having errors
00214 function SetAdditionalErrorFields($FieldNames)
00215 {
00216 # convert to array if needed
00217 if (!is_array($FieldNames))
00218 {
00219 $FieldNames = array($FieldNames);
00220 }
00221
00222 # save fields (if not already present)
00223 foreach ($FieldNames as $FieldName)
00224 {
00225 if (!in_array($FieldName, $this->AdditionalErrorFields))
00226 {
00227 $this->AdditionalErrorFields[] = $FieldName;
00228 }
00229 }
00230 }
00231
00232 # save additional error codes
00233 function SetAdditionalErrorCodes($Codes)
00234 {
00235 # convert to array if needed
00236 if (!is_array($Codes))
00237 {
00238 $Codes = array($Codes);
00239 }
00240
00241 # save codes (if not already present)
00242 foreach ($Codes as $Code)
00243 {
00244 if (!isset($this->AdditionalErrorCodes)
00245 || !in_array($Code, $this->AdditionalErrorCodes))
00246 {
00247 $this->AdditionalErrorCodes[] = $Code;
00248 }
00249 }
00250 }
00251
00252 # convenience function that adds value and err codes to URL
00253 function GetUrlWithValuesAndErrorCodes($BaseUrl, $IncludePasswords = FALSE)
00254 {
00255 $ValParams = $this->GetValsAsUrlParams($IncludePasswords);
00256 $ErrParams = $this->GetErrorCodesAsUrlParams();
00257 $ParamStart = strpos($BaseUrl, "?") ? "&" : "?";
00258 return $BaseUrl
00259 .(strlen($ValParams) ? $ParamStart.$ValParams : "")
00260 .(strlen($ErrParams) ?
00261 (strlen($ValParams) ? "&" : $ParamStart).$ErrParams : "");
00262 }
00263
00264 # get list of error messages based on codes from URL ($_GET)
00265 function GetErrorMessages($EliminateDuplicateMessages = TRUE)
00266 {
00267 # start with empty list
00268 $ErrorList = array();
00269
00270 # if it looks like there are field-specific error messages to be had
00271 if (isset($_GET["FTFieldErrs"]))
00272 {
00273 # split error data into list of fields
00274 $FieldList = explode("!", $_GET["FTFieldErrs"]);
00275
00276 # for each field found
00277 foreach ($FieldList as $FieldListEntry)
00278 {
00279 # split field entry into name and code
00280 list($FieldName, $ErrorCode) = explode("-", $FieldListEntry);
00281
00282 # if we know about this field
00283 if (isset($this->Fields[$FieldName]))
00284 {
00285 # translate error code into message and add to list
00286 $Field = $this->Fields[$FieldName];
00287 $Replacements = array(
00288 "%N" => "<i>".$Field->Name()."</i>",
00289 "%V" => "<i>".$Field->Value()."</i>",
00290 "%L" => "<i>".preg_replace("/:$/", "", $Field->Label())."</i>",
00291 "%C" => "<i>".$ErrorCode."</i>",
00292 );
00293 $Message = $Field->GetInvalidValueMessage($ErrorCode);
00294 $ErrorList[$FieldName] = str_replace(
00295 array_keys($Replacements), $Replacements, $Message);
00296 }
00297 }
00298 }
00299
00300 # if it looks like there are additional general error messages to be had
00301 if (isset($_GET["FTAddErrCodes"]) && count($this->AdditionalErrorMessages))
00302 {
00303 # split error data into list of codes
00304 $CodeList = explode("!", $_GET["FTAddErrCodes"]);
00305
00306 # for each code found
00307 foreach ($CodeList as $Code)
00308 {
00309 # if there is a message corresponding to this code
00310 if (isset($this->AdditionalErrorMessages[$Code]))
00311 {
00312 # add message to list
00313 $ErrorList[$Code] = $this->AdditionalErrorMessages[$Code];
00314 }
00315 }
00316 }
00317
00318 # remove duplicate messages (if requested by caller)
00319 if ($EliminateDuplicateMessages)
00320 {
00321 $NewErrorList = array();
00322 foreach ($ErrorList as $Code => $Message)
00323 {
00324 if (!in_array($Message, $NewErrorList))
00325 {
00326 $NewErrorList[$Code] = $Message;
00327 }
00328 }
00329 $ErrorList = $NewErrorList;
00330 }
00331
00332 # return list of error messages to caller
00333 return $ErrorList;
00334 }
00335
00336 # print tags for specified field
00337 function PrintField($FieldName)
00338 {
00339 $this->Fields[$FieldName]->PrintField(
00340 ($this->ErrorCodesAvailable() && $this->CheckFieldValue($FieldName))
00341 || in_array($FieldName, $this->AdditionalErrorFields));
00342 }
00343 function PrintLabelForField($FieldName)
00344 {
00345 $this->Fields[$FieldName]->PrintLabel(
00346 ($this->ErrorCodesAvailable() && $this->CheckFieldValue($FieldName))
00347 || in_array($FieldName, $this->AdditionalErrorFields));
00348 }
00349 function PrintInputForField($FieldName)
00350 {
00351 $this->Fields[$FieldName]->PrintInput(
00352 ($this->ErrorCodesAvailable() && $this->CheckFieldValue($FieldName))
00353 || in_array($FieldName, $this->AdditionalErrorFields));
00354 }
00355
00356 # report whether error codes are available
00357 function ErrorCodesAvailable()
00358 {
00359 return isset($_GET["FTFieldErrs"]) || isset($_GET["FTAddErrCodes"]);
00360 }
00361
00362 # return array of US state names with two-letter abbreviations as index
00363 static function GetArrayOfUsStates()
00364 {
00365 return array(
00366 "" => "--",
00367 "AL" => "Alabama",
00368 "AK" => "Alaska",
00369 "AZ" => "Arizona",
00370 "AR" => "Arkansas",
00371 "CA" => "California",
00372 "CO" => "Colorado",
00373 "CT" => "Connecticut",
00374 "DE" => "Delaware",
00375 "DC" => "District of Columbia",
00376 "FL" => "Florida",
00377 "GA" => "Georgia",
00378 "HI" => "Hawaii",
00379 "ID" => "Idaho",
00380 "IL" => "Illinois",
00381 "IN" => "Indiana",
00382 "IA" => "Iowa",
00383 "KS" => "Kansas",
00384 "KY" => "Kentucky",
00385 "LA" => "Louisiana",
00386 "ME" => "Maine",
00387 "MD" => "Maryland",
00388 "MA" => "Massachusetts",
00389 "MI" => "Michigan",
00390 "MN" => "Minnesota",
00391 "MS" => "Mississippi",
00392 "MO" => "Missouri",
00393 "MT" => "Montana",
00394 "NE" => "Nebraska",
00395 "NV" => "Nevada",
00396 "NH" => "New Hampshire",
00397 "NJ" => "New Jersey",
00398 "NM" => "New Mexico",
00399 "NY" => "New York",
00400 "NC" => "North Carolina",
00401 "ND" => "North Dakota",
00402 "OH" => "Ohio",
00403 "OK" => "Oklahoma",
00404 "OR" => "Oregon",
00405 "PA" => "Pennsylvania",
00406 "RI" => "Rhode Island",
00407 "SC" => "South Carolina",
00408 "SD" => "South Dakota",
00409 "TN" => "Tennessee",
00410 "TX" => "Texas",
00411 "UT" => "Utah",
00412 "VT" => "Vermont",
00413 "VA" => "Virginia",
00414 "WA" => "Washington",
00415 "WV" => "West Virginia",
00416 "WI" => "Wisconsin",
00417 "WY" => "Wyoming",
00418 );
00419 }
00420
00421
00422 # ---- PRIVATE INTERFACE -------------------------------------------------
00423
00424 var $Fields;
00425 var $ErrorColor;
00426 var $AdditionalErrorCodes;
00427 var $AdditionalErrorFields;
00428 var $AdditionalErrorMessages;
00429
00430 # check form (POST) value for specified field and return error code
00431 function CheckFieldValue($FieldName)
00432 {
00433 $Value = isset($_POST[$FieldName]) ? $_POST[$FieldName]
00434 : (isset($_GET[$FieldName]) ? $_GET[$FieldName] : NULL);
00435 $ErrorCode = $this->Fields[$FieldName]->IsInvalidValue($Value);
00436 return $ErrorCode;
00437 }
00438 }