function checkFields($aData, $zData = false) { // Checks fields before submission of data. global $_AUTH, $_SETT; $aForm = $this->getForm(); $aFormInfo = array(); if ($aForm) { $aFormInfo = $aForm[0]; if (!in_array($aFormInfo[0], array('GET', 'POST'))) { // We're not working on a full form array, possibly an incomplete VOT form. $aFormInfo = array('POST'); } else { unset($aForm[0]); } } else { // No form information available. $aForm = array(); } if (lovd_getProjectFile() != '/import.php') { // Always mandatory... unless importing. $this->aCheckMandatory[] = 'password'; } $aHeaders = array(); // Validate form by looking at the form itself, and check what's needed. foreach ($aForm as $aField) { if (!is_array($aField)) { // 'skip', 'hr', etc... continue; } @(list($sHeader, $sHelp, $sType, $sName) = $aField); if (lovd_getProjectFile() == '/import.php') { // During import, we don't mention the field names how they appear on screen, but using their IDs which are used in the file. $sHeader = $sName; } $aHeaders[$sName] = $sHeader; // Trim() all fields. We don't want those spaces in the database anyway. if (lovd_getProjectFile() != '/import.php' && isset($aData[$sName]) && !is_array($aData[$sName])) { $GLOBALS['_' . $aFormInfo[0]][$sName] = trim($GLOBALS['_' . $aFormInfo[0]][$sName]); $aData[$sName] = trim($aData[$sName]); } // Mandatory fields, as defined by child object. if (in_array($sName, $this->aCheckMandatory) && (!isset($aData[$sName]) || $aData[$sName] === '')) { lovd_errorAdd($sName, 'Please fill in the \'' . $sHeader . '\' field.'); } if ($sType == 'select') { if (!empty($aField[7])) { // The browser fails to send value if selection list w/ multiple selection options is left empty. // This is causing notices in the code. if (!isset($aData[$sName])) { $GLOBALS['_' . $aFormInfo[0]][$sName] = array(); $aData[$sName] = array(); } } // Simple check on non-custom columns (custom columns have their own function for this) to see if the given value is actually allowed. // 0 is a valid entry for the check for mandatory fields, so we should also check if 0 is a valid entry in the selection list! if (strpos($sName, '/') === false && isset($aData[$sName]) && $aData[$sName] !== '') { $Val = $aData[$sName]; $aOptions = array_keys($aField[5]); if (lovd_getProjectFile() == '/import.php' && !is_array($Val)) { $Val = explode(';', $Val); // Normally the form sends an array, but from the import I need to create an array. } elseif (!is_array($Val)) { $Val = array($Val); } foreach ($Val as $sValue) { $sValue = trim($sValue); // Trim whitespace from $sValue to ensure match independent of whitespace. if (!in_array($sValue, $aOptions)) { if (lovd_getProjectFile() == '/import.php') { lovd_errorAdd($sName, 'Please select a valid entry from the \'' . $sHeader . '\' selection box, \'' . strip_tags($sValue) . '\' is not a valid value. Please choose from these options: \'' . implode('\', \'', $aOptions) . '\'.'); } else { lovd_errorAdd($sName, 'Please select a valid entry from the \'' . $sHeader . '\' selection box, \'' . strip_tags($sValue) . '\' is not a valid value.'); } } } } } elseif ($sType == 'checkbox') { // The browser fails to send value if checkbox is left empty. // This is causing problems sometimes with MySQL, since INT // columns can't receive an empty string if STRICT is on. if (!isset($aData[$sName])) { $GLOBALS['_' . $aFormInfo[0]][$sName] = 0; $aData[$sName] = 0; } elseif (!in_array($aData[$sName], array('0', '1'))) { lovd_errorAdd($sName, 'The field \'' . $sHeader . '\' must contain either a \'0\' or a \'1\'.'); } } if ($sName == 'password') { // Password is in the form, it must be checked. Assuming here that it is also considered mandatory. if (!empty($aData['password']) && !lovd_verifyPassword($aData['password'], $_AUTH['password'])) { lovd_errorAdd('password', 'Please enter your correct password for authorization.'); } } } // Check all fields that we receive for data type and maximum length. // No longer to this through $aForm, because when importing, // we do have data to check but no $aForm entry linked to it. foreach ($aData as $sFieldname => $sFieldvalue) { if (!is_string($sFieldvalue)) { // Checks below currently do not handle non-string values. continue; } $sNameClean = preg_replace('/^\\d{' . $_SETT['objectid_length']['transcripts'] . '}_/', '', $sFieldname); // Remove prefix (transcriptid) that LOVD_TranscriptVariants puts there. if (isset($aHeaders[$sFieldname])) { $sHeader = $aHeaders[$sFieldname]; } else { $sHeader = $sFieldname; } // Checking free text fields for max length, data types, etc. if ($sMySQLType = lovd_getColumnType(constant($this->sTable), $sNameClean)) { // FIXME; we're assuming here, that $sName equals the database name. Which is true in probably most/every case, but even so... // FIXME; select fields might also benefit from having this check (especially for import). // Check max length. $nMaxLength = lovd_getColumnLength(constant($this->sTable), $sNameClean); if (!empty($sFieldvalue)) { // For numerical columns, maxlength works differently! if (in_array($sMySQLType, array('DECIMAL', 'DECIMAL_UNSIGNED', 'FLOAT', 'FLOAT_UNSIGNED', 'INT', 'INT_UNSIGNED'))) { // SIGNED cols: negative values. if (in_array($sMySQLType, array('DECIMAL', 'INT')) && (int) $sFieldvalue < (int) ('-' . str_repeat('9', $nMaxLength))) { lovd_errorAdd($sFieldname, 'The \'' . $sHeader . '\' field is limited to numbers no lower than -' . str_repeat('9', $nMaxLength) . '.'); } // ALL numerical cols (except floats): positive values. if (substr($sMySQLType, 0, 5) != 'FLOAT' && (int) $sFieldvalue > (int) str_repeat('9', $nMaxLength)) { lovd_errorAdd($sFieldname, 'The \'' . $sHeader . '\' field is limited to numbers no higher than ' . str_repeat('9', $nMaxLength) . '.'); } } elseif (strlen($sFieldvalue) > $nMaxLength) { lovd_errorAdd($sFieldname, 'The \'' . $sHeader . '\' field is limited to ' . $nMaxLength . ' characters, you entered ' . strlen($sFieldvalue) . '.'); } } // Check data type. if (!empty($sFieldvalue)) { switch ($sMySQLType) { case 'DATE': if (!lovd_matchDate($sFieldvalue)) { lovd_errorAdd($sFieldname, 'The field \'' . $sHeader . '\' must contain a date in the format YYYY-MM-DD, "' . htmlspecialchars($sFieldvalue) . '" does not match.'); } break; case 'DATETIME': if (!preg_match('/^[0-9]{4}[.\\/-][0-9]{2}[.\\/-][0-9]{2}( [0-9]{2}\\:[0-9]{2}\\:[0-9]{2})?$/', $sFieldvalue)) { lovd_errorAdd($sFieldname, 'The field \'' . $sHeader . '\' must contain a date, possibly including a time, in the format YYYY-MM-DD HH:MM:SS, "' . htmlspecialchars($sFieldvalue) . '" does not match.'); } break; case 'DECIMAL': case 'DECIMAL_UNSIGNED': case 'FLOAT': case 'FLOAT_UNSIGNED': if (!is_numeric($sFieldvalue) || substr($sMySQLType, -8) == 'UNSIGNED' && $sFieldvalue < 0) { lovd_errorAdd($sFieldname, 'The field \'' . $sHeader . '\' must contain a' . (substr($sMySQLType, -8) != 'UNSIGNED' ? '' : ' positive') . ' number, "' . htmlspecialchars($sFieldvalue) . '" does not match.'); } break; case 'INT': case 'INT_UNSIGNED': if (!preg_match('/^' . ($sMySQLType != 'INT' ? '' : '\\-?') . '[0-9]*$/', $sFieldvalue)) { lovd_errorAdd($sFieldname, 'The field \'' . $sHeader . '\' must contain a' . ($sMySQLType == 'INT' ? 'n' : ' positive') . ' integer, "' . htmlspecialchars($sFieldvalue) . '" does not match.'); } break; } } } } return $aData; }
// Select_options. if (!empty($_POST['select_options'])) { $aOptions = explode("\r\n", $_POST['select_options']); foreach ($aOptions as $n => $sOption) { if (!preg_match('/^([^=]+|[A-Z0-9 \\/\\()?._+-]+ *= *[^=]+)$/i', $sOption)) { lovd_errorAdd('select_options', 'Select option #' . ($n + 1) . ' "' . htmlspecialchars($sOption) . '" not understood.'); } } } if (!empty($_POST['default_val'])) { // Default values in text field cannot contain a quote. if ($_POST['form_type'] == 'text' && !preg_match('/^[^"]*$/', $_POST['default_val'])) { lovd_errorAdd('default_val', 'The \'Default value\' field can not contain a quote.'); } // Format for the DATE/DATETIME column types. if ($_POST['form_type'] == 'date' && !lovd_matchDate($_POST['default_val'], !empty($_POST['time']))) { lovd_errorAdd('default_val', 'The \'Default value\' for the date field should be like YYYY-MM-DD' . (empty($_POST['time']) ? '.' : ' HH:MM:SS.')); } } if (!lovd_error()) { // Build proper values and send them through. $sMySQLType = ''; $sFormType = ''; $sPregPattern = ''; // Store vars in $_SESSION... $aStore = array('name', 'help_text', 'description_form', 'size', 'rows', 'maxlength', 'scale', 'time', 'preg_pattern', 'unsigned', 'default_val', 'select', 'select_options', 'select_all'); foreach ($aStore as $key) { if (!isset($_POST[$key])) { $_POST[$key] = ''; } $_SESSION['data_wizard'][$_GET['workID']][$key] = $_POST[$key];
$aLine[$sCol] = $_AUTH['id']; } elseif (!$zData || in_array($sCol, $aColumns)) { if ($aLine[$sCol] && !in_array($aLine[$sCol], $aUsers)) { lovd_errorAdd('import', 'Error (' . $sCurrentSection . ', line ' . $nLine . '): ' . $sCol . ' value "' . htmlspecialchars($aLine[$sCol]) . '" refers to non-existing user.'); } elseif (($sCol != 'edited_by' || $aLine['edited_date']) && !$aLine[$sCol]) { // Edited_by is only filled in if empty and edited_date is filled in. $aLine[$sCol] = $_AUTH['id']; } } } foreach (array('created_date', 'edited_date') as $sCol) { if ($zData && $sCol == 'edited_date') { // If zData is set, always set the edited date. $aLine[$sCol] = $sDate; } elseif (!$zData || in_array($sCol, $aColumns)) { if ($aLine[$sCol] && !lovd_matchDate($aLine[$sCol], true)) { lovd_errorAdd('import', 'Error (' . $sCurrentSection . ', line ' . $nLine . '): ' . $sCol . ' value "' . htmlspecialchars($aLine[$sCol]) . '" is not a correct date format, use the format YYYY-MM-DD HH:MM:SS.'); } elseif (($sCol == 'created_date' || $aLine['edited_by']) && !$aLine[$sCol]) { // Edited_date is only filled in if empty and edited_by is filled in. $aLine[$sCol] = $sDate; } } } // Can't be edited earlier than created. if (isset($aLine['edited_date']) && $aLine['edited_date'] && $aLine['edited_date'] < $aLine['created_date']) { $aLine['edited_date'] = $aLine['created_date']; } // If you're not manager or higher, there are some restrictions. if ($_AUTH['level'] < LEVEL_MANAGER) { $aLine['created_by'] = $_AUTH['id']; $aLine['created_date'] = $sDate;