public function testKnownGoodZipArchiveEqualsGeneratedZipArchive() { $this->auth(); $goodZip = new ZipArchiveModel(null, array('filename' => PROJECT_PATH . "/test/data/zip/test-archive.zip")); $xml = file_get_contents(PROJECT_PATH . "/test/data/xml/test1-questionnaire-definition.xml"); QuestionnaireModel::importXML($xml); InstanceModel::importXML($xml, 'Test1 Company'); $instance = new InstanceModel(array('questionnaireName' => 'Test1 Questionnaire', 'questionnaireVersion' => '3.00', 'revision' => 1, 'instanceName' => 'Test1 Company', 'depth' => 'question')); while ($page = $instance->nextPage()) { while ($section = $page->nextSection()) { while ($question = $section->nextQuestion()) { $fileObj = new FileModel($question); $fileObj->store(file_get_contents(PROJECT_PATH . '/test/data/zip/test-archive-attachment.txt'), array('filename' => 'test-archive-attachment.txt')); break 3; } } } $zip = new ZipArchiveModel($instance, array('new' => '1')); $zip->addInstanceFullResponsesXMLDocument(); $zip->addAttachments(); $zip->close(); $zip = new ZipArchiveModel($instance, array('filename' => $zip->getZipFileName())); $this->assertEquals($goodZip->getInstanceFullResponsesXMLDocument(), $zip->getInstanceFullResponsesXMLDocument()); $this->assertEquals($goodZip->getFromName('files/4'), $zip->getFromName('files/4')); $zip->deleteZipFile(); }
/** * Exports an Instance XML Document * * @param integer If true, exports the entire questionnaire definition (question text, etc). * If false, only exports guid and response data. * @param array PageHeader strings to export. If empty, export entire instance. * @return string XML Document */ public function toXML($complete = 0, $pageHeaders = array()) { $instanceID = $this->instanceRow->instanceID; QFrame_Db_Table::resetAll(); $this->attachmentQuestions = FileModel::fetchObjectIdsByInstance($this->instanceRow->instanceID); $instance = new InstanceModel(array('instanceID' => $instanceID, 'depth' => 'response')); $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n"; $xml .= '<csi:questionnaire'; $xml .= ' xmlns:csi="http://www.csinitiative.com/ns/csi-qframe"'; $xml .= ' questionnaireName="' . self::_xmlentities($instance->questionnaireName) . '" questionnaireVersion="' . self::_xmlentities($instance->questionnaireVersion) . '" revision="' . self::_xmlentities($instance->revision) . '" targetQFrameVersion="' . QFRAME_VERSION . '" instanceName="' . self::_xmlentities($instance->instanceName) . '">' . "\n"; $xml .= " <csi:pages>\n"; while ($page = $instance->nextPage()) { if (count($pageHeaders) > 0 && array_search($page->pageHeader, $pageHeaders) === FALSE) { continue; } $xml .= " <csi:page>\n"; if ($complete) { $xml .= " <csi:pageHeader>" . self::_xmlentities($page->pageHeader) . "</csi:pageHeader>\n"; } $xml .= " <csi:pageGUID>" . self::_xmlentities($page->pageGUID) . "</csi:pageGUID>\n"; $xml .= " <csi:seqNumber>" . self::_xmlentities($page->seqNumber) . "</csi:seqNumber>\n"; if ($complete) { $xml .= " <csi:description>" . self::_xmlentities($page->description) . "</csi:description>\n"; $xml .= " <csi:headerText>" . self::_xmlentities($page->headerText) . "</csi:headerText>\n"; $xml .= " <csi:footerText>" . self::_xmlentities($page->footerText) . "</csi:footerText>\n"; $xml .= " <csi:cloneable>" . self::_xmlentities($page->cloneable) . "</csi:cloneable>\n"; $xml .= " <csi:defaultPageHidden>" . self::_xmlentities($page->defaultPageHidden) . "</csi:defaultPageHidden>\n"; } $xml .= " <csi:sections>\n"; while ($section = $page->nextSection()) { $xml .= " <csi:section>\n"; if ($complete) { $xml .= ' <csi:sectionHeader>' . self::_xmlentities($section->sectionHeader) . "</csi:sectionHeader>\n"; } $xml .= ' <csi:sectionGUID>' . self::_xmlentities($section->sectionGUID) . "</csi:sectionGUID>\n"; $xml .= ' <csi:seqNumber>' . self::_xmlentities($section->seqNumber) . "</csi:seqNumber>\n"; if ($complete) { $xml .= ' <csi:description>' . self::_xmlentities($section->description) . "</csi:description>\n"; $xml .= ' <csi:cloneable>' . self::_xmlentities($section->cloneable) . "</csi:cloneable>\n"; $xml .= ' <csi:defaultSectionHidden>' . self::_xmlentities($section->defaultSectionHidden) . "</csi:defaultSectionHidden>\n"; $references = $section->references; if (count($references) > 0) { $xml .= " <csi:sectionReferences>"; foreach ($references as $reference) { $xml .= " <csi:reference>"; $xml .= ' <csi:shortName>' . self::_xmlentities($reference['shortName']) . "</csi:shortName>\n"; $xml .= ' <csi:referenceName>' . self::_xmlentities($reference['referenceName']) . "</csi:referenceName>\n"; $xml .= ' <csi:item>' . self::_xmlentities($reference['item']) . "</csi:item>\n"; $xml .= ' <csi:referenceURL>' . self::_xmlentities($reference['referenceURL']) . "</csi:referenceURL>\n"; $xml .= ' <csi:referenceText>' . self::_xmlentities($reference['referenceText']) . "</csi:referenceText>\n"; $xml .= "</csi:reference>\n"; } $xml .= "</csi:sectionReferences>\n"; } } $xml .= " <csi:questions>\n"; while ($question = $section->nextQuestion()) { $padding = ''; if (count($question->children)) { $xml .= " <csi:questionGroup>\n"; if ($complete) { $xml .= " <csi:qText>" . self::_xmlentities($question->qText) . "</csi:qText>\n"; } $xml .= " <csi:questionGUID>" . self::_xmlentities($question->questionGUID) . "</csi:questionGUID>\n"; $xml .= " <csi:seqNumber>" . self::_xmlentities($question->seqNumber) . "</csi:seqNumber>\n"; if ($complete && strlen(self::_xmlentities($question->questionNumber))) { $xml .= " <csi:groupQuestionNumber>" . self::_xmlentities($question->questionNumber) . "</csi:groupQuestionNumber>\n"; } $xml .= " <csi:cloneable>" . self::_xmlentities($question->cloneable) . "</csi:cloneable>\n"; $xml .= " <csi:groupDefaultQuestionHidden>" . self::_xmlentities($question->defaultQuestionHidden) . "</csi:groupDefaultQuestionHidden>\n"; $references = $question->references; if (count($references) > 0) { $xml .= " <csi:groupQuestionReferences>"; foreach ($references as $reference) { $xml .= " <csi:reference>\n"; $xml .= " <csi:shortName>" . self::_xmlentities($reference['shortName']) . "</csi:shortName>\n"; $xml .= " <csi:referenceName>" . self::_xmlentities($reference['referenceName']) . "</csi:referenceName>\n"; $xml .= " <csi:item>" . self::_xmlentities($reference['item']) . "</csi:item>\n"; $xml .= " <csi:referenceURL>" . self::_xmlentities($reference['referenceURL']) . "</csi:referenceURL>\n"; $xml .= " <csi:referenceText>" . self::_xmlentities($reference['referenceText']) . "</csi:referenceText>\n"; $xml .= " </csi:reference>\n"; } $xml .= "</csi:groupQuestionReferences>\n"; } if (isset($this->attachmentQuestions['QuestionModel'][$question->questionID])) { $fileObj = new FileModel($question); $ids = $fileObj->fetchAll(); if (count($ids)) { $xml .= " <csi:attachments>\n"; foreach ($ids as $id) { $xml .= " <csi:attachment>\n"; $file = $fileObj->fetchProperties($id); $xml .= " <csi:filename>" . self::_xmlentities($file['filename']) . "</csi:filename>\n"; $xml .= " <csi:mime>" . self::_xmlentities($file['mime']) . "</csi:mime>\n"; $xml .= " <csi:location>files/{$id}</csi:location>\n"; $xml .= " </csi:attachment>\n"; } $xml .= " </csi:attachments>\n"; } } $padding = ' '; $questions = $question->children; } else { $questions = array($question); } foreach ($questions as $question) { $xml .= "{$padding} <csi:question>\n"; if ($question->virtualQuestion) { $xml .= "{$padding} <csi:questionGUID>" . self::_xmlentities($question->questionGUID) . "</csi:questionGUID>\n"; $xml .= "{$padding} <csi:seqNumber>" . self::_xmlentities($question->seqNumber) . "</csi:seqNumber>\n"; $xml .= "{$padding} <csi:questionNumber>" . self::_xmlentities($question->questionNumber) . "</csi:questionNumber>\n"; $xml .= "{$padding} <csi:questionType>V</csi:questionType>\n"; } else { if ($complete) { $xml .= "{$padding} <csi:qText>" . self::_xmlentities($question->qText) . "</csi:qText>\n"; } $xml .= "{$padding} <csi:questionGUID>" . self::_xmlentities($question->questionGUID) . "</csi:questionGUID>\n"; $xml .= "{$padding} <csi:seqNumber>" . self::_xmlentities($question->seqNumber) . "</csi:seqNumber>\n"; $prompts = $question->prompts; if ($complete) { if (strlen(self::_xmlentities($question->questionNumber))) { $xml .= "{$padding} <csi:questionNumber>" . self::_xmlentities($question->questionNumber) . "</csi:questionNumber>\n"; } if (!$padding) { $xml .= "{$padding} <csi:cloneable>" . self::_xmlentities($question->cloneable) . "</csi:cloneable>\n"; } $xml .= "{$padding} <csi:defaultQuestionHidden>" . self::_xmlentities($question->defaultQuestionHidden) . "</csi:defaultQuestionHidden>\n"; $references = $question->references; if (count($references) > 0) { $xml .= "{$padding} <csi:questionReferences>"; foreach ($references as $reference) { $xml .= "{$padding} <csi:reference>\n"; $xml .= "{$padding} <csi:shortName>" . self::_xmlentities($reference['shortName']) . "</csi:shortName>\n"; $xml .= "{$padding} <csi:referenceName>" . self::_xmlentities($reference['referenceName']) . "</csi:referenceName>\n"; $xml .= "{$padding} <csi:item>" . self::_xmlentities($reference['item']) . "</csi:item>\n"; $xml .= "{$padding} <csi:referenceURL>" . self::_xmlentities($reference['referenceURL']) . "</csi:referenceURL>\n"; $xml .= "{$padding} <csi:referenceText>" . self::_xmlentities($reference['referenceText']) . "</csi:referenceText>\n"; $xml .= "{$padding} </csi:reference>\n"; } $xml .= "</csi:questionReferences>\n"; } $xml .= "{$padding} <csi:questionType>" . self::_xmlentities($question->format) . "</csi:questionType>\n"; foreach ($prompts as $prompt) { $xml .= "{$padding} <csi:questionPrompt>\n"; $xml .= "{$padding} <csi:promptText>" . self::_xmlentities($prompt['value']) . "</csi:promptText>\n"; $xml .= "{$padding} <csi:requireAdditionalInfo>" . self::_xmlentities($prompt['requireAddlInfo']) . "</csi:requireAdditionalInfo>\n"; foreach (array('enablePage', 'enableSection', 'enableQuestion', 'disablePage', 'disableSection', 'disableQuestion') as $t) { foreach ($prompt['rules'] as $rule) { $type = $rule->type; if ($type === $t) { $xml .= "{$padding} <csi:{$type}>" . self::_xmlentities($rule->targetGUID) . "</csi:{$type}>\n"; } } } $xml .= "{$padding} </csi:questionPrompt>\n"; } } $first = true; while ($response = $question->nextResponse()) { if ($first === true) { $xml .= "{$padding} <csi:responses>\n"; $xml .= "{$padding} <csi:state>" . self::_xmlentities($response->state) . "</csi:state>\n"; $xml .= "{$padding} <csi:additionalInfo>" . self::_xmlentities($response->additionalInfo) . "</csi:additionalInfo>\n"; } $responseDate = $response->responseDate; $responseDate = preg_replace('/ /', 'T', $responseDate); if (count($prompts) > 0) { $rTexts = explode(',', $response->responseText); foreach ($prompts as $prompt) { foreach ($rTexts as $r) { if ($r === $prompt['promptID']) { $xml .= "{$padding} <csi:response>\n"; $xml .= "{$padding} <csi:responseDate>" . self::_xmlentities($responseDate) . "</csi:responseDate>\n"; $xml .= "{$padding} <csi:responseText>" . self::_xmlentities($prompt['value']) . "</csi:responseText>\n"; $xml .= "{$padding} </csi:response>\n"; } } } } else { $xml .= "{$padding} <csi:response>\n"; $xml .= "{$padding} <csi:responseDate>" . self::_xmlentities($responseDate) . "</csi:responseDate>\n"; $xml .= "{$padding} <csi:responseText>" . self::_xmlentities($response->responseText) . "</csi:responseText>\n"; $xml .= "{$padding} </csi:response>\n"; } if ($first === true) { $first = false; } } if ($first === false) { $xml .= "{$padding} </csi:responses>\n"; } } if (isset($this->attachmentQuestions['QuestionModel'][$question->questionID])) { $fileObj = new FileModel($question); $ids = $fileObj->fetchAll(); if (count($ids)) { $xml .= "{$padding} <csi:attachments>\n"; foreach ($ids as $id) { $xml .= "{$padding} <csi:attachment>\n"; $file = $fileObj->fetchProperties($id); $xml .= "{$padding} <csi:filename>" . self::_xmlentities($file['filename']) . "</csi:filename>\n"; $xml .= "{$padding} <csi:mime>" . self::_xmlentities($file['mime']) . "</csi:mime>\n"; $xml .= "{$padding} <csi:location>files/{$id}</csi:location>\n"; $xml .= "{$padding} </csi:attachment>\n"; } $xml .= "{$padding} </csi:attachments>\n"; } } $xml .= "{$padding} </csi:question>" . "\n"; } if ($padding) { $xml .= " </csi:questionGroup>\n"; } } $xml .= " </csi:questions>\n"; $xml .= " </csi:section>\n"; } $xml .= " </csi:sections>\n"; $xml .= " </csi:page>\n"; } $xml .= " </csi:pages>\n"; $xml .= "</csi:questionnaire>\n"; QFrame_Db_Table::resetAll(); return $xml; }
/** * Adds all attachments associated with the instance to the zip archive */ public function addAttachments() { $attachmentQuestions = FileModel::fetchObjectIdsByInstance($this->instance->instanceID); $instance = new InstanceModel(array('instanceID' => $this->instance->instanceID, 'depth' => 'question')); while ($page = $instance->nextPage()) { while ($section = $page->nextSection()) { while ($question = $section->nextQuestion()) { if (isset($attachmentQuestions['QuestionModel'][$question->questionID])) { $fileObj = new FileModel($question); $ids = $fileObj->fetchAll(); if ($ids === NULL) { continue; } foreach ($ids as $id) { $file = $fileObj->fetchWithProperties($id); $this->addFromString("files/{$id}", $file['contents']); } } } } } }