View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
17747 | Feature requests | RemoteControl | public | 2021-11-22 10:21 | 2022-02-03 21:56 |
Reporter | tbart | Assigned To | galads | ||
Priority | none | Severity | feature | ||
Status | acknowledged | Resolution | open | ||
Summary | 17747: Add export_survey_archive/export_survey_structure to API (working implementation attached) | ||||
Description | I am doing pretty complex automation stuff with limesurvey (some more details/tools might follow later if people are interested), one of them being the creation of surveys based on survey templates (and manipulating their XML in between), the other one being copying surveys to a given ID/changed name (as copy_survey does to allow to set a target ID and import_survey is buggy, see https://bugs.limesurvey.org/view.php?id=17746). As I needed an export of lss/lsa anyway, I fixed both issues by implementing the two functions and manipulating the name and ID in the XML, then reimporting the surveys. However, I am not a developer (probably one of the functional/procedural type, but definitely no OO and php dev) but just a sysadmin with automation skills. There's a good amount of code duplication, which I know is ugly. The addtoZip() implementation also does not seem right like I did it. However, I had to work with what's available. If you think this might be useful to others, please consider implementing it along the structure outlined in the attached diff (but please correct the ugliness I produced :-) ) Feel free to use the code as you see fit, no copyright/strings attached. Thanks a lot! PS: I hit the limit of bash's max. commandline length when trying to import an lss as a string. I solved this by eventually creating an lsa from it by simply zipping it though this is not documented like this. I think it would be practical to either state this possibility in the documentation or probably make lss a zipped format, though I think just documenting it in the API documentation (that's the place devs go to to find how they can perform API tasks) might be enough without breaking established formats. | ||||
Tags | No tags attached. | ||||
Bug heat | 4 | ||||
api_export_survey.patch (7,413 bytes)
--- application/helpers/remotecontrol/remotecontrol_handle.php.org 2020-02-13 16:39:43.137157937 +0100 +++ application/helpers/remotecontrol/remotecontrol_handle.php 2020-05-26 17:19:04.892983689 +0200 @@ -255,6 +255,146 @@ } /** + * RPC Routine to export a survey archive (LSA). + * + * @access public + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID_org Id of the survey + * @return string|array in case of success : Base64 encoded string of the .lsa file. On failure array with error information. + * */ + public function export_survey_archive ($sSessionKey, $iSurveyID_org) + { + $iSurveyID = (int) $iSurveyID_org; + if (!$this->_checkSessionKey($sSessionKey)) { + return array('status' => 'Invalid session key'); + } + $aData['bFailed'] = false; // Put a var for continue + if (!$iSurveyID) { + $aData['sErrorMessage'] = "No survey ID has been provided. Cannot export survey"; + $aData['bFailed'] = true; + } elseif (!Survey::model()->findByPk($iSurveyID)) { + $aData['sErrorMessage'] = "Invalid survey ID"; + $aData['bFailed'] = true; + } elseif (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'export') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'export')) { + $aData['sErrorMessage'] = "You don't have sufficient permissions."; + $aData['bFailed'] = true; + } else { + $aExcludes = array(); + $aExcludes['dates'] = true; + $btranslinksfields = true; + Yii::app()->loadHelper('export'); + + /* START CODE DUPLICATION + * taken from application/controllers/admin/export.php:_exportarchive + * This is ugly. + * Sorry, I am just a sysadmin, no PHP dev + * The mentioned function would somehow need to be public to actually use it + * However, I barely understand OO programming + * + * I also added addToZip to export_helper.php and made it non-private + * to be able to use it here. Ugly as well. + * + * Still, it works, so the concept should be clear. + */ + $survey = Survey::model()->findByPk($iSurveyID); + + // $aSurveyInfo = getSurveyInfo($iSurveyID); // unused, even in export.php + + $sTempDir = Yii::app()->getConfig("tempdir"); + + $aZIPFileName = $sTempDir.DIRECTORY_SEPARATOR.randomChars(30); + $sLSSFileName = $sTempDir.DIRECTORY_SEPARATOR.randomChars(30); + $sLSRFileName = $sTempDir.DIRECTORY_SEPARATOR.randomChars(30); + $sLSTFileName = $sTempDir.DIRECTORY_SEPARATOR.randomChars(30); + $sLSIFileName = $sTempDir.DIRECTORY_SEPARATOR.randomChars(30); + + Yii::import('application.libraries.admin.pclzip', true); + $zip = new PclZip($aZIPFileName); + + file_put_contents($sLSSFileName, surveyGetXMLData($iSurveyID)); + + addToZip($zip, $sLSSFileName, 'survey_'.$iSurveyID.'.lss'); + + unlink($sLSSFileName); + + if ($survey->isActive) { + getXMLDataSingleTable($iSurveyID, 'survey_'.$iSurveyID, 'Responses', 'responses', $sLSRFileName, false); + addToZip($zip, $sLSRFileName, 'survey_'.$iSurveyID.'_responses.lsr'); + unlink($sLSRFileName); + } + + if ($survey->hasTokensTable) { + getXMLDataSingleTable($iSurveyID, 'tokens_'.$iSurveyID, 'Tokens', 'tokens', $sLSTFileName); + addToZip($zip, $sLSTFileName, 'survey_'.$iSurveyID.'_tokens.lst'); + unlink($sLSTFileName); + } + + if (isset($survey->hasTimingsTable) && $survey->hasTimingsTable == 'Y') { + getXMLDataSingleTable($iSurveyID, 'survey_'.$iSurveyID.'_timings', 'Timings', 'timings', $sLSIFileName); + addToZip($zip, $sLSIFileName, 'survey_'.$iSurveyID.'_timings.lsi'); + unlink($sLSIFileName); + } + + if (is_file($aZIPFileName)) { + /* END CODE DUPLICATION */ + + $sResult = file_get_contents($aZIPFileName); + unlink($aZIPFileName); + } else { + $aData['bFailed'] = true; + $aData['sErrorMessage'] = 'Error creating lsa archive'; + } + } + if ($aData['bFailed']) { + return array('status' => 'Export failed', 'error'=> $aData['sErrorMessage']); + } else { + return base64_encode($sResult); + } + } + /** + * RPC Routine to export a survey structure (LSS). + * + * @access public + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID_org Id of the survey + * @return string|array in case of success : Base64 encoded string of the .lss file. On failure array with error information. + * */ + public function export_survey_structure ($sSessionKey, $iSurveyID_org) + { + $iSurveyID = (int) $iSurveyID_org; + if (!$this->_checkSessionKey($sSessionKey)) { + return array('status' => 'Invalid session key'); + } + $aData['bFailed'] = false; // Put a var for continue + if (!$iSurveyID) { + $aData['sErrorMessage'] = "No survey ID has been provided. Cannot export survey"; + $aData['bFailed'] = true; + } elseif (!Survey::model()->findByPk($iSurveyID)) { + $aData['sErrorMessage'] = "Invalid survey ID"; + $aData['bFailed'] = true; + } elseif (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'export') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'export')) { + $aData['sErrorMessage'] = "You don't have sufficient permissions."; + $aData['bFailed'] = true; + } else { + $aExcludes = array(); + $aExcludes['dates'] = true; + $btranslinksfields = true; + Yii::app()->loadHelper('export'); + $exportsurveystructuredata = surveyGetXMLData($iSurveyID, $aExcludes); + if ($exportsurveystructuredata) { + $sResult = $exportsurveystructuredata; + } else { + $aData['bFailed'] = true; + } + } + if ($aData['bFailed']) { + return array('status' => 'Export failed', 'error'=> $aData['sErrorMessage']); + } else { + return base64_encode($sResult); + } + } + + /** * Copy survey (RPC function) * * @access public --- application/helpers/export_helper.php.org 2020-05-26 17:22:50.808991768 +0200 +++ application/helpers/export_helper.php 2020-05-26 17:07:19.924958477 +0200 @@ -13,6 +13,26 @@ */ /** + * CODE DUPLICATION! This is also part of export.php + * Sorry I can't solve this any better... + * @param PclZip $zip + * @param string $name + * @param string $full_name + */ + +function addToZip($zip, $name, $full_name) +{ + $zip->add( + array( + array( + PCLZIP_ATT_FILE_NAME => $name, + PCLZIP_ATT_FILE_NEW_FULL_NAME => $full_name + ) + ) + ); +} + +/** * Strips html tags and replaces new lines * * @param $string |
|
Hello, Thank you for creating a patch. Can you create a PR? |
|
Basically I use git everyday with my local instance but have never used it for shared projects. My team is currently extremely overloaded so yes, maybe, but this can take pretty long as I'd have to read up on how to do this and find a free slot once we're better staffed again. |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2021-11-22 10:21 | tbart | New Issue | |
2021-11-22 10:21 | tbart | File Added: api_export_survey.patch | |
2022-02-01 13:43 | galads | Note Added: 68164 | |
2022-02-01 13:43 | galads | Bug heat | 0 => 2 |
2022-02-01 13:43 | galads | Assigned To | => galads |
2022-02-01 13:43 | galads | Status | new => acknowledged |
2022-02-03 21:56 | tbart | Note Added: 68201 | |
2022-02-03 21:56 | tbart | Bug heat | 2 => 4 |