From abebe9bd2706763883c2783c1e1ca227ddb91d91 Mon Sep 17 00:00:00 2001 From: Gabriel Jenik Date: Thu, 11 Mar 2021 14:07:00 -0300 Subject: [PATCH] Fixed issue #16939: exporting list question with 'other' to SPSS does not read all data (#1791) --- application/controllers/admin/export.php | 12 ++++++++++++ application/helpers/export_helper.php | 25 ++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/application/controllers/admin/export.php b/application/controllers/admin/export.php index 0657967c0cb..e8814c84769 100644 --- a/application/controllers/admin/export.php +++ b/application/controllers/admin/export.php @@ -554,6 +554,18 @@ public function exportspss() } } + // Add instructions to change variable type and recode 'Other' option. + // This is needed when all answer option codes are numeric but the question has 'Other' enabled, + // because the variable is initialy set as alphanumeric in order to hold the '-oth-' value. See issue #16939 + foreach ($fields as $field) { + if (isset($field['needsAlterType'])) { + echo "RECODE {$field['id']} (\"-oth-\" = \"666666\").\n"; + echo "EXECUTE.\n"; + echo "ADD VALUE LABELS {$field['id']} 666666 \"other\".\n"; + echo "ALTER TYPE {$field['id']} (F6.0).\n"; + } + } + foreach ($fields as $field) { if ($field['scale'] !== '') { switch ($field['scale']) { diff --git a/application/helpers/export_helper.php b/application/helpers/export_helper.php index 591f924d270..2fa7bbce76b 100644 --- a/application/helpers/export_helper.php +++ b/application/helpers/export_helper.php @@ -17,12 +17,15 @@ * Strips html tags and replaces new lines * * @param $string +* @param $removeOther if 'true', removes '-oth-' from the string. * @return string */ -function stripTagsFull($string) +function stripTagsFull($string, $removeOther = true) { $string = flattenText($string, false, true); // stripo whole + html_entities - $string = str_replace('-oth', '', $string);// Why ? + if ($removeOther) { + $string = str_replace('-oth-', '', $string); + } //The backslashes must be escaped twice, once for php, and again for the regexp $string = str_replace("'|\\\\'", "'", $string); return $string; @@ -252,7 +255,7 @@ function SPSSExportData($iSurveyID, $iLength, $na = '', $sEmptyAnswerValue = '', break; // Break inside if : comment and other are string to be filtered } // else do default action default: - $strTmp = mb_substr(stripTagsFull($row[$fieldno]), 0, $iLength); + $strTmp = mb_substr(stripTagsFull($row[$fieldno], false), 0, $iLength); if (trim($strTmp) != '') { echo quoteSPSS($strTmp, $q, $field); } elseif ($row[$fieldno] === '') { @@ -314,7 +317,7 @@ function SPSSGetValues($field = array(), $qidattributes = null, $language) foreach ($result as $row) { $answers[] = array( 'code' => $row['code'], - 'value' => mb_substr(stripTagsFull($row["answer"]), 0, $length_vallabel), + 'value' => mb_substr(stripTagsFull($row["answer"], false), 0, $length_vallabel), ); } } @@ -408,8 +411,18 @@ function SPSSGetValues($field = array(), $qidattributes = null, $language) $spsstype = 'A'; } } + // For questions types with answer options, if all answer codes are numeric but "Other" option is enabled, + // field should be exported as SPSS type 'A', size 6. See issue #16939 + if (strpos("!LORFH1", $field['LStype']) !== false && $spsstype == 'F') { + $oQuestion = Question::model()->findByPk($field["qid"]); + if ($oQuestion->other == 'Y') { + $spsstype = 'A'; + $size = 6; + } + } $answers['SPSStype'] = $spsstype; $answers['size'] = $size; + $answers['needsAlterType'] = true; return $answers; } else { /* Not managed (currently): url, IP, … */ @@ -649,6 +662,10 @@ function SPSSFieldMap($iSurveyID, $prefix = 'V', $sLanguage = '') $tempArray['SPSStype'] = $answers['SPSStype']; unset($answers['SPSStype']); } + if (isset($answers['needsAlterType'])) { + $tempArray['needsAlterType'] = $answers['needsAlterType']; + unset($answers['needsAlterType']); + } if (!empty($answers)) { $tempArray['answers'] = $answers; }