From: <gem...@li...> - 2011-09-16 08:03:27
|
Revision: 29 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=29&view=rev Author: mennodekker Date: 2011-09-16 08:03:15 +0000 (Fri, 16 Sep 2011) Log Message: ----------- Fixed #6: Add export options for collected data Modified Paths: -------------- trunk/library/classes/Gems/Menu.php Added Paths: ----------- trunk/library/classes/Gems/Default/ExportAction.php trunk/library/classes/Gems/Export/ trunk/library/classes/Gems/Export/Excel.php trunk/library/classes/Gems/Export/ExportAbstract.php trunk/library/classes/Gems/Export/ExportInterface.php trunk/library/classes/Gems/Export/ExportModel.php trunk/library/classes/Gems/Export/Spss.php trunk/library/classes/Gems/Export.php trunk/library/controllers/ExportController.php Added: trunk/library/classes/Gems/Default/ExportAction.php =================================================================== --- trunk/library/classes/Gems/Default/ExportAction.php (rev 0) +++ trunk/library/classes/Gems/Default/ExportAction.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,270 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @package Gems + * @subpackage Default + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: DatabaseAction.php 28 2011-09-16 06:24:15Z mennodekker $ + */ + +/** + * Standard controller for database creation and maintenance. + * + * @package Gems + * @subpackage Default + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 + */ +class Gems_Default_ExportAction extends Gems_Controller_Action +{ + /** + * @var Gems_Export + */ + public $export; + + /** + * + * @var Zend_Locale + */ + public $locale; + + public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array()) + { + parent::__construct($request, $response, $invokeArgs); + $this->export = $this->loader->getExport(); + + //Add this controller to the export so it can render view when needed + $this->export->controller = $this; + } + + public function getTopic($count = 1) + { + return $this->_('Data'); + } + + public function getTopicTitle() + { + return $this->_('Export data'); + } + + public function indexAction() + { + $this->initHtml(); + //Hacked around to get a self-refreshing form, quite hardcoded but fine for now + if ($form = $this->processForm()) { + if (!$this->getRequest()->isPost() || $form->getElement('export')->isChecked()) { + if ($form->getElement('export')->isChecked()) { + $data = $form->getValues(); + $this->handleExport($data); + } + $this->html->h3($this->getTopicTitle()); + $div = $this->html->div(array('id' => 'mainform')); + $div[] = $form; + } else { + Zend_Layout::resetMvcInstance(); + $this->view->addHelperPath('Gems/JQuery/View/Helper', 'Gems_JQuery_View_Helper'); + $this->view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper'); + $this->html->raw($form->render($this->view)); + + //Now add all onload actions to make the form still work + $actions = $this->view->jQuery()->getOnLoadActions(); + $this->html->raw('<script type="text/javascript">'); + foreach($actions as $action) { + $this->html->raw($action); + } + $this->html->raw('</script>'); + } + } + } + + /** + * Handle the form + * + * @param type $saveLabel + * @param type $data + * @return type + */ + public function processForm($saveLabel = null, $data = null) + { + $request = $this->getRequest(); + + if ($request->isPost()) { + $data = $request->getPost() + (array) $data; + } else { + //Set the defaults for the form here + $data = $this->export->getDefaults(); + } + + $form = $this->getForm($data); + + $form->setAttrib('id', 'autosubmit'); + $form->setAutoSubmit(MUtil_Html::attrib('href', array('action' => 'index', MUtil_Model::TEXT_FILTER => null, 'RouteReset' => true)), 'mainform'); + //$this->html[] = new Gems_JQuery_AutoSubmitForm(MUtil_Html::attrib('href', array('action' => 'index', MUtil_Model::TEXT_FILTER => null, 'RouteReset' => true)), 'mainform', $form); + + if ($request->isPost()) { + $form->populate($data); + } + + if ($data) { + $form->populate($data); + } + return $form; + } + + /** + * Retrieve the form + * + * @param array $data + * @return Gems_Form + */ + public function getForm(&$data) + { + //Read some data from tables, initialize defaults... + $surveys = $this->db->fetchPairs('SELECT gsu_id_survey, gsu_survey_name FROM gems__surveys WHERE gsu_active = 1 ORDER BY gsu_survey_name'); + $organizations = $this->escort->getAllowedOrganizations(); + $types = $this->export->getExportClasses(); + + //Create the basic form + $form = new Gems_Form_TableForm(); + $form->loadDefaultDecorators(); + $form->removeDecorator('TabPane'); + + //Start adding elements + $element = new Zend_Form_Element_Select('sid'); + $element->setLabel($this->_('Survey')) + ->setMultiOptions($surveys); + $elements[] = $element; + + //Add a field to the form showing the record count. If this is too slow for large recordsets + //then remove it or make it more efficient + unset($data['records']); + if (isset($data['sid'])) { + $gsu_id = intval($data['sid']); + $survey = $this->loader->getTracker()->getSurvey($gsu_id); + + $filter = $this->_getFilter($data); + $answers = $survey->getRawTokenAnswerRows($filter); + } else { + $answers = array(); + } + $element = new MUtil_Form_Element_Exhibitor('records'); + $element->setValue(sprintf($this->_('%s records found.'), count($answers))); + $elements[] = $element; + + $element = new Zend_Form_Element_MultiCheckbox('oid'); + $element->setLabel($this->_('Organization')) + ->setMultiOptions($organizations); + $elements[] = $element; + $element = new Gems_JQuery_Form_Element_ToggleCheckboxes('toggleOrg', array('selector'=>'input[name^=oid]')); + $element->setLabel('Toggle'); + $elements[] = $element; + + $element = new Zend_Form_Element_Select('type'); + $element->setLabel($this->_('Export to')) + ->setMultiOptions($types); + $elements[] = $element; + + //Add all elements to the form + $form->addElements($elements); + unset($elements); + + //Now make a change for the selected export type + if (isset($data['type'])) { + $exportClass = $this->export->getExport($data['type']); + $formFields = $exportClass->getFormElements($form, $data); + $exportName = $exportClass->getName(); + //Now add a hidden field so we know that when this is present in the $data + //we don't need to set the defaults + $formFields[] = new Zend_Form_Element_Hidden($exportName); + foreach ($formFields as $formField) { + $formField->setBelongsTo($exportName); + $form->addElement($formField); + } + + if (!isset($data[$exportName])) { + $data[$exportName] = $exportClass->getDefaults(); + } + } + + //Finally create a submit button and add to the form + $element = new Zend_Form_Element_Submit('export'); + $element->setLabel('Export') + ->setAttrib('class', 'button'); + $form->addElement($element); + + return $form; + } + + /** + * Take care of exporting the data + * + * @param array $data + */ + public function handleExport($data) + { + $language = $this->locale->getLanguage(); + $emptyMsg = sprintf($this->_('No %s found.'), $this->getTopic(0)); + $gsu_id = intval($data['sid']); + $survey = $this->loader->getTracker()->getSurvey($gsu_id); + + $filter = $this->_getFilter($data); + $answers = $survey->getRawTokenAnswerRows($filter); + $answerModel = $survey->getAnswerModel($language); + //Now add the organization id => name mapping + $answerModel->set('organizationid', 'multiOptions', $this->escort->getAllowedOrganizations()); + + if (count($answers) === 0) { + $answers[0] = array('' => $emptyMsg); + } + + if (isset($data['type'])) { + //Do the logging + $message = join(', ', $data); + Gems_AccessLog::getLog()->log('export', $this->getRequest(), $message, null, true); + + //And delegate the export to the right class + $exportClass = $this->export->getExport($data['type']); + $exportClass->handleExport($data, $survey, $answers, $answerModel, $language); + } + } + + public function _getFilter($data) { + $filter = array(); + if (isset($data['oid'])) { + $filter['organizationid'] = $data['oid']; + } else { + //Invalid id so when nothing selected... we get nothing + //$filter['organizationid'] = '-1'; + } + $filter['consentcode'] = array_diff((array) $this->util->getConsentTypes(), (array) $this->util->getConsentRejected()); + + return $filter; + } +} \ No newline at end of file Added: trunk/library/classes/Gems/Export/Excel.php =================================================================== --- trunk/library/classes/Gems/Export/Excel.php (rev 0) +++ trunk/library/classes/Gems/Export/Excel.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,138 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Short description of file + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Excel.php 140 2011-09-15 14:18:14Z 175780 $ + */ + +/** + * Short description for Excel + * + * Long description for class Excel (if any)... + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class Gems_Export_Excel extends Gems_Export_ExportAbstract +{ + /** + * Return an array of Form Elements for this specific export + * + * @param type $form + * @param type $data + * @return array of Zend_Form_Element + */ + public function getFormElements(&$form, &$data) + { + $element = new Zend_Form_Element_MultiCheckbox('format'); + $element->setLabel($this->_('Excel options')) + ->setMultiOptions(array( + 'formatVariable' => $this->_('Export questions instead of variable names'), + 'formatAnswer' => $this->_('Format answers') + )); + $elements[] = $element; + + return $elements; + } + + /** + * Sets the default form values when this export type is first chosen + * + * @return array + */ + public function getDefaults() + { + return array('format'=>array('formatVariable', 'formatAnswer')); + } + + /** + * Returns the unique name for this class + * + * It will be used for handling this export's specific options + * + * @return string + */ + public function getName() + { + return 'excel'; + } + + /** + * This method handles the export with the given options + * + * The method takes care of rendering the right script by using $this->export->controller to + * access the controller object. + * + * @param array $data The formdata + * @param Gems_Tracker_Survey $survey The survey object we are exporting + * @param array $answers The array of answers + */ + public function handleExport($data, $survey, $answers, $answerModel, $language) + { + $questions = $survey->getQuestionList($language); + if (isset($data[$this->getName()])) { + $options = $data[$this->getName()]; + if (isset($options['format'])) { + $options = $options['format']; + } + } else { + $options = array(); + } + + if (in_array('formatVariable', $options)) { + //@@TODO This breaks date formatting, think of a way to fix this, check out the spss exports for + //a more direct export, also check UTF-8 differences between view / direct output + foreach ($answers[0] as $key => $value) { + if (isset($questions[$key])) { + $headers[0][$key] = $questions[$key]; + } else { + $headers[0][$key] = $key; + } + } + } else { + $headers[0] = array_keys($answers[0]); + } + $answers = array_merge($headers, $answers); + + if (in_array('formatAnswer', $options)) { + $answers = new Gems_FormattedData($answers, $answerModel); + } + + $this->view->result = $answers; + $this->view->filename = $survey->getName() . '.xls'; + $this->view->setScriptPath(GEMS_LIBRARY_DIR . '/views/scripts'); + $this->export->controller->render('excel',null,true); + } +} \ No newline at end of file Added: trunk/library/classes/Gems/Export/ExportAbstract.php =================================================================== --- trunk/library/classes/Gems/Export/ExportAbstract.php (rev 0) +++ trunk/library/classes/Gems/Export/ExportAbstract.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,84 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Short description of file + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: ExportAbstract.php 128 2011-08-12 12:33:14Z 175780 $ + */ + +/** + * Short description for ExportAbstract + * + * Long description for class ExportAbstract (if any)... + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +abstract class Gems_Export_ExportAbstract extends Gems_Loader_TargetLoaderAbstract implements Gems_Export_ExportInterface +{ + /** + * Variable needed to access the controller functions + * + * $this->export->controller + * + * @var Gems_Export + */ + public $export; + + /** + * @var Zend_Translate + */ + public $translate; + + /** + * @var Zend_View + */ + public $view; + + /** + * Copy from Zend_Translate_Adapter + * + * Translates the given string + * returns the translation + * + * @param string $text Translation string + * @param string|Zend_Locale $locale (optional) Locale/Language to use, identical with locale + * identifier, @see Zend_Locale for more information + * @return string + */ + public function _($text, $locale = null) + { + return $this->translate->_($text, $locale); + } +} \ No newline at end of file Added: trunk/library/classes/Gems/Export/ExportInterface.php =================================================================== --- trunk/library/classes/Gems/Export/ExportInterface.php (rev 0) +++ trunk/library/classes/Gems/Export/ExportInterface.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,87 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: ExportInterface.php 128 2011-08-12 12:33:14Z 175780 $ + */ + +/** + * The export interface + * + * Exporting survey-data can be done for various sorts of output formats, this interface + * describes the methods needed to implement an output format + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +interface Gems_Export_ExportInterface +{ + /** + * Return an array of Form Elements for this specific export + * + * @param type $form + * @param type $data + * @return array of Zend_Form_Element + */ + public function getFormElements(&$form, &$data); + + /** + * Sets the default form values when this export type is first chosen + * + * @return array + */ + public function getDefaults(); + + /** + * Returns the unique name for this class + * + * It will be used for handling this export's specific options + * + * @return string + */ + public function getName(); + + /** + * This method handles the export with the given options + * + * The method takes care of rendering the right script by using $this->export->controller to + * access the controller object. + * + * @param array $data The formdata + * @param Gems_Tracker_Survey $survey The survey object we are exporting + * @param array $answers The array of answers + * @param MUtil_Model_ModelAbstract $answerModel The modified answermodel that includes info about extra attributes + * @param string $language The language used / to use for the export + */ + public function handleExport($data, $survey, $answers, $answerModel, $language); +} \ No newline at end of file Added: trunk/library/classes/Gems/Export/ExportModel.php =================================================================== --- trunk/library/classes/Gems/Export/ExportModel.php (rev 0) +++ trunk/library/classes/Gems/Export/ExportModel.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,80 @@ +<?php + +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Short description of file + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: ExportModel.php 138 2011-09-15 10:44:24Z 175780 $ + */ + +/** + * Short description for ExportModel + * + * Long description for class ExportModel (if any)... + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class Gems_Export_ExportModel extends MUtil_Model_ModelAbstract +{ + + public function __construct() + { + parent::__construct('export'); + } + + public function delete($filter = true) + { + return false; + } + + public function hasNew() + { + return false; + } + + public function load($filter = true, $sort = true) + { + $result = array(); + foreach ($this->getItemsOrdered() as $item) { + $result[0][$item] = $item; + } + return $result; + } + + public function save(array $newValues, array $filter = null) + { + return $newValues; + } +} \ No newline at end of file Added: trunk/library/classes/Gems/Export/Spss.php =================================================================== --- trunk/library/classes/Gems/Export/Spss.php (rev 0) +++ trunk/library/classes/Gems/Export/Spss.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,270 @@ +<?php + +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Short description of file + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Spss.php 140 2011-09-15 14:18:14Z 175780 $ + */ + +/** + * Short description for Spss + * + * Long description for class Spss (if any)... + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class Gems_Export_Spss extends Gems_Export_ExportAbstract +{ + + public function getDefaults() + { + return array('file'=>'data'); + } + + public function getFormElements(&$form, &$data) + { + $element = new Zend_Form_Element_Radio('file'); + $element->setLabel($this->_('Which file')); + $element->setMultiOptions(array('syntax' => $this->_('syntax'), + 'data' => $this->_('data'))); + + $elements[] = $element; + + $element = new MUtil_Form_Element_Exhibitor('help'); + $element->setValue($this->_('Some help for this export')); + $elements[] = $element; + + return $elements; + } + + public function getName() + { + return 'spss'; + } + + /** + * This method handles the export with the given options + * + * The method takes care of rendering the right script by using $this->export->controller to + * access the controller object. + * + * @param array $data The formdata + * @param Gems_Tracker_Survey $survey The survey object we are exporting + * @param array $answers The array of answers + * @param MUtil_Model_ModelAbstract $answerModel The modified answermodel that includes info about extra attributes + * @param string $language The language used / to use for the export + */ + public function handleExport($data, $survey, $answers, $answerModel, $language) + { + if (isset($data[$this->getName()])) { + $options = $data[$this->getName()]; + } else { + $options = array(); + } + + if (isset($options['file'])) { + if ($options['file'] == 'syntax') { + $controller = $this->export->controller; + $controller->getHelper('layout')->disableLayout(); + $controller->getHelper('viewRenderer')->setNoRender(true); + $response = $controller->getResponse(); + $filename = $survey->getName() . '.sps'; + $filenameDat = $survey->getName() . '.dat'; + $response->clearHeaders(); + $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"') + ->setHeader('Content-type', 'text/comma-separated-values; charset=UTF-8') + ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') + ->setHeader('Pragma', 'public'); + + //first output our script + $response->appendBody( + "SET UNICODE=ON. +GET DATA + /TYPE=TXT + /FILE=\"" . $filenameDat . "\" + /DELCASE=LINE + /DELIMITERS=\",\" + /QUALIFIER=\"'\" + /ARRANGEMENT=DELIMITED + /FIRSTCASE=1 + /IMPORTCASE=ALL + /VARIABLES="); + $answerRow = reset($answers); + $labels = array(); + $types = array(); + $questions = $survey->getQuestionList($language); + foreach($answerRow as $key => $value) { + $options = array(); + $type = $answerModel->get($key,'type'); + switch ($type) { + case MUtil_Model::TYPE_DATE: + $type = 'SDATE10'; + break; + + case MUtil_Model::TYPE_DATETIME: + case MUtil_Model::TYPE_TIME: + $type = 'DATETIME23'; + break; + + case MUtil_Model::TYPE_NUMERIC: + $defaultSize = 5; + $type = 'F'; + break; + + //When no type set... assume string + case MUtil_Model::TYPE_STRING: + default: + $defaultSize = 64; + $type = 'A'; + break; + } + $types[$key] = $type; + if ($type == 'A' || $type == 'F') { + $size = $answerModel->get($key,'size'); + if (is_null($size)) { + $size = $defaultSize; + } + if ($type == 'A') { + $type = $type . $size; + } else { + $type = $type . $size . '.' . ($size-1); //decimal + } + } + if (isset($questions[$key])) { + $labels[$key] = $questions[$key]; + } + $response->appendBody("\n " . $key . ' '. $type); + } + $response->appendBody(".\nCACHE.\nEXECUTE.\n"); + $response->appendBody("\n*Define variable labels.\n"); + foreach($labels as $key => $label) { + $response->appendBody("VARIABLE LABELS " . $key . ' "' . $label . '".' . "\n"); + } + + $response->appendBody("\n*Define value labels.\n"); + foreach($answerRow as $key => $value) { + if($options = $answerModel->get($key, 'multiOptions')) { + $response->appendBody('VALUE LABELS ' . $key); + foreach($options as $option=>$label) { + if($types[$key]=='F') { + //Numeric + $response->appendBody("\n" . $option . ' ' . '"' . $label . '"'); + } else { + //String + $response->appendBody("\n" . '"' .$option . '" ' . '"' . $label . '"'); + } + } + $response->appendBody(".\n\n"); + } + } + } else { + $controller = $this->export->controller; + $controller->getHelper('layout')->disableLayout(); + $controller->getHelper('viewRenderer')->setNoRender(true); + $response = $controller->getResponse(); + $filename = $survey->getName() . '.dat'; + $response->clearHeaders(); + $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"') + ->setHeader('Content-type', 'text/comma-separated-values; charset=UTF-8') + ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') + ->setHeader('Pragma', 'public'); + + //We should create a model with the transformations we need + //think of date translations, numers and strings + $answerRow = reset($answers); + $spssModel = new Zsd_Export_ExportModel(); + foreach($answerRow as $key => $value) { + $options = array(); + $type = $answerModel->get($key,'type'); + switch ($type) { + case MUtil_Model::TYPE_DATE: + $options['storageFormat'] = 'yyyy-MM-dd'; + $options['dateFormat'] = 'yyyy-MM-dd'; + break; + + case MUtil_Model::TYPE_DATETIME: + $options['storageFormat'] = 'yyyy-MM-dd HH:mm:ss'; + $options['dateFormat'] = 'dd-MM-yyyy HH:mm:ss'; + break; + + case MUtil_Model::TYPE_TIME: + $options['storageFormat'] = 'HH:mm:ss'; + $options['dateFormat'] = 'HH:mm:ss'; + break; + + case MUtil_Model::TYPE_NUMERIC: + break; + + //When no type set... assume string + case MUtil_Model::TYPE_STRING: + default: + $type = MUtil_Model::TYPE_STRING; + $options['formatFunction'] = $this->formatString; + break; + } + $options['type'] = $type; + $spssModel->set($key, $options); + } + //Now apply the model to the answers + $answers = new Gems_FormattedData($answers, $spssModel); + + //And output the data + foreach($answers as $answerRow) { + $resultRow = implode(',', $answerRow); + $response->appendBody($resultRow ."\n"); + } + } + } + } + + /** + * Formatting of strings for SPSS export. Enclose in single quotes and escape single quotes + * with a single quote + * + * Example: + * This isn't hard to understand + * ==> + * 'This isn''t hard to understand' + * + * @param type $input + * @return string + */ + public function formatString($input) { + $output = str_replace("'", "''", $input); + $output = "'" . $output . "'"; + return $output; + } +} \ No newline at end of file Added: trunk/library/classes/Gems/Export.php =================================================================== --- trunk/library/classes/Gems/Export.php (rev 0) +++ trunk/library/classes/Gems/Export.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,140 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Short description of file + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Export.php 124 2011-08-09 11:56:35Z 175780 $ + */ + +/** + * Short description for Export + * + * Long description for class Export (if any)... + * + * @package Gems + * @subpackage Export + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class Gems_Export extends Gems_Loader_TargetLoaderAbstract +{ + /** + * Allows sub classes of Gems_Loader_LoaderAbstract to specify the subdirectory where to look for. + * + * @var string $cascade An optional subdirectory where this subclass always loads from. + */ + protected $cascade = 'Export'; + + /** + * Is set to the calling controller to allow rendering the view + * + * @var Gems_Controller_Action + */ + public $controller = null; + + /** + * This variable holds all registered export classes, may be changed in derived classes + * + * @var array Of classname => description + */ + protected $_exportClasses = array( + 'Excel' => 'Excel (xls)', + 'Spss' => 'SPSS', + ); + + /** + * The default values for the form. Defaults for a specific export-type should come + * from that class + * + * @var array + */ + protected $_defaults = array( + 'type' => 'excel' + ); + + /** + * + * @param type $container A container acting as source fro MUtil_Registry_Source + * @param array $dirs The directories where to look for requested classes + */ + public function __construct($container, array $dirs) + { + parent::__construct($container, $dirs); + + // Make sure the export is known + $this->addRegistryContainer(array('export' => $this)); + } + + /** + * Add one or more export classes + * + * @param array $stack classname / description array of sourceclasses + */ + public function addExportClasses($stack) + { + $this->_exportClasses = array_merge($this->_exportClasses, $stack); + } + + public function getDefaults() + { + return $this->_defaults; + } + + /** + * + * @return Gems_Export_ExportInterface + */ + public function getExport($type) + { + return $this->_getClass($type); + } + + /** + * Returns all registered export classes + * + * @return array Of classname => description + */ + public function getExportClasses() + { + return $this->_exportClasses; + } + + /** + * Set the default options for the form + * + * @param array $defaults + */ + public function setDefaults($defaults) + { + $this->_defaults = $defaults; + } +} \ No newline at end of file Modified: trunk/library/classes/Gems/Menu.php =================================================================== --- trunk/library/classes/Gems/Menu.php 2011-09-16 06:24:15 UTC (rev 28) +++ trunk/library/classes/Gems/Menu.php 2011-09-16 08:03:15 UTC (rev 29) @@ -588,6 +588,9 @@ // MAIL CONTAINER $this->addMailSetupPage($this->escort->_('Mail')); + + // EXPORT DATA + $this->addContainer('Export data', 'pr.export', array('controller'=>'export', 'action'=>'index')); // OTHER ITEMS $this->addLogonOffToken(); Added: trunk/library/controllers/ExportController.php =================================================================== --- trunk/library/controllers/ExportController.php (rev 0) +++ trunk/library/controllers/ExportController.php 2011-09-16 08:03:15 UTC (rev 29) @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @package controllers + */ +class ExportController extends Gems_Default_ExportAction +{ +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |