Skip to content

Commit

Permalink
Fixed issue #17578: PSPP reports warnings when opening SPSS SAV file …
Browse files Browse the repository at this point in the history
…using Export to SAV (#2034)
  • Loading branch information
adamzammit committed Sep 9, 2021
1 parent eea8dbe commit b44112a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
56 changes: 39 additions & 17 deletions application/core/plugins/ExportSPSSsav/SPSSWriter.php
Expand Up @@ -32,6 +32,8 @@ function __construct($pluginsettings)
$this->separator = ',';
$this->hasOutputHeader = false;
$this->spssfileversion = $pluginsettings['spssfileversion']['current'];


if ($this->spssfileversion >= 13) {
$this->maxStringLength = 32767; // for SPSS version 13 and above
} else {
Expand Down Expand Up @@ -312,11 +314,18 @@ protected function updateCustomresponsemap()
foreach ($this->customResponsemap as $iRespId => &$aResponses) {
// go through variables and response items


//relevant types for SPSS are numeric (need to know largest number and number of decimal places), date and string
foreach ($aResponses as $iVarid => &$response) {
$response = trim($response);
$iDatatype = 5;
$iStringlength = 1;
if ($response != '') {

if ($response == '-oth-') {
$this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['spssothervaluelabel'] = true;
}

$numberresponse = trim($response);
if ($this->customFieldmap['info']['surveyls_numberformat'] == 1) {
// if settings: decimal seperator==','
Expand Down Expand Up @@ -351,22 +360,18 @@ protected function updateCustomresponsemap()
$iNumberWidth = strlen($response);
$iDecimalPlaces = $iNumberWidth - ($tmpdpoint + 1);
}

}
}
} else {
// non-numeric response
$iDatatype = 1; //string
$iStringlength = strlen($response); //for strings we need the length for the format and the data type
}
} else {
$iDatatype = 1; // response = ""
$iStringlength = 1;
}

// initialize format and type (default: empty)
if (!isset($aSPSStypelist[$this->headersSGQA[$iVarid]]['type'])) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] = 1;
$aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] = 5;
}
if (!isset($aSPSStypelist[$this->headersSGQA[$iVarid]]['format'])) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['format'] = 0;
Expand All @@ -376,38 +381,39 @@ protected function updateCustomresponsemap()
}

// Does the variable need a higher datatype because of the current response?
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] < $iDatatype) {
if ($iDatatype < $aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] ) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] = $iDatatype;
}

// if datatype is a string, set needed stringlength
if ($iDatatype == 1) {
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] == 1 || $aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] == 5) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['decimals'] = -1;
// Does the variable need a higher stringlength because of the current response?
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['format'] < $iStringlength) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['format'] = $iStringlength;
}

}
// if datatype is a numeric, set needed width and decimals
if ($iDatatype == 2) {
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['type'] == 2) {
// Does the variable need a higher length because of the current response?
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['format'] < $iNumberWidth) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['format'] = $iNumberWidth;
}
if ($aSPSStypelist[$this->headersSGQA[$iVarid]]['decimals'] < $iDecimalPlaces) {
$aSPSStypelist[$this->headersSGQA[$iVarid]]['decimals'] = $iDecimalPlaces;
}

}
//write the recoded response back to the response array
$this->customResponsemap[$iRespId][$iVarid] = $response;
}
}


// translate coding into SPSS datatypes, format and length
foreach ($aSPSStypelist as $variable => $data) {

switch ($data['type']) {
case 5:
case 1:
$this->customFieldmap['questions'][$variable]['spsswidth'] = min($data['format'], $this->maxStringLength);
$this->customFieldmap['questions'][$variable]['spssformat'] = Variable::FORMAT_TYPE_A;
Expand Down Expand Up @@ -459,8 +465,8 @@ public function close()
}
$tmpvar['label'] = $question['varlabel'];
$tmpwidth = $question['spsswidth'];
//export value labels if they exist
if (!empty($this->customFieldmap['answers'][$question['qid']]) && $question['commentother'] == false) {
//export value labels if they exist (not for time questions)
if (!empty($this->customFieldmap['answers'][$question['qid']]) && $question['commentother'] == false && $question['type'] != "answer_time") {
$tmpvar['values'] = array();
foreach($this->customFieldmap['answers'][$question['qid']] as $aAnswercodes) {
foreach($aAnswercodes as $sAnscode => $aAnswer) {
Expand All @@ -476,6 +482,10 @@ public function close()
}
}
}
//if other is set add as value label
if (isset($question['spssothervaluelabel']) && $question['spssothervaluelabel'] == true) {
$tmpvar['values']['-oth-'] = "Other";
}
}
$tmpvar['width'] = $tmpwidth;
$tmpvar['columns'] = 8;
Expand All @@ -487,11 +497,23 @@ public function close()
$header = array(
'prodName' => '@(#) IBM SPSS STATISTICS 64-bit Macintosh 23.0.0.0',
'creationDate' => date('d M y'),
'creationTime' => date('H:M:s'),
'weightIndex' => 0);


$writer = new \SPSS\Sav\Writer(['header' => $header, 'variables' => $variables]);
'creationTime' => date('H:i:s'),
'weightIndex' => 0,
);

$info = array(
'machineInteger' => [
'machineCode' => 720,
'version' => [23, 0, 0],
],
'machineFloatingPoint' => [
'sysmis' => -1.7976931348623157e+308,
'highest' => 1.7976931348623157e+308,
'lowest' => -1.7976931348623155e+308,
],
);

$writer = new \SPSS\Sav\Writer(['header' => $header, 'info' => $info, 'variables' => $variables]);

foreach ($this->customResponsemap as $aResponses) {
$tmpdat = array();
Expand Down
4 changes: 2 additions & 2 deletions application/core/plugins/ExportSPSSsav/config.xml
Expand Up @@ -4,10 +4,10 @@
<name>ExportSPSSsav</name>
<type>plugin</type>
<creationDate>2021-03-31</creationDate>
<lastUpdate>2021-03-31</lastUpdate>
<lastUpdate>2021-08-02</lastUpdate>
<author>Adam Zammit</author>
<authorUrl>https://www.acspri.org.au</authorUrl>
<version>1.0.0</version>
<version>1.0.4</version>
<license>GNU General Public License version 2 or later</license>
<description><![CDATA[Core: Export survey results to an SPSS sav file]]></description>
</metadata>
Expand Down

0 comments on commit b44112a

Please sign in to comment.