From 517cc04acd9e0dcc072e3ffa034b50919c80ae4f Mon Sep 17 00:00:00 2001 From: cmoyon Date: Fri, 15 Apr 2016 14:14:55 +0200 Subject: [PATCH 1/5] Adding reponse identifier callback --- model/flyExporter/extractor/QtiExtractor.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/model/flyExporter/extractor/QtiExtractor.php b/model/flyExporter/extractor/QtiExtractor.php index a2cafac47d..075d2b286c 100644 --- a/model/flyExporter/extractor/QtiExtractor.php +++ b/model/flyExporter/extractor/QtiExtractor.php @@ -404,6 +404,17 @@ public function getInteractionType($interaction) } } + /** + * Callback to retrieve interaction response identifier + * + * @param $interaction + * @return mixed + */ + public function getReponseIdentifier($interaction) + { + return $interaction['responseIdentifier']; + } + /** * Get human readable declaration class * @return string From b483eeda689dcb586dfc4e0cf612a8d8060c03d1 Mon Sep 17 00:00:00 2001 From: cmoyon Date: Fri, 15 Apr 2016 14:42:19 +0200 Subject: [PATCH 2/5] Adding update & install script --- config/default/simpleExporter.conf.php | 6 ++++++ manifest.php | 2 +- model/flyExporter/extractor/QtiExtractor.php | 2 +- scripts/update/Updater.php | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/config/default/simpleExporter.conf.php b/config/default/simpleExporter.conf.php index b1dd3c1aaf..c6239ee695 100644 --- a/config/default/simpleExporter.conf.php +++ b/config/default/simpleExporter.conf.php @@ -45,6 +45,12 @@ 'callback' => 'getNumberOfChoices' ) ), + 'responseIdentifier' => array ( + 'extractor' => 'QtiExtractor', + 'parameters' => array ( + 'callback' => 'getResponseIdentifier', + ) + ), 'BR' => array ( 'extractor' => 'QtiExtractor', 'parameters' => array ( diff --git a/manifest.php b/manifest.php index 99da5573f9..5adf22dcb3 100755 --- a/manifest.php +++ b/manifest.php @@ -26,7 +26,7 @@ 'label' => 'QTI item model', 'description' => 'TAO QTI item model', 'license' => 'GPL-2.0', - 'version' => '2.21.0', + 'version' => '2.22.0', 'author' => 'Open Assessment Technologies', 'requires' => array( 'taoItems' => '>=2.13', diff --git a/model/flyExporter/extractor/QtiExtractor.php b/model/flyExporter/extractor/QtiExtractor.php index 075d2b286c..ced1e6d9ef 100644 --- a/model/flyExporter/extractor/QtiExtractor.php +++ b/model/flyExporter/extractor/QtiExtractor.php @@ -410,7 +410,7 @@ public function getInteractionType($interaction) * @param $interaction * @return mixed */ - public function getReponseIdentifier($interaction) + public function getResponseIdentifier($interaction) { return $interaction['responseIdentifier']; } diff --git a/scripts/update/Updater.php b/scripts/update/Updater.php index 22aac70194..74cfb52f07 100644 --- a/scripts/update/Updater.php +++ b/scripts/update/Updater.php @@ -21,6 +21,7 @@ namespace oat\taoQtiItem\scripts\update; +use oat\oatbox\service\ConfigurableService; use oat\taoQtiItem\install\scripts\addValidationSettings; use oat\taoQtiItem\install\scripts\createExportDirectory; use oat\taoQtiItem\model\flyExporter\extractor\OntologyExtractor; @@ -318,6 +319,22 @@ public function update($initialVersion){ } $this->skip('2.20.0', '2.21.0'); + + if ($this->isVersion('2.21.0')) { + $simpleExporter = $this->getServiceManager()->get(SimpleExporter::SERVICE_ID); + $columns = $simpleExporter->getOption('columns'); + $columns['responseIdentifier'] = array ( + 'extractor' => 'QtiExtractor', + 'parameters' => array ( + 'callback' => 'getResponseIdentifier', + ) + ); + $simpleExporter->setOption('columns', $columns); + $simpleExporter->setServiceManager($this->getServiceManager()); + $this->getServiceManager()->register(SimpleExporter::SERVICE_ID, $simpleExporter); + + $this->setVersion('2.22.0'); + } } } From 1b2837a253509258ba1690def21478ffc77cb8da Mon Sep 17 00:00:00 2001 From: cmoyon Date: Fri, 15 Apr 2016 15:02:50 +0200 Subject: [PATCH 3/5] Move responseIdentifier in right position --- scripts/update/Updater.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/update/Updater.php b/scripts/update/Updater.php index 74cfb52f07..bfb82cd4bf 100644 --- a/scripts/update/Updater.php +++ b/scripts/update/Updater.php @@ -323,12 +323,16 @@ public function update($initialVersion){ if ($this->isVersion('2.21.0')) { $simpleExporter = $this->getServiceManager()->get(SimpleExporter::SERVICE_ID); $columns = $simpleExporter->getOption('columns'); - $columns['responseIdentifier'] = array ( + $responseIdentifier['responseIdentifier'] = array ( 'extractor' => 'QtiExtractor', 'parameters' => array ( 'callback' => 'getResponseIdentifier', ) ); + + $offset = array_search('BR', array_keys($columns)); + $columns = array_slice($columns, 0, $offset, true) + $responseIdentifier + array_slice($columns, $offset, NULL, true); + $simpleExporter->setOption('columns', $columns); $simpleExporter->setServiceManager($this->getServiceManager()); $this->getServiceManager()->register(SimpleExporter::SERVICE_ID, $simpleExporter); From e395b24f4375676b912d33b9399b10a5caa0f8dc Mon Sep 17 00:00:00 2001 From: cmoyon Date: Mon, 18 Apr 2016 09:48:01 +0200 Subject: [PATCH 4/5] TAO-2520: change trim to xml output sanitization --- model/flyExporter/extractor/QtiExtractor.php | 31 +++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/model/flyExporter/extractor/QtiExtractor.php b/model/flyExporter/extractor/QtiExtractor.php index a2cafac47d..817d54b2ab 100644 --- a/model/flyExporter/extractor/QtiExtractor.php +++ b/model/flyExporter/extractor/QtiExtractor.php @@ -263,10 +263,12 @@ protected function extractInteractions() $interaction['responseIdentifier'] = $interactionNode->item($i)->getAttribute('responseIdentifier'); $rightAnswer = $this->xpath->query('./qti:responseDeclaration[@identifier="' . $interaction['responseIdentifier'] . '"]'); if ($rightAnswer->length > 0) { - $answers = trim($rightAnswer->item(0)->textContent); + $answers = $rightAnswer->item(0)->textContent; if (!empty($answers)) { foreach(explode(PHP_EOL, $answers) as $answer) { - $interaction['responses'][] = trim($answer); + if (trim($answer)!=='') { + $interaction['responses'][] = $answer; + } } } } @@ -284,7 +286,8 @@ protected function extractInteractions() if (!empty($choiceNode) && $choiceNode->length > 0) { for($j=0 ; $j < $choiceNode->length ; $j++) { $identifier = $choiceNode->item($j)->getAttribute('identifier'); - $value = preg_replace('/\s+/', '', $choiceNode->item($j)->nodeValue); + $value = $this->sanitizeNodeToValue($this->dom->saveHtml($choiceNode->item($j))); + //Image if ($value==='') { $imgNode = $this->xpath->query('./qti:img/@src', $choiceNode->item($j)); @@ -302,6 +305,23 @@ protected function extractInteractions() return $this; } + /** + * Remove first and last xml tag from string + * Transform variable to string value + * + * @param $value + * @return string + */ + protected function sanitizeNodeToValue($value) + { + $first = strpos($value, '>')+1; + $last = strrpos($value, '<')-$first; + $value = substr($value, $first, $last); + $value = strval($value); + + return $value; + } + /** * Callback to retrieve right answers * Find $responses & resolve identifier with $choices @@ -364,16 +384,13 @@ public function getChoices($interaction) if (isset($interaction['choices'])) { $i = 1; foreach ($interaction['choices'] as $identifier => $choice) { - \common_Logger::d($interaction['type']); - \common_Logger::d($choice); if (!$choice!=='') { $return['choice_' . $i] = $choice; } else { $return['choice_' . $i] = $identifier; } - \common_Logger::d($return['choice_' . $i]); - \common_Logger::d('--------- '); + $i++; } if ($this->headerChoice > count($return)) { From 8b39759ff890593a1969f59f9b88b22889e55c8c Mon Sep 17 00:00:00 2001 From: cmoyon Date: Mon, 18 Apr 2016 11:20:30 +0200 Subject: [PATCH 5/5] TAO-2520: remove quote at end of xml data --- model/flyExporter/extractor/QtiExtractor.php | 11 ++++++----- model/flyExporter/simpleExporter/ItemExporter.php | 13 +++++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/model/flyExporter/extractor/QtiExtractor.php b/model/flyExporter/extractor/QtiExtractor.php index 817d54b2ab..7712177deb 100644 --- a/model/flyExporter/extractor/QtiExtractor.php +++ b/model/flyExporter/extractor/QtiExtractor.php @@ -317,9 +317,8 @@ protected function sanitizeNodeToValue($value) $first = strpos($value, '>')+1; $last = strrpos($value, '<')-$first; $value = substr($value, $first, $last); - $value = strval($value); - - return $value; + $value = str_replace('"', "'", $value); + return trim($value); } /** @@ -334,7 +333,7 @@ public function getRightAnswer($interaction, $params) $return = []; if (isset($interaction['responses'])) { foreach ($interaction['responses'] as $response) { - $allResponses = explode(' ', $response); + $allResponses = explode(' ', trim($response)); $returnResponse = []; foreach ($allResponses as $partialResponse) { @@ -345,7 +344,9 @@ public function getRightAnswer($interaction, $params) $returnResponse[] = $partialResponse; } } - $return[] = implode(' ', $returnResponse); + if (!empty($returnResponse)) { + $return[] = implode(' - ', $returnResponse); + } } } if (isset($params['delimiter'])) { diff --git a/model/flyExporter/simpleExporter/ItemExporter.php b/model/flyExporter/simpleExporter/ItemExporter.php index 7689ae213e..7b99220227 100644 --- a/model/flyExporter/simpleExporter/ItemExporter.php +++ b/model/flyExporter/simpleExporter/ItemExporter.php @@ -41,6 +41,11 @@ class ItemExporter extends ConfigurableService implements SimpleExporter */ const CSV_DELIMITER = ','; + /** + * Defautl csv enclosure + */ + const CSV_ENCLOSURE = '"'; + /** * Default property delimiter */ @@ -236,13 +241,13 @@ protected function save(array $data) $output = $contents = []; - $contents[] = implode(self::CSV_DELIMITER, $this->headers); + $contents[] = self::CSV_ENCLOSURE . implode(self::CSV_ENCLOSURE . self::CSV_DELIMITER . self::CSV_ENCLOSURE, $this->headers) . self::CSV_ENCLOSURE; foreach ($data as $item) { foreach ($item as $line) { foreach ($this->headers as $index => $value) { if (isset($line[$value]) && $line[$value]!=='') { - $output[$value] = '"' . $line[$value] . '"'; + $output[$value] = self::CSV_ENCLOSURE . (string) $line[$value] . self::CSV_ENCLOSURE; unset($line[$value]); } else { $output[$value] = ''; @@ -251,7 +256,7 @@ protected function save(array $data) $contents[] = implode(self::CSV_DELIMITER, array_merge($output, $line)); } } - $this->filesystem->update($this->filelocation, implode("\n", $contents)); + $this->filesystem->update($this->filelocation, chr(239) . chr(187) . chr(191) . implode("\n", $contents)); } /** @@ -271,7 +276,7 @@ protected function handleFile($filename) $this->filesystem->delete($filename); } - if ($resource = fopen('temp', 'w')===false) { + if (($resource = fopen('temp', 'w'))===false) { throw new \Exception('Unable to create csv file.'); }